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

📄 proxy.c

📁 这是一个C程序
💻 C
📖 第 1 页 / 共 3 页
字号:
if (configuration.debuglevel){ /* just dump the buffer */   char *tmp, *tmp2;   size_t tmplen;   sts = osip_message_get_body(mymsg, 0, &body);   sts = sip_body_to_str(body, &tmp, &tmplen);   osip_content_length_to_str(mymsg->content_length, &tmp2);   DEBUG("Body before rewrite (may be truncated) - (clen=%s, strlen=%ld):\n%s\n----",         tmp2, (long)tmplen, tmp);   osip_free(tmp);   osip_free(tmp2);}   /*    * RTP proxy: get ready and start forwarding    * start forwarding for each media stream ('m=' item in SIP message)    */   /* get outbound address */   if (get_interface_ip(IF_OUTBOUND, &outside_addr) != STS_SUCCESS) {      sdp_message_free(sdp);      return STS_FAILURE;   }   /* get inbound address */   if (get_interface_ip(IF_INBOUND, &inside_addr) != STS_SUCCESS) {      sdp_message_free(sdp);      return STS_FAILURE;   }   /* figure out what address to use for RTP masquerading */   if (MSG_IS_REQUEST(mymsg)) {      if (direction == DIR_INCOMING) {         memcpy(&map_addr, &inside_addr, sizeof (map_addr));         rtp_direction = DIR_OUTGOING;      } else {         memcpy(&map_addr, &outside_addr, sizeof (map_addr));         rtp_direction = DIR_INCOMING;      }   } else /* MSG_IS_REPONSE(mymsg) */ {      if (direction == DIR_INCOMING) {         memcpy(&map_addr, &inside_addr, sizeof (map_addr));         rtp_direction = DIR_OUTGOING;      } else {         memcpy(&map_addr, &outside_addr, sizeof (map_addr));         rtp_direction = DIR_INCOMING;      }   }   DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: SIP[%s %s] RTP[%s %s]",          MSG_IS_REQUEST(mymsg)? "RQ" : "RS",          (direction==DIR_INCOMING)? "IN" : "OUT",          (rtp_direction==DIR_INCOMING)? "IN" : "OUT",          utils_inet_ntoa(map_addr));   /*    * first, check presence of a 'c=' item on session level    */   if (sdp->c_connection==NULL || sdp->c_connection->c_addr==NULL) {      /*       * No 'c=' on session level, search on media level now       *       * According to RFC2327, ALL media description must       * include a 'c=' item now:       */      media_stream_no=0;      while (!sdp_message_endof_media(sdp, media_stream_no)) {         /* check if n'th media stream is present */         if (sdp_message_c_addr_get(sdp, media_stream_no, 0) == NULL) {            ERROR("SDP: have no 'c=' on session level and neither "                  "on media level (media=%i)",media_stream_no);            sdp_message_free(sdp);            return STS_FAILURE;         }         media_stream_no++;      } /* while */   }   /* Required 'c=' items ARE present */   /*    * rewrite 'c=' item on session level if present and not yet done.    * remember the original address in addr_sess    */   memset(&addr_sess, 0, sizeof(addr_sess));   if (sdp->c_connection && sdp->c_connection->c_addr) {      sts = get_ip_by_host(sdp->c_connection->c_addr, &addr_sess);      if (sts == STS_FAILURE) {         ERROR("SDP: cannot resolve session 'c=' host [%s]",               sdp->c_connection->c_addr);         sdp_message_free(sdp);         return STS_FAILURE;      }      /*       * Rewrite       * an IP address of 0.0.0.0 means *MUTE*, don't rewrite such       */      if (strcmp(sdp->c_connection->c_addr, "0.0.0.0") != 0) {         osip_free(sdp->c_connection->c_addr);         sdp->c_connection->c_addr=osip_malloc(HOSTNAME_SIZE);         sprintf(sdp->c_connection->c_addr, "%s", utils_inet_ntoa(map_addr));      } else {         /* 0.0.0.0 - don't rewrite */         DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "                "got a MUTE c= record (on session level - legal?)");      }   }   /*    * rewrite 'o=' item (originator) on session level if present.    */   if (sdp->o_addrtype && sdp->o_addr) {      if (strcmp(sdp->o_addrtype, "IP4") != 0) {         ERROR("got IP6 in SDP originator - not yet suported by siproxd");         sdp_message_free(sdp);         return STS_FAILURE;      }      osip_free(sdp->o_addr);      sdp->o_addr=osip_malloc(HOSTNAME_SIZE);      sprintf(sdp->o_addr, "%s", utils_inet_ntoa(map_addr));   }   /*    * loop through all media descritions,    * start RTP proxy and rewrite them    */   for (media_stream_no=0;;media_stream_no++) {      /* check if n'th media stream is present */      if (sdp_message_m_port_get(sdp, media_stream_no) == NULL) break;      /*       * check if a 'c=' item is present in this media description,       * if so -> rewrite it       */      memset(&addr_media, 0, sizeof(addr_media));      have_c_media=0;      sdp_conn=sdp_message_connection_get(sdp, media_stream_no, 0);      if (sdp_conn && sdp_conn->c_addr) {         if (strcmp(sdp_conn->c_addr, "0.0.0.0") != 0) {            sts = get_ip_by_host(sdp_conn->c_addr, &addr_media);            have_c_media=1;            /* have a valid address */            osip_free(sdp_conn->c_addr);            sdp_conn->c_addr=osip_malloc(HOSTNAME_SIZE);            sprintf(sdp_conn->c_addr, "%s", utils_inet_ntoa(map_addr));         } else {            /* 0.0.0.0 - don't rewrite */            DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: got a "                   "MUTE c= record (media level)");         }      }      /* start an RTP proxying stream */      if (sdp_message_m_port_get(sdp, media_stream_no)) {         msg_port=atoi(sdp_message_m_port_get(sdp, media_stream_no));         if ((msg_port > 0) && (msg_port <= 65535)) {            client_id_t client_id;            osip_contact_t *contact = NULL;            char *tmp=NULL;            char *protocol=NULL;            /* try to get some additional UA specific unique ID.             * This Client-ID should be guaranteed persistent             * and not depend on if a UA/Server does include a             * particular Header (Contact) or not.             * I should just go for the remote IP address here, no?             */            /* &&& NO, using the sender IP will cause troubles if             * the remote peer (Proxy/registrar) is thrown out of             * the signalling path. Then suddenly the IP address changes.             *             * I should probably go back to the Contact Header based idea,             * with fallback to IP.             * I must use a n-item structure, including all things that             * can be used for comparing. Then, in the RTP proxy, comparison             * must take place according to priorities with the item             * with highest priority present in the RTP table *and*             * extracted from the SIP message.             * To start with, this can be just 2 things, the Contact header             * and the Layer 3 IP address. As long as the UAs include the             * Contact header, we survive IP changes (e.g. when the SIP             * Registrar/Proxy is removed from signalling path within an             * ongoing call. This may happen if the Registrar/Proxy does             * not explicitely ask to stay in the signalling path using              * Record-Route headers - which is perfectly legal             *             */            memset(&client_id, 0, sizeof(client_id));            /* get the Contact Header if present */            osip_message_get_contact(mymsg, 0, &contact);            if (contact) osip_contact_to_str(contact, &tmp);            if (tmp) strncpy(client_id.contact, tmp, CLIENT_ID_SIZE-1);            /* store the IP address of the sender */            memcpy(&client_id.from_ip, &ticket->from.sin_addr,                   sizeof(client_id.from_ip));            /*             * is this an RTP stream ? If yes, set 'isrtp=1'             */            protocol = sdp_message_m_proto_get (sdp, media_stream_no);            if (protocol == NULL) {               DEBUGC(DBCLASS_PROXY, "no protocol definition found!");            } else {               char *check;               char *cmp;               isrtp = 1;               check = protocol ;               cmp = "RTP/" ;               while (*cmp && (isrtp = isrtp && *check) &&                       (isrtp = isrtp && (*cmp++ == toupper(*check++))) ) {} ;               if (isrtp) {                  DEBUGC(DBCLASS_PROXY, "found RTP protocol [%s]!", protocol);               } else {                  DEBUGC(DBCLASS_PROXY, "found non RTP protocol [%s]!", protocol);               }            }            /*             * do we have a 'c=' item on media level?             * if not, use the same as on session level             */            if (have_c_media == 0) {               memcpy(&addr_media, &addr_sess, sizeof(addr_sess));            }            /*             * Am I running in front of the routing device? Then I cannot             * use the external IP to bind a listen socket to, but should             * use my real IP on the outbound interface (which may legally             * be the same as the inbound interface if only one interface             * is used).             */            if ((rtp_direction == DIR_INCOMING) &&                (configuration.outbound_host) &&                (strcmp(configuration.outbound_host, "")!=0)) {               DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "                      "in-front-of-NAT-Router, use real outboud IP");               if (get_interface_real_ip(IF_OUTBOUND, &map_addr)                   != STS_SUCCESS) {                  ERROR("cannot get my real outbound interface address");                  /* as we do not know better, take the internal address */                  memcpy(&map_addr, &inside_addr, sizeof (map_addr));               }            }            sts = rtp_start_fwd(osip_message_get_call_id(mymsg),                                client_id,                                rtp_direction,                                media_stream_no,                                map_addr, &map_port,                                addr_media, msg_port,                                isrtp);            if (sts == STS_SUCCESS) {               /* and rewrite the port */               sdp_med=osip_list_get(&(sdp->m_medias), media_stream_no);               if (sdp_med && sdp_med->m_port) {                  osip_free(sdp_med->m_port);                  sdp_med->m_port=osip_malloc(8); /* 5 digits, \0 + align */                  sprintf(sdp_med->m_port, "%i", map_port);                  DEBUGC(DBCLASS_PROXY, "proxy_rewrite_invitation_body: "                         "m= rewrote port to [%i]",map_port);               } else {                  ERROR("rewriting port in m= failed sdp_med=%p, "                        "m_number_of_port=%p", sdp_med, sdp_med->m_port);               }            } /* sts == success */         } /* if msg_port > 0 */      } else {         /* no port defined - skip entry */         WARN("no port defined in m=(media) stream_no=%i", media_stream_no);         continue;      }   } /* for media_stream_no */   /* remove old body */   sts = osip_list_remove(&(mymsg->bodies), 0);   osip_body_free(body);   /* dump new body */   sdp_message_to_str(sdp, &buff);   buflen=strlen(buff);   /* free sdp structure */   sdp_message_free(sdp);   /* include new body */   sip_message_set_body(mymsg, buff, buflen);   if (sts != 0) {      ERROR("rewrite_invitation_body: unable to sip_message_set_body body");   }   /* free content length resource and include new one*/   osip_content_length_free(mymsg->content_length);   mymsg->content_length=NULL;   sprintf(clen,"%ld",(long)buflen);   sts = osip_message_set_content_length(mymsg, clen);   /* free old body */   osip_free(buff);if (configuration.debuglevel){ /* just dump the buffer */   char *tmp, *tmp2;   size_t tmplen;   sts = osip_message_get_body(mymsg, 0, &body);   sts = sip_body_to_str(body, &tmp, &tmplen);   osip_content_length_to_str(mymsg->content_length, &tmp2);   DEBUG("Body after rewrite (may be truncated) - (clen=%s, strlen=%ld):\n%s\n----",         tmp2, (long)tmplen, tmp);   osip_free(tmp);   osip_free(tmp2);}   return STS_SUCCESS;}/* * PROXY_REWRITE_REQUEST_URI * * rewrites the incoming Request URI *  * RETURNS *	STS_SUCCESS on success */int proxy_rewrite_request_uri(osip_message_t *mymsg, int idx){   char *scheme;   char *username;   char *host;   char *port;   osip_uri_t *url;   if ((idx >= URLMAP_SIZE) || (idx < 0)) {      WARN("proxy_rewrite_request_uri: called with invalid index");      return STS_FAILURE;   }   DEBUGC(DBCLASS_PROXY,"rewriting incoming Request URI");   url=osip_message_get_uri(mymsg);   /* set the true scheme */   if (url->scheme) {osip_free(url->scheme);url->scheme=NULL;}   if (urlmap[idx].true_url->scheme) {      DEBUGC(DBCLASS_BABBLE,"proxy_rewrite_request_uri: scheme=%s",             urlmap[idx].true_url->scheme);      scheme = (char *)osip_malloc(strlen(urlmap[idx].true_url->scheme)+1);      memcpy(scheme, urlmap[idx].true_url->scheme,             strlen(urlmap[idx].true_url->scheme));      scheme[strlen(urlmap[idx].true_url->scheme)]='\0';      osip_uri_set_scheme(url, scheme);   }   /* set the true username */   if (url->username) {osip_free(url->username);url->username=NULL;}   if (urlmap[idx].true_url->username) {      DEBUGC(DBCLASS_BABBLE,"proxy_rewrite_request_uri: username=%s",             urlmap[idx].true_url->username);      username = (char*)osip_malloc(strlen(urlmap[idx].true_url->username)+1);      memcpy(username, urlmap[idx].true_url->username,             strlen(urlmap[idx].true_url->username));      username[strlen(urlmap[idx].true_url->username)]='\0';      osip_uri_set_username(url, username);   }   /* set the true host */   if (url->host) {osip_free(url->host);url->host=NULL;}   if (urlmap[idx].true_url->host) {      DEBUGC(DBCLASS_BABBLE,"proxy_rewrite_request_uri: host=%s",             urlmap[idx].true_url->host);      host = (char *)osip_malloc(strlen(urlmap[idx].true_url->host)+1);      memcpy(host, urlmap[idx].true_url->host, strlen(urlmap[idx].true_url->host));      host[strlen(urlmap[idx].true_url->host)]='\0';      osip_uri_set_host(url, host);   }   /* set the true port */   if (url->port) {osip_free(url->port);url->port=NULL;}   if (urlmap[idx].true_url->port) {      DEBUGC(DBCLASS_BABBLE,"proxy_rewrite_request_uri: port=%s",             urlmap[idx].true_url->port);      port = (char *)osip_malloc(strlen(urlmap[idx].true_url->port)+1);      memcpy(port, urlmap[idx].true_url->port, strlen(urlmap[idx].true_url->port));      port[strlen(urlmap[idx].true_url->port)]='\0';      osip_uri_set_port(url, port);   }   return STS_SUCCESS;}/* * PROXY_REWRITE_USERAGENT * * rewrites the User Agent String *  * RETURNS *	STS_SUCCESS on success */int proxy_rewrite_useragent(sip_ticket_t *ticket){   osip_header_t *ua_hdr=NULL;   osip_message_get_user_agent(ticket->sipmsg, 0, &ua_hdr);   /* Configured? & Does User-Agent header exist? */   if ((configuration.ua_string) && (ua_hdr && ua_hdr->hvalue)) {      DEBUGC(DBCLASS_PROXY,"proxy_rewrite_useragent: [%s] -> [%s]",             ua_hdr->hvalue, configuration.ua_string);      osip_free(ua_hdr->hvalue);      ua_hdr->hvalue=osip_malloc(strlen(configuration.ua_string)+1);      strcpy(ua_hdr->hvalue, configuration.ua_string);   }   return STS_SUCCESS;}

⌨️ 快捷键说明

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