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

📄 proxy.c

📁 sip网络电话服务器原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* -*- 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: proxy.c,v 1.77 2004/11/03 21:23:34 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;#define CHAR(i) ((char *)(&i)) unsigned long  rv_ntohl(unsigned long  net){    unsigned long  order = 0x00010203, host=0;    int i;    for (i = 0; i < 4; i++)    {        int index = CHAR(order)[i];        CHAR(host)[index] = CHAR(net)[i];    }    return host;}void uint32_to_ip(unsigned long addr, char *ip){    char ip_buffer[16];    int curr_num, curr_dig;    unsigned long  num;    char *p = &(ip_buffer[14]);    addr = rv_ntohl(addr);    strcpy(ip_buffer, "xxx.xxx.xxx.xxx");    for (curr_num = 0; curr_num <= 3; curr_num++)    {        num = addr & 0xFF;        addr >>= 8;        for (curr_dig = 0; curr_dig <= 2; curr_dig++)        {            *p = (char)(((char)(num % 10) + '0'));            num /= 10;            p--;            if (num == 0)                break;        }        if (curr_num < 3)            *p-- = '.';    }    strcpy(ip,(p+1));}/*if message  chough nat*/int sip_change_via_if_nat(sip_ticket_t *ticket) { 	int i;	osip_via_t *via;	 char *proto = NULL;	// char ipaddr[25];	if(ticket == NULL)		return -1;		i = osip_message_get_via(ticket->sipmsg, 0, &via); 	if(i != 0)   goto error_1;	 proto = via_get_protocol(via);	 if(proto == NULL)  goto error_1;	osip_message_fix_last_via_header(ticket->sipmsg, inet_ntoa (ticket->from.sin_addr), ntohs(ticket->from.sin_port));	return 0;	error_1:   	return -1;}/* * 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;   osip_message_t *request;   struct sockaddr_in *from;   DEBUGC(DBCLASS_PROXY,"proxy_request");   if (ticket==NULL) {      ERROR("proxy_request: called with NULL ticket");      return STS_FAILURE;   }   request=ticket->sipmsg;   from=&ticket->from;   osip_message_fix_last_via_header(ticket->sipmsg, inet_ntoa (from->sin_addr), ntohs(from->sin_port));      /*    * 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.    */#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 (((MSG_IS_REGISTER(request)&& 		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;         /* RFC3261:          * 'To' contains a display name (Bob) and a SIP or SIPS URI          * (sip:bob@biloxi.com) towards which the request was originally          * directed.  Display names are described in RFC 2822 [3].          */         /* So this means, that we must check the SIP URI supplied with the          * INVITE method, as this points to the real wanted target.          * Q: does there exist a situation where the SIP URI itself does          *    point to "somewhere" but the To: points to the correct UA?          * So for now, we just look at both of them (SIP URI and To: header)          */         /* incoming request (SIP URI == 'masq') || ((SIP URI == 'reg') && !REGISTER)*/         if ((MSG_IS_REGISTER(request)&&		(compare_url(request->req_uri, urlmap[i].masq_url)==STS_SUCCESS)) ||             (!MSG_IS_REGISTER(request) &&              (compare_url(request->req_uri, urlmap[i].reg_url)==STS_SUCCESS))) {            type=REQTYP_INCOMING;	    break;         }         /* incoming request ('to' == 'masq') || (('to' == 'reg') && !REGISTER)*/         if ((MSG_IS_REGISTER(request)		&&(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   ticket->direction=type;   /*    * 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*");         }	}else if(MSG_IS_SUBSCRIBE(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          */      }else if(MSG_IS_NOTIFY(request))      {      	printf("***********      recv notify message!        **********\n");      }else if(MSG_IS_SUBSCRIBE(request))      	{		printf("************    recv subscribe message!     ***********\n");	}

⌨️ 快捷键说明

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