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

📄 extl_udp.c

📁 exosip
💻 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);				    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);				    snprintf(co->url->port, 9, "%i", ainfo->nat_port);				}			}	    }	}  }  return 0;}#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 0; /* 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 0;}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 0;}static intudp_tl_set_socket(int socket){  udp_socket = socket;    return 0;}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 0;    }  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 0;}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 0;}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 + -