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

📄 sip_utils.c

📁 Siproxd is a proxy/masquerading daemon for the SIP protocol. It handles registrations of SIP client
💻 C
📖 第 1 页 / 共 3 页
字号:
 * - magic cookie "z9hG4bK" * - 1st part (unique calculated ID * - 2nd part (value for loop detection) <<- not yet used by siproxd */   osip_message_t *sip_msg=ticket->sipmsg;   static char *magic_cookie="z9hG4bK";   osip_via_t *via;   osip_uri_param_t *param=NULL;   osip_call_id_t *call_id=NULL;   HASHHEX hashstring;   hashstring[0]='\0';   /*    * Examine topmost via and look for a magic cookie.    * If it is there, I use THIS branch parameter as input for    * our hash calculation    */   via = osip_list_get (sip_msg->vias, 0);   if (via == NULL) {      ERROR("have a SIP message without any via header");      return STS_FAILURE;   }   param=NULL;   osip_via_param_get_byname(via, "branch", &param);   if (param && param->gvalue) {      DEBUGC(DBCLASS_BABBLE, "looking for magic cookie [%s]",param->gvalue);      if (strncmp(param->gvalue, magic_cookie,                  strlen(magic_cookie))==0) {         /* calculate MD5 hash */         MD5_CTX Md5Ctx;         HASH HA1;         MD5Init(&Md5Ctx);         MD5Update(&Md5Ctx, param->gvalue,                   strlen(param->gvalue));         MD5Final(HA1, &Md5Ctx);         CvtHex(HA1, hashstring);         DEBUGC(DBCLASS_BABBLE, "existing branch -> branch hash [%s]",                hashstring);      }   }   /*    * If I don't have a branch parameter in the existing topmost via,    * then I need:    *   - the topmost via    *   - the tag in the To header field    *   - the tag in the From header field    *   - the Call-ID header field    *   - the CSeq number (but not method)    *   - the Request-URI from the received request    */   if (hashstring[0] == '\0') {      /* calculate MD5 hash */      MD5_CTX Md5Ctx;      HASH HA1;      char *tmp;      MD5Init(&Md5Ctx);      /* topmost via */      osip_via_to_str(via, &tmp);      if (tmp) {         MD5Update(&Md5Ctx, tmp, strlen(tmp));         osip_free(tmp);      }           /* Tag in To header */      osip_to_get_tag(sip_msg->to, &param);      if (param && param->gvalue) {         MD5Update(&Md5Ctx, param->gvalue, strlen(param->gvalue));      }      /* Tag in From header */      osip_from_get_tag(sip_msg->from, &param);      if (param && param->gvalue) {         MD5Update(&Md5Ctx, param->gvalue, strlen(param->gvalue));      }      /* Call-ID */      call_id = osip_message_get_call_id(sip_msg);      osip_call_id_to_str(call_id, &tmp);      if (tmp) {         MD5Update(&Md5Ctx, tmp, strlen(tmp));         osip_free(tmp);      }      /* CSeq number (but not method) */      tmp = osip_cseq_get_number(sip_msg->cseq);      if (tmp) {         MD5Update(&Md5Ctx, tmp, strlen(tmp));      }       /* Request URI */      osip_uri_to_str(sip_msg->req_uri, &tmp);      if (tmp) {         MD5Update(&Md5Ctx, tmp, strlen(tmp));         osip_free(tmp);      }      MD5Final(HA1, &Md5Ctx);      CvtHex(HA1, hashstring);      DEBUGC(DBCLASS_BABBLE, "non-existing branch -> branch hash [%s]",             hashstring);   }   /* include the magic cookie */   sprintf(id, "%s%s", magic_cookie, hashstring);   return STS_SUCCESS;}/* * SIP_FIND_OUTBOUND_PROXY * * performs the lookup for an apropriate outbound proxy * * RETURNS *	STS_SUCCESS on successful lookup *	STS_FAILURE if no outbound proxy to be used */int  sip_find_outbound_proxy(sip_ticket_t *ticket, struct in_addr *addr,                             int *port) {   int i, sts;   char *domain=NULL;   osip_message_t *sipmsg;   sipmsg=ticket->sipmsg;   if (!addr ||!port) {      ERROR("sip_find_outbound_proxy called with NULL addr or port");      return STS_FAILURE;   }   if (sipmsg && sipmsg->from && sipmsg->from->url) {      domain=sipmsg->from->url->host;   }   if (domain == NULL) {      WARN("sip_find_outbound_proxy called with NULL from->url->host");      return STS_FAILURE;   }   /*    * check consistency of configuration:    * outbound_domain_name, outbound_domain_host, outbound_domain_port    * must match up    */   if ((configuration.outbound_proxy_domain_name.used !=        configuration.outbound_proxy_domain_host.used) ||       (configuration.outbound_proxy_domain_name.used !=        configuration.outbound_proxy_domain_port.used)) {      ERROR("configuration of outbound_domain_ inconsistent, check config");   } else {      /*       * perform the lookup for domain specific proxies       * first match wins       */      for (i=0; i<configuration.outbound_proxy_domain_name.used; i++) {         if (strcmp(configuration.outbound_proxy_domain_name.string[i],             domain)==0) {            sts = get_ip_by_host(configuration.outbound_proxy_domain_host.string[i],                                 addr);            if (sts == STS_FAILURE) {               ERROR("sip_find_outbound_proxy: cannot resolve "                     "outbound proxy host [%s], check config",                      configuration.outbound_proxy_domain_host.string[i]);               return STS_FAILURE;            }            *port=atoi(configuration.outbound_proxy_domain_port.string[i]);            if (*port == 0) *port = SIP_PORT;            return STS_SUCCESS;         } /* strcmp */      } /* for i */   }   /*    * now check for a global outbound proxy    */   if (configuration.outbound_proxy_host) {      /* I have a global outbound proxy configured */      sts = get_ip_by_host(configuration.outbound_proxy_host, addr);      if (sts == STS_FAILURE) {         DEBUGC(DBCLASS_PROXY, "proxy_request: 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;      }      DEBUGC(DBCLASS_PROXY, "proxy_request: have outbound proxy %s:%i",             configuration.outbound_proxy_host, *port);      return STS_SUCCESS;   }   return STS_FAILURE; /* no proxy */}/* * SIP_IS_OUTGOING * * Figures out if this is an outgoing or incoming request/response. * The direction is stored in the ticket->direction property. * * RETURNS *	STS_SUCCESS on success *	STS_FAILURE if unable to determine */int  sip_find_direction(sip_ticket_t *ticket, int *urlidx) {   int type;   int i, sts;   struct sockaddr_in *from;   osip_message_t *request;   osip_message_t *response;   from=&ticket->from;   request=ticket->sipmsg;   response=ticket->sipmsg;   type = 0;   ticket->direction = 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_SIP, "sip_find_direction: cannot resolve host [%s]",             urlmap[i].true_url->host);      } else {         DEBUGC(DBCLASS_SIP, "sip_find_direction: 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) {            if (MSG_IS_REQUEST(ticket->sipmsg)) {               type=REQTYP_OUTGOING;            } else {               type=RESTYP_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)          */         if (MSG_IS_REQUEST(ticket->sipmsg)) {            /* REQUEST */            /* incoming request (SIP URI == 'masq') || ((SIP URI == 'reg') && !REGISTER)*/            if ((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 ((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;            }         } else {             /* RESPONSE */            /* 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;            }         } /* is request */      } /* for i */   } /* if type == 0 */   if (MSG_IS_RESPONSE(ticket->sipmsg)) {      /* &&&& 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 as a header         inserted 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;         /* get the via address */         via = (osip_via_t *) osip_list_get (response->vias, 0);         DEBUGC(DBCLASS_SIP, "sip_find_direction: check via [%s] for "                "registered UA",via->host);         sts=get_ip_by_host(via->host, &addr_via);         if (sts == STS_FAILURE) {            DEBUGC(DBCLASS_SIP, "sip_find_direction: cannot resolve VIA [%s]",                   via->host);         } else {            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_SIP, "sip_find_direction: cannot resolve "                         "true_url [%s]", via->host);                  continue;               }               port_via=0;               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_SIP, "sip_find_direction: 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;               }            } /* for i */         }      } /* if type == 0 */   } /* is response */   if (type == 0) {      DEBUGC(DBCLASS_SIP, "sip_find_direction: unable to determine "                          "direction of SIP packet");      return STS_FAILURE;   }   ticket->direction=type;   if (urlidx) *urlidx=i;   return STS_SUCCESS;}

⌨️ 快捷键说明

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