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

📄 proxy.c

📁 siproxd is a proxy/masquerading for the SIP protocal.
💻 C
📖 第 1 页 / 共 3 页
字号:
/* -*- Mode: C; c-basic-offset: 3 -*-    Copyright (C) 2002  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 <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: " __FILE__ ": " PACKAGE "-" VERSION "-"			  BUILDSTR " $";/* configuration storage */extern struct siproxd_config configuration;extern int errno;extern struct urlmap_s urlmap[];		/* URL mapping table     */extern struct lcl_if_s local_addresses;extern int sip_socket;				/* sending SIP datagrams *//* * 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 (osip_message_t *request, struct sockaddr_in *from) {   int i;   int sts;   int type;   struct in_addr sendto_addr;   osip_uri_t *url;   int port;   char *buffer;#define REQTYP_INCOMING		1#define REQTYP_OUTGOING		2   DEBUGC(DBCLASS_PROXY,"proxy_request");   /*    * RFC 3261, Section 16.4    * Proxy Behavior - Route Information Preprocessing    * (process Route header)    *//*   The proxy MUST inspect the Request-URI of the request.  If the   Request-URI of the request contains a value this proxy previously   placed into a Record-Route header field (see Section 16.6 item 4),   the proxy MUST replace the Request-URI in the request with the last   value from the Route header field, and remove that value from the   Route header field.  The proxy MUST then proceed as if it received   this modified request.   NOT IMPLEMENTED*/   /*    * Check if I am listed at the topmost Route header (if any Route    * header is existing at all). If so, remove it from the list and    * rewrite the request URI to point to the now topmost Route.    */   if (request->routes && !osip_list_eol(request->routes, 0)) {      struct in_addr addr1, addr2, addr3;      osip_route_t *route;            route = (osip_route_t *) osip_list_get(request->routes, 0);            sts = get_ip_by_host(route->url->host, &addr1);      get_ip_by_ifname(configuration.inbound_if, &addr2);      get_ip_by_ifname(configuration.outbound_if, &addr3);            if ((sts == STS_SUCCESS) &&          ((memcmp(&addr1, &addr2, sizeof(addr1)) == 0) ||           (memcmp(&addr1, &addr3, sizeof(addr1)) == 0)) &&           (route->url->port ?               configuration.sip_listen_port == atoi(route->url->port):               configuration.sip_listen_port == SIP_PORT)) {         osip_list_remove(request->routes, 0);         osip_route_free(route);         /* request->routes will be freed by osip_message_free() */         DEBUGC(DBCLASS_PROXY,"removed Route header pointing to myself");      }   }         /*    * figure out whether this is an incoming or outgoing request    * by doing a lookup in the registration table.    */#define _OLD_DIRECTION_EVALUATION 0#if _OLD_DIRECTION_EVALUATION   type = 0;   for (i=0; i<URLMAP_SIZE; i++) {      if (urlmap[i].active == 0) continue;      /* incoming request ('to' == 'masq') || (('to' == 'reg') && !REGISTER)*/      if ((compare_url(request->to->url, urlmap[i].masq_url)==STS_SUCCESS) ||          (!MSG_IS_REGISTER(request) &&           (compare_url(request->to->url, urlmap[i].reg_url)==STS_SUCCESS))) {         type=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*");	 break;      }      /* outgoing request ('from' == 'reg') */      if (compare_url(request->from->url, urlmap[i].reg_url)==STS_SUCCESS) {         type=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*");	 break;      }   }#else   type = 0;   /*    * did I receive the telegram from a REGISTERED host?    * -> it must be an OUTGOING request    */   for (i=0; i<URLMAP_SIZE; i++) {      struct in_addr tmp_addr;      if (urlmap[i].active == 0) continue;      if (get_ip_by_host(urlmap[i].true_url->host, &tmp_addr) == STS_FAILURE) {         DEBUGC(DBCLASS_PROXY, "proxy_request: cannot resolve host [%s]",             urlmap[i].true_url);      } else {         DEBUGC(DBCLASS_PROXY, "proxy_request: reghost:%s ip:%s",                urlmap[i].true_url->host, utils_inet_ntoa(from->sin_addr));         if (memcmp(&tmp_addr, &from->sin_addr, sizeof(tmp_addr)) == 0) {            type=REQTYP_OUTGOING;	    break;         }      }   }   /*    * is the telegram directed to an internally registered host?    * -> it must be an INCOMING request    */   if (type == 0) for (i=0; i<URLMAP_SIZE; i++) {      if (urlmap[i].active == 0) continue;      /* incoming request ('to' == 'masq') || (('to' == 'reg') && !REGISTER)*/      if ((compare_url(request->to->url, urlmap[i].masq_url)==STS_SUCCESS) ||          (!MSG_IS_REGISTER(request) &&           (compare_url(request->to->url, urlmap[i].reg_url)==STS_SUCCESS))) {         type=REQTYP_INCOMING;	 break;      }   }#endif   /*    * logging of passing calls    */   if (configuration.log_calls) {      osip_uri_t *cont_url = NULL;      if (!osip_list_eol(request->contacts, 0))         cont_url = ((osip_contact_t*)(request->contacts->node->element))->url;            /* INVITE */      if (MSG_IS_INVITE(request)) {         if (cont_url) {            INFO("%s Call from: %s:%s",                 (type==REQTYP_INCOMING) ? "Incoming":"Outgoing",                 cont_url->username ? cont_url->username:"*NULL*",                 cont_url->host ? cont_url->host : "*NULL*");         } else {            INFO("%s Call (w/o contact header) from: %s:%s",                 (type==REQTYP_INCOMING) ? "Incoming":"Outgoing",	         request->from->url->username ?                     request->from->url->username:"*NULL*",	         request->from->url->host ?                     request->from->url->host : "*NULL*");         }      /* BYE / CANCEL */      } else if (MSG_IS_BYE(request) || MSG_IS_CANCEL(request)) {         if (cont_url) {            INFO("Ending Call from: %s:%s",                 cont_url->username ? cont_url->username:"*NULL*",                 cont_url->host ? cont_url->host : "*NULL*");         } else {            INFO("Ending Call (w/o contact header) from: %s:%s",	         request->from->url->username ?                     request->from->url->username:"*NULL*",	         request->from->url->host ?                     request->from->url->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 */      if (check_rewrite_rq_uri(request) == STS_TRUE) {         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)) {         /* First, rewrite the body */         if (configuration.rtp_proxy_enable == 1) {            sts = proxy_rewrite_invitation_body(request, DIR_INCOMING);         }         /*          * Note: Incoming requests have no need to rewrite Contact          * header - as we are not masquerading something there          */      }      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(request) == 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(request, 403 /*forbidden*/);         return STS_FAILURE;      }#endif      /* rewrite Contact header to represent the masqued address */      sip_rewrite_contact(request, DIR_OUTGOING);      /* if an INVITE, rewrite body */      if (MSG_IS_INVITE(request)) {         sts = proxy_rewrite_invitation_body(request, 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);      }      break;   

⌨️ 快捷键说明

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