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

📄 extl_udp.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 2 页
字号:
static inteXtl_update_local_target (osip_message_t * req){  int pos = 0;  struct eXosip_account_info *ainfo = NULL;  char *proxy = NULL;  int i;  if (MSG_IS_REQUEST (req))    {      if (req->from != NULL          && req->from->url != NULL && req->from->url->host != NULL)        proxy = req->from->url->host;  } else    {      if (req->to != NULL && req->to->url != NULL && req->to->url->host != NULL)        proxy = req->to->url->host;    }  if (proxy != NULL)    {      for (i = 0; i < MAX_EXOSIP_ACCOUNT_INFO; i++)        {          if (eXosip.account_entries[i].proxy[0] != '\0')            {              if (strstr (eXosip.account_entries[i].proxy, proxy) != NULL                  || strstr (proxy, eXosip.account_entries[i].proxy) != NULL)                {                  /* use ainfo */                  if (eXosip.account_entries[i].nat_ip[0] != '\0')                    {                      ainfo = &eXosip.account_entries[i];                      break;                    }                }            }        }    }  if (udp_firewall_ip != '\0')    {      while (!osip_list_eol (&req->contacts, pos))        {          osip_contact_t *co;          co = (osip_contact_t *) osip_list_get (&req->contacts, pos);          pos++;          if (co != NULL && co->url != NULL && co->url->host != NULL              && 0 == osip_strcasecmp (co->url->host, udp_firewall_ip))            {              if (ainfo == NULL)                {                  if (co->url->port == NULL &&                      0 != osip_strcasecmp (udp_firewall_port, "5060"))                    {                      co->url->port = osip_strdup (udp_firewall_port);                  } else if (co->url->port != NULL &&                             0 != osip_strcasecmp (udp_firewall_port,                                                   co->url->port))                    {                      osip_free (co->url->port);                      co->url->port = osip_strdup (udp_firewall_port);                    }              } else                {                  if (co->url->port == NULL && ainfo->nat_port != 5060)                    {                      co->url->port = osip_malloc (10);                      if (co->url->port == NULL)                        return OSIP_NOMEM;                      snprintf (co->url->port, 9, "%i", ainfo->nat_port);                  } else if (co->url->port != NULL &&                             ainfo->nat_port != atoi (co->url->port))                    {                      osip_free (co->url->port);                      co->url->port = osip_malloc (10);                      if (co->url->port == NULL)                        return OSIP_NOMEM;                      snprintf (co->url->port, 9, "%i", ainfo->nat_port);                    }                }            }        }    }  return OSIP_SUCCESS;}#ifndef INET6_ADDRSTRLEN#define INET6_ADDRSTRLEN 46#endifstatic intudp_tl_send_message (osip_transaction_t * tr, osip_message_t * sip, char *host,                     int port, int out_socket){  int len = 0;  size_t length = 0;  struct addrinfo *addrinfo;  struct __eXosip_sockaddr addr;  char *message;  char ipbuf[INET6_ADDRSTRLEN];  int i;  if (udp_socket <= 0)    return -1;  if (host == NULL)    {      host = sip->req_uri->host;      if (sip->req_uri->port != NULL)        port = osip_atoi (sip->req_uri->port);      else        port = 5060;    }  eXtl_update_local_target (sip);  i = -1;#ifndef MINISIZE  if (tr != NULL && tr->record.name[0] != '\0'      && tr->record.srventry[0].srv[0] != '\0')    {      /* always choose the first here.         if a network error occur, remove first entry and         replace with next entries.       */      osip_srv_entry_t *srv;      int n = 0;      for (srv = &tr->record.srventry[0];           n < 10 && tr->record.srventry[0].srv[0]; srv = &tr->record.srventry[0])        {          i = eXosip_get_addrinfo (&addrinfo, srv->srv, srv->port, IPPROTO_UDP);          if (i == 0)            {              host = srv->srv;              port = srv->port;              break;            }          memmove (&tr->record.srventry[0], &tr->record.srventry[1],                   9 * sizeof (osip_srv_entry_t));          memset (&tr->record.srventry[9], 0, sizeof (osip_srv_entry_t));          i = -1;          /* copy next element */          n++;        }    }#endif  /* if SRV was used, distination may be already found */  if (i != 0)    {      i = eXosip_get_addrinfo (&addrinfo, host, port, IPPROTO_UDP);    }  if (i != 0)    {      return -1;    }  memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);  len = addrinfo->ai_addrlen;  eXosip_freeaddrinfo (addrinfo);  /* remove preloaded route if there is no tag in the To header   */  {    osip_route_t *route = NULL;    osip_generic_param_t *tag = NULL;    osip_message_get_route (sip, 0, &route);    osip_to_get_tag (sip->to, &tag);    if (tag == NULL && route != NULL && route->url != NULL)      {        osip_list_remove (&sip->routes, 0);      }    i = osip_message_to_str (sip, &message, &length);    if (tag == NULL && route != NULL && route->url != NULL)      {        osip_list_add (&sip->routes, route, 0);      }  }  if (i != 0 || length <= 0)    {      return -1;    }  switch (((struct sockaddr *) &addr)->sa_family)    {      case AF_INET:        inet_ntop (((struct sockaddr *) &addr)->sa_family,                   &(((struct sockaddr_in *) &addr)->sin_addr), ipbuf,                   sizeof (ipbuf));        break;      case AF_INET6:        inet_ntop (((struct sockaddr *) &addr)->sa_family,                   &(((struct sockaddr_in6 *) &addr)->sin6_addr), ipbuf,                   sizeof (ipbuf));        break;      default:        strncpy (ipbuf, "(unknown)", sizeof (ipbuf));        break;    }  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,                          "Message sent: (to dest=%s:%i)\n%s\n",                          ipbuf, port, message));  if (tr != NULL)    {      if (tr->ict_context != NULL)        osip_ict_set_destination (tr->ict_context, osip_strdup (ipbuf), port);      if (tr->nict_context != NULL)        osip_nict_set_destination (tr->nict_context, osip_strdup (ipbuf), port);    }  if (0 >      sendto (udp_socket, (const void *) message, length, 0,              (struct sockaddr *) &addr, len))    {#ifdef WIN32      if (WSAECONNREFUSED == WSAGetLastError ())#else      if (ECONNREFUSED == errno)#endif        {          /* This can be considered as an error, but for the moment,             I prefer that the application continue to try sending             message again and again... so we are not in a error case.             Nevertheless, this error should be announced!             ALSO, UAS may not have any other options than retry always             on the same port.           */          osip_free (message);          return 1;      } else        {#ifndef MINISIZE          /* delete first SRV entry that is not reachable */          if (tr != NULL && tr->record.name[0] != '\0'              && tr->record.srventry[0].srv[0] != '\0')            {              memmove (&tr->record.srventry[0], &tr->record.srventry[1],                       9 * sizeof (osip_srv_entry_t));              memset (&tr->record.srventry[9], 0, sizeof (osip_srv_entry_t));              osip_free (message);              return OSIP_SUCCESS;      /* retry for next retransmission! */            }#endif          /* SIP_NETWORK_ERROR; */          osip_free (message);          return -1;        }    }  if (eXosip.keep_alive > 0)    {      if (MSG_IS_REGISTER (sip))        {          eXosip_reg_t *reg = NULL;          if (_eXosip_reg_find (&reg, tr) == 0)            {              memcpy (&(reg->addr), &addr, len);              reg->len = len;            }        }    }  osip_free (message);  return OSIP_SUCCESS;}static intudp_tl_keepalive (void){  char buf[4] = "jaK";  eXosip_reg_t *jr;  for (jr = eXosip.j_reg; jr != NULL; jr = jr->next)    {      if (jr->len > 0)        {          if (sendto (udp_socket, (const void *) buf, 4, 0,                      (struct sockaddr *) &(jr->addr), jr->len) > 0)            {              OSIP_TRACE (osip_trace                          (__FILE__, __LINE__, OSIP_INFO1, NULL,                           "eXosip: Keep Alive sent on UDP!\n"));            }        }    }  return OSIP_SUCCESS;}static intudp_tl_set_socket (int socket){  udp_socket = socket;  return OSIP_SUCCESS;}static intudp_tl_masquerade_contact (const char *public_address, int port){  if (public_address == NULL || public_address[0] == '\0')    {      memset (udp_firewall_ip, '\0', sizeof (udp_firewall_ip));      return OSIP_SUCCESS;    }  snprintf (udp_firewall_ip, sizeof (udp_firewall_ip), "%s", public_address);  if (port > 0)    {      snprintf (udp_firewall_port, sizeof (udp_firewall_port), "%i", port);    }  return OSIP_SUCCESS;}static intudp_tl_get_masquerade_contact (char *ip, int ip_size, char *port, int port_size){  memset (ip, 0, ip_size);  memset (port, 0, port_size);  if (udp_firewall_ip != '\0')    snprintf (ip, ip_size, "%s", udp_firewall_ip);  if (udp_firewall_port != '\0')    snprintf (port, port_size, "%s", udp_firewall_port);  return OSIP_SUCCESS;}struct eXtl_protocol eXtl_udp = {  1,  5060,  "UDP",  "0.0.0.0",  IPPROTO_UDP,  AF_INET,  0,  0,  &udp_tl_init,  &udp_tl_free,  &udp_tl_open,  &udp_tl_set_fdset,  &udp_tl_read_message,  &udp_tl_send_message,  &udp_tl_keepalive,  &udp_tl_set_socket,  &udp_tl_masquerade_contact,  &udp_tl_get_masquerade_contact};

⌨️ 快捷键说明

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