⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 proxy.c

📁 sip proxy
💻 C
📖 第 1 页 / 共 3 页
字号:
/*    Copyright (C) 2002-2007  Thomas Ries <tries@gmx.net>    This file is part of Siproxd.        Siproxd is free software; you can redistribute it and/or modify    it under the terms of the GNU General Public License as published by    the Free Software Foundation; either version 2 of the License, or    (at your option) any later version.        Siproxd is distributed in the hope that it will be useful,    but WITHOUT ANY WARRANTY; without even the implied warranty of    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the    GNU General Public License for more details.        You should have received a copy of the GNU General Public License    along with Siproxd; if not, write to the Free Software    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */#include "config.h"#include <stdio.h>#include <ctype.h>#include <time.h>#include <stdlib.h>#include <string.h>#include <sys/types.h>#include <netinet/in.h>#include <arpa/inet.h>#include <netdb.h>#include <osipparser2/osip_parser.h>#include <osipparser2/sdp_message.h>#include "siproxd.h"#include "log.h"static char const ident[]="$Id: proxy.c,v 1.106 2007/10/28 13:48:10 hb9xar Exp $";/* configuration storage */extern struct siproxd_config configuration;	/* defined in siproxd.c */extern struct urlmap_s urlmap[];		/* URL mapping table     */extern struct lcl_if_s local_addresses;/* * PROXY_REQUEST * * RETURNS *	STS_SUCCESS on success *	STS_FAILURE on error * * RFC3261 *    Section 16.3: Proxy Behavior - Request Validation *    1. Reasonable Syntax *    2. URI scheme *    3. Max-Forwards *    4. (Optional) Loop Detection *    5. Proxy-Require *    6. Proxy-Authorization * *    Section 16.6: Proxy Behavior - Request Forwarding *    1.  Make a copy of the received request *    2.  Update the Request-URI *    3.  Update the Max-Forwards header field *    4.  Optionally add a Record-route header field value *    5.  Optionally add additional header fields *    6.  Postprocess routing information *    7.  Determine the next-hop address, port, and transport *    8.  Add a Via header field value *    9.  Add a Content-Length header field if necessary *    10. Forward the new request *    11. Set timer C */int proxy_request (sip_ticket_t *ticket) {   int i;   int sts;   int type;   struct in_addr sendto_addr;   osip_uri_t *url;   int port;   char *buffer;   size_t buflen;   osip_message_t *request;   DEBUGC(DBCLASS_PROXY,"proxy_request");   if (ticket==NULL) {      ERROR("proxy_request: called with NULL ticket");      return STS_FAILURE;   }   request=ticket->sipmsg;   /*    * RFC 3261, Section 16.4    * Proxy Behavior - Route Information Preprocessing    * (process Route header)    */   route_preprocess(ticket);   /*    * figure out whether this is an incoming or outgoing request    * by doing a lookup in the registration table.    */    sip_find_direction(ticket, &i);    type = ticket->direction;   /*    * logging of passing calls    *//*&&&& this should be moved to its own logging plugin */   if (configuration.log_calls) {      osip_uri_t *from_url = NULL;      osip_uri_t *to_url   = NULL;      char *to_username =NULL;      char *to_host = NULL;      char *from_username =NULL;      char *from_host = NULL;      char *call_type = NULL;      /* From: 1st preference is From header, then try contact header */      if (request->from->url) {         from_url = request->from->url;      } else {         from_url = (osip_uri_t *)osip_list_get(request->contacts, 0);      }      to_url = request->to->url;      if (to_url) {         to_username = to_url->username;         to_host = to_url->host;      }      if (from_url) {         from_username = from_url->username;         from_host = from_url->host;      }      /* INVITE */      if (MSG_IS_INVITE(request)) {         if (type==REQTYP_INCOMING) call_type="Incoming";         else call_type="Outgoing";      /* BYE / CANCEL */      } else if (MSG_IS_ACK(request)) {         call_type="ACK";      } else if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {         call_type="Ending";      }      if (call_type) {         INFO("%s Call: %s@%s -> %s@%s",              call_type,              from_username ? from_username: "*NULL*",              from_host     ? from_host    : "*NULL*",              to_username   ? to_username  : "*NULL*",              to_host       ? to_host      : "*NULL*");      }   } /* log_calls */   /*    * RFC 3261, Section 16.6 step 1    * Proxy Behavior - Request Forwarding - Make a copy    */   /* nothing to do here, copy is ready in 'request'*/   /* get destination address */   url=osip_message_get_uri(request);   switch (type) {  /*   * from an external host to the internal masqueraded host   */   case REQTYP_INCOMING:      DEBUGC(DBCLASS_PROXY,"incoming request from %s@%s from outbound",	request->from->url->username? request->from->url->username:"*NULL*",        request->from->url->host? request->from->url->host: "*NULL*");      /*       * RFC 3261, Section 16.6 step 2       * Proxy Behavior - Request Forwarding - Request-URI       * (rewrite request URI to point to the real host)       */      /* 'i' still holds the valid index into the URLMAP table */      proxy_rewrite_request_uri(request, i);      /* if this is CANCEL/BYE request, stop RTP proxying */      if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {         /* stop the RTP proxying stream(s) */         rtp_stop_fwd(osip_message_get_call_id(request), DIR_INCOMING);         rtp_stop_fwd(osip_message_get_call_id(request), DIR_OUTGOING);      /* check for incoming request */      } else if (MSG_IS_INVITE(request)) {         /* Rewrite the body */         sts = proxy_rewrite_invitation_body(ticket, DIR_INCOMING);      } else if (MSG_IS_ACK(request) || MSG_IS_PRACK(request)) {         /* Rewrite the body */         sts = proxy_rewrite_invitation_body(ticket, DIR_INCOMING);      }sts=sip_obscure_callid(ticket);      break;     /*   * from the internal masqueraded host to an external host   */   case REQTYP_OUTGOING:      DEBUGC(DBCLASS_PROXY,"outgoing request from %s@%s from inbound",	request->from->url->username? request->from->url->username:"*NULL*",        request->from->url->host? request->from->url->host: "*NULL*");      /*       * RFC 3261, Section 16.6 step 2       * Proxy Behavior - Request Forwarding - Request-URI       */      /* nothing to do for an outgoing request */      /* if it is addressed to myself, then it must be some request       * method that I as a proxy do not support. Reject */#if 0/* careful - an internal UA might send an request to another internal UA.   This would be caught here, so don't do this. This situation should be   caught in the default part of the CASE statement below */      if (is_sipuri_local(ticket) == STS_TRUE) {         WARN("unsupported request [%s] directed to proxy from %s@%s -> %s@%s",	    request->sip_method? request->sip_method:"*NULL*",	    request->from->url->username? request->from->url->username:"*NULL*",	    request->from->url->host? request->from->url->host : "*NULL*",	    url->username? url->username : "*NULL*",	    url->host? url->host : "*NULL*");         sip_gen_response(ticket, 403 /*forbidden*/);         return STS_FAILURE;      }#endif      /* Rewrite Contact header to represent the masqued address */      sip_rewrite_contact(ticket, DIR_OUTGOING);      /* Masquerade the User-Agent if configured to do so */      proxy_rewrite_useragent(ticket);      /* if an INVITE, rewrite body */      if (MSG_IS_INVITE(request)) {         sts = proxy_rewrite_invitation_body(ticket, DIR_OUTGOING);      } else if (MSG_IS_ACK(request) || MSG_IS_PRACK(request)) {         sts = proxy_rewrite_invitation_body(ticket, DIR_OUTGOING);      }      /* if this is CANCEL/BYE request, stop RTP proxying */      if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {         /* stop the RTP proxying stream(s) */         rtp_stop_fwd(osip_message_get_call_id(request), DIR_INCOMING);         rtp_stop_fwd(osip_message_get_call_id(request), DIR_OUTGOING);      }sts=sip_obscure_callid(ticket);      break;      default:      DEBUGC(DBCLASS_PROXY, "request [%s] from/to unregistered UA "           "(RQ: %s@%s -> %s@%s)",           request->sip_method? request->sip_method:"*NULL*",	   request->from->url->username? request->from->url->username:"*NULL*",	   request->from->url->host? request->from->url->host : "*NULL*",	   url->username? url->username : "*NULL*",	   url->host? url->host : "*NULL*");/* * we may end up here for two reasons: *  1) An incomming request (from outbound) that is directed to *     an unknown (not registered) local UA *  2) an outgoing request from a local UA that is not registered. * * Case 1) we should probably answer with "404 Not Found", * case 2) more likely a "403 Forbidden" *  * How about "408 Request Timeout" ? * */      sip_gen_response(ticket, 408 /* Request Timeout */);      return STS_FAILURE;   }   /*    * RFC 3261, Section 16.6 step 3    * Proxy Behavior - Request Forwarding - Max-Forwards    * (if Max-Forwards header exists, decrement by one, if it does not    * exist, add a new one with value SHOULD be 70)    */   {   osip_header_t *max_forwards;   int forwards_count = DEFAULT_MAXFWD;   char mfwd[12]; /* 10 digits, +/- sign, termination */   osip_message_get_max_forwards(request, 0, &max_forwards);   if (max_forwards == NULL) {      sprintf(mfwd, "%i", forwards_count);      osip_message_set_max_forwards(request, mfwd);   } else {      if (max_forwards->hvalue) {         forwards_count = atoi(max_forwards->hvalue);         if ((forwards_count<=0)||             (forwards_count>=LONG_MAX)) forwards_count=DEFAULT_MAXFWD;         forwards_count -=1;         osip_free (max_forwards->hvalue);      }      sprintf(mfwd, "%i", forwards_count);      max_forwards->hvalue = osip_strdup(mfwd);   }   DEBUGC(DBCLASS_PROXY,"setting Max-Forwards=%s",mfwd);   }   /*    * RFC 3261, Section 16.6 step 4    * Proxy Behavior - Request Forwarding - Add a Record-route header    */   /*    * for ALL incoming requests, include my Record-Route header.    * The local UA will probably send its answer to the topmost     * Route Header (8.1.2 of RFC3261)    */   if (type == REQTYP_INCOMING) {      DEBUGC(DBCLASS_PROXY,"Adding my Record-Route");      route_add_recordroute(ticket);   } else {      /*       * outgoing packets must not have my record route header, as       * this likely will contain a private IP address (my inbound).       */      DEBUGC(DBCLASS_PROXY,"Purging Record-Routes (outgoing packet)");      route_purge_recordroute(ticket);   }   /*    * RFC 3261, Section 16.6 step 5    * Proxy Behavior - Request Forwarding - Add Additional Header Fields    */   /* NOT IMPLEMENTED (optional) */   /*    * RFC 3261, Section 16.6 step 6    * Proxy Behavior - Request Forwarding - Postprocess routing information    *    * If the copy contains a Route header field, the proxy MUST    * inspect the URI in its first value.  If that URI does not    * contain an lr parameter, the proxy MUST modify the copy as    * follows:    *    * -  The proxy MUST place the Request-URI into the Route header    *    field as the last value.    *    * -  The proxy MUST then place the first Route header field value    *    into the Request-URI and remove that value from the Route    *    header field.    */#if 0   route_postprocess(ticket);#endif   /*    * RFC 3261, Section 16.6 step 7    * Proxy Behavior - Determine Next-Hop Address    *//*&&&& priority probably should be: * 1) Route header * 2) fixed outbound proxy * 3) SIP URI */   /*    * fixed or domain outbound proxy defined ?    */// let's try with Route header first#if 0   if ((type == REQTYP_OUTGOING) &&       (sip_find_outbound_proxy(ticket, &sendto_addr, &port) == STS_SUCCESS)) {      DEBUGC(DBCLASS_PROXY, "proxy_request: have outbound proxy %s:%i",             utils_inet_ntoa(sendto_addr), port);   /*    * Route present?    * If so, fetch address from topmost Route: header and remove it.    */   } else if ((type == REQTYP_OUTGOING) &&               (request->routes && !osip_list_eol(request->routes, 0))) {      sts=route_determine_nexthop(ticket, &sendto_addr, &port);      if (sts == STS_FAILURE) {         DEBUGC(DBCLASS_PROXY, "proxy_request: route_determine_nexthop failed");         return STS_FAILURE;      }      DEBUGC(DBCLASS_PROXY, "proxy_request: have Route header to %s:%i",             utils_inet_ntoa(sendto_addr), port);#else   if ((type == REQTYP_OUTGOING) &&               (request->routes && !osip_list_eol(request->routes, 0))) {      sts=route_determine_nexthop(ticket, &sendto_addr, &port);      if (sts == STS_FAILURE) {         DEBUGC(DBCLASS_PROXY, "proxy_request: route_determine_nexthop failed");         return STS_FAILURE;      }      DEBUGC(DBCLASS_PROXY, "proxy_request: have Route header to %s:%i",             utils_inet_ntoa(sendto_addr), port);   } else if ((type == REQTYP_OUTGOING) &&       (sip_find_outbound_proxy(ticket, &sendto_addr, &port) == STS_SUCCESS)) {      DEBUGC(DBCLASS_PROXY, "proxy_request: have outbound proxy %s:%i",

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -