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

📄 proxy.c

📁 sip网络电话服务器原代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    * so let's take FROM instead...    * the TO and FROM headers are EQUAL to the request - that means     * they are swapped in their meaning for a response...    */#if _OLD_DIRECTION_EVALUATION   type = 0;   for (i=0; i<URLMAP_SIZE; i++) {      if (urlmap[i].active == 0) continue;      /* incoming response ('from' == 'masq') || ('from' == 'reg') */      if ((compare_url(response->from->url, urlmap[i].reg_url)==STS_SUCCESS)		||(compare_url(response->from->url, urlmap[i].masq_url)==STS_SUCCESS))     {         type=RESTYP_INCOMING;         DEBUGC(DBCLASS_PROXY,"incoming response for %s@%s from outbound",	   response->from->url->username? response->from->url->username:"*NULL*",	   response->from->url->host? response->from->url->host : "*NULL*");	 break;      }      /* outgoing response ('to' == 'reg') || ('to' == 'masq' ) */      if ((compare_url(response->to->url, urlmap[i].masq_url)==STS_SUCCESS) ||          (compare_url(response->to->url, urlmap[i].reg_url)==STS_SUCCESS)){         type=RESTYP_OUTGOING;         DEBUGC(DBCLASS_PROXY,"outgoing response for %s@%s from inbound",	        response->from->url->username ?                   response->from->url->username : "*NULL*",	        response->from->url->host ?                    response->from->url->host : "*NULL*");	 break;      }   }#else   type = 0;   /*    * did I receive the telegram from a REGISTERED host?    * -> it must be an OUTGOING response    */   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_response: cannot resolve host [%s]",             urlmap[i].true_url);      } else {         DEBUGC(DBCLASS_PROXY, "proxy_response: 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=RESTYP_OUTGOING;	    break;         }      }   }   /*    * is the telegram directed to an internal registered host?    * -> it must be an INCOMING response    */   if (type == 0) {      for (i=0; i<URLMAP_SIZE; i++) {         if (urlmap[i].active == 0) continue;         /* incoming response ('from' == 'masq') || ('from' == 'reg') */         if ((compare_url(response->from->url, urlmap[i].reg_url)==STS_SUCCESS) ||             (compare_url(response->from->url, urlmap[i].masq_url)==STS_SUCCESS)) {            type=RESTYP_INCOMING;	    break;         }      }   }/* &&&& Open Issue &&&&   it has been seen with cross-provider calls that the FROM may be 'garbled'   (e.g 1393xxx@proxy01.sipphone.com for calls made sipphone -> FWD)   How can we deal with this? Should I take into consideration the 'Via'   headers? This is the only clue I have, pointing to the *real* UA.   Maybe I should put in a 'siproxd' ftag value to recognize it a header   put in by myself*/   if ((type == 0) && (!osip_list_eol(response->vias, 0)))    {      osip_via_t *via;      struct in_addr addr_via, addr_myself;      int port_via, port_ua;      osip_generic_param_t *received;      osip_generic_param_t *rport;      /* get the via address */      via = (osip_via_t *) osip_list_get (response->vias, 0);      DEBUGC(DBCLASS_PROXY, "proxy_response: check via [%s] for "             "registered UA",via->host);printf("444444444444444444444444444444444444444444444444444444\n");    osip_via_param_get_byname(via, "received",&received);    osip_via_param_get_byname (via, "rport", &rport);    if(received != NULL && received->gvalue !=NULL)    {        if (utils_inet_aton(received->gvalue,&addr_via) == 0)	 {      		/* yes, get IP address */      		sts = get_ip_by_host(received->gvalue, &addr_via);      		if (sts == STS_FAILURE) 		{        	 	DEBUGC(DBCLASS_REG, "aaaaa_response: cannot resolve VIA [%s]",                received->gvalue);      		}   	}   }   else   {      sts=get_ip_by_host(via->host, &addr_via);      if (sts == STS_FAILURE)       {         DEBUGC(DBCLASS_DNS, "proxy_response: cannot resolve VIA [%s]",                via->host);      }    }        	if(sts == STS_SUCCESS){        	for (i=0; i<URLMAP_SIZE; i++) 	 	{            		if (urlmap[i].active == 0) continue;            		/* incoming response (1st via in list points to a registered UA) */            		sts=get_ip_by_host(urlmap[i].true_url->host, &addr_myself);            		if (sts == STS_FAILURE) 	    		{               			DEBUGC(DBCLASS_DNS, "proxy_response: cannot resolve "                      		"true_url [%s]", via->host);               			continue;            		}            	port_via=0;	    	if(rport!=NULL && rport->gvalue != NULL)	    	{			port_via = atoi(rport->gvalue);	    	}	    	else if (via->port)	    	{ 			port_via=atoi(via->port);	    	}                        	if (port_via <= 0) port_via=SIP_PORT;            	port_ua=0;            	if (urlmap[i].true_url->port)               		port_ua=atoi(urlmap[i].true_url->port);            	if (port_ua <= 0) port_ua=SIP_PORT;           	 DEBUGC(DBCLASS_BABBLE, "proxy_response: checking for registered "                	   "host [%s:%i] <-> [%s:%i]",                   urlmap[i].true_url->host, port_ua,                   via->host, port_via);            if ((memcmp(&addr_myself, &addr_via, sizeof(addr_myself))==0) &&                (port_via == port_ua))             {               type=RESTYP_INCOMING;	       break;            }         }      }  }     #endif   ticket->direction=type;/* * ok, we got a response that we are allowed to process. */   switch (type) {  /*   * from an external host to the internal masqueraded host   */   case RESTYP_INCOMING:      DEBUGC(DBCLASS_PROXY,"incoming response for %s@%s from outbound",	response->from->url->username? response->from->url->username:"*NULL*",	response->from->url->host? response->from->url->host : "*NULL*");      /*       * Response for INVITE - deal with RTP data in body and       *                       start RTP proxy stream(s). In case       *                       of a negative answer, stop RTP stream       */      if (MSG_IS_RESPONSE_FOR(response,"INVITE")) {         /* positive response, start RTP stream */         if ((MSG_IS_STATUS_1XX(response)) ||               (MSG_IS_STATUS_2XX(response))) {            if (configuration.rtp_proxy_enable == 1) {               sts = proxy_rewrite_invitation_body(response, DIR_INCOMING);            }         /* negative - stop a possibly started RTP stream */         } else if ((MSG_IS_STATUS_4XX(response))  ||                     (MSG_IS_STATUS_5XX(response)) ||                     (MSG_IS_STATUS_6XX(response))) {            rtp_stop_fwd(osip_message_get_call_id(response), DIR_INCOMING);            rtp_stop_fwd(osip_message_get_call_id(response), DIR_OUTGOING);         }      } /* if INVITE */      /*       * Response for REGISTER - special handling of Contact header       */      if (MSG_IS_RESPONSE_FOR(response,"REGISTER")) {         /*          * REGISTER returns *my* Contact header information.          * Rewrite Contact header back to represent the true address.          * Other responses do return the Contact header of the sender.          */         sip_rewrite_contact(ticket, DIR_INCOMING);      }      /*        * Response for SUBSCRIBE       *       * HACK for Grandstream SIP phones (with newer firmware like 1.0.4.40):       *   They send a SUBSCRIBE request to the registration server. In       *   case of beeing registering directly to siproxd, this request of       *   course will eventually be forwarded back to the same UA.       *   Grandstream then does reply with an '202' response (A 202       *   response merely indicates that the subscription has been       *   understood, and that authorization may or may not have been       *   granted), which then of course is forwarded back to the phone.       *   Ans it seems that the Grandstream can *not* *handle* this       *   response, as it immediately sends another SUBSCRIBE request.       *   And this games goes on and on and on...       *       *   As a workaround we will transform any 202 response to a       *   '404 unknown destination'       *          */{      osip_header_t *ua_hdr=NULL;      osip_message_get_user_agent(response, 0, &ua_hdr);      if (ua_hdr && ua_hdr->hvalue &&          (osip_strncasecmp(ua_hdr->hvalue,"grandstream", 11)==0) &&          (MSG_IS_RESPONSE_FOR(response,"SUBSCRIBE")) &&          (MSG_TEST_CODE(response, 202))) {         DEBUGC(DBCLASS_PROXY, "proxy_response: Grandstream hack 202->404");         response->status_code=404;      }}      break;     /*   * from the internal masqueraded host to an external host   */   case RESTYP_OUTGOING:      DEBUGC(DBCLASS_PROXY,"outgoing response for %s@%s from inbound",	     response->from->url->username ?                response->from->url->username : "*NULL*",	     response->from->url->host ?                 response->from->url->host : "*NULL*");      /* rewrite Contact header to represent the masqued address */      sip_rewrite_contact(ticket, DIR_OUTGOING);      /*       * If an 2xx OK or 1xx response, answer to an INVITE request,       * rewrite body       *       * In case of a negative answer, stop RTP stream       */      if (MSG_IS_RESPONSE_FOR(response,"INVITE")) {         /* positive response, start RTP stream */         if ((MSG_IS_STATUS_1XX(response)) ||               (MSG_IS_STATUS_2XX(response))) {            /* This is an outgoing response, therefore an outgoing stream */            sts = proxy_rewrite_invitation_body(response, DIR_OUTGOING);         /* megative - stop a possibly started RTP stream */         } else if ((MSG_IS_STATUS_4XX(response))  ||                     (MSG_IS_STATUS_5XX(response)) ||                     (MSG_IS_STATUS_6XX(response))) {            rtp_stop_fwd(osip_message_get_call_id(response), DIR_INCOMING);            rtp_stop_fwd(osip_message_get_call_id(response), DIR_OUTGOING);         }      } /* if INVITE */      break;      default:      DEBUGC(DBCLASS_PROXY, "response from/to unregistered UA (%s@%s)",	   response->from->url->username? response->from->url->username:"*NULL*",	   response->from->url->host? response->from->url->host : "*NULL*");      return STS_FAILURE;   }   /*    * for ALL incoming response 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 == RESTYP_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);    }   /*    * Determine Next-Hop Address    *//*&&&& priority probably should be: * 1) Route header * 2) fixed outbound proxy * 3) SIP URI */   /*    * check if we need to send to an outbound proxy    */   if ((type == RESTYP_OUTGOING) && (configuration.outbound_proxy_host)) {      /* have an outbound proxy - use it to send the packet */      sts = get_ip_by_host(configuration.outbound_proxy_host, &sendto_addr);      if (sts == STS_FAILURE) {         DEBUGC(DBCLASS_PROXY, "proxy_response: cannot resolve outbound "                " proxy host [%s]", configuration.outbound_proxy_host);         return STS_FAILURE;      }      if (configuration.outbound_proxy_port) {         port=configuration.outbound_proxy_port;      } else {         port = SIP_PORT;      }   /*    * Route present?    * If so, fetch address from topmost Route: header and remove it.    */   } else if ((type == RESTYP_OUTGOING) &&               (response->routes && !osip_list_eol(response->routes, 0))) {      sts=route_determine_nexthop(ticket, &sendto_addr, &port);      if (sts == STS_FAILURE) {         DEBUGC(DBCLASS_PROXY, "proxy_response: route_determine_nexthop failed");         return STS_FAILURE;      }      DEBUGC(DBCLASS_PROXY, "proxy_response: have Route header to %s:%i",             utils_inet_ntoa(sendto_addr), port);   } else {       osip_generic_param_t *received;       osip_generic_param_t *rport;      /* get target address and port from VIA header */      via = (osip_via_t *) osip_list_get (response->vias, 0);      if (via == NULL) {         ERROR("proxy_response: list_get via failed");         return STS_FAILURE;      }      osip_via_param_get_byname(via, "received",&received);      osip_via_param_get_byname (via, "rport", &rport);      if(received != NULL)      {	sts = get_ip_by_host(received->gvalue, &sendto_addr);      }      else      {      	sts = get_ip_by_host(via->host, &sendto_addr);      }            if (sts == STS_FAILURE) {         DEBUGC(DBCLASS_PROXY, "proxy_response: cannot resolve VIA [%s]",                via->host);         return STS_FAILURE;      }            	if(rport!=NULL && rport->gvalue!=NULL)      	{        	port = atoi(rport->gvalue);      	}      	else if (via->port)       	{

⌨️ 快捷键说明

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