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

📄 extl_udp.c

📁 libeXosip2-3.0.3.tar.gz
💻 C
📖 第 1 页 / 共 2 页
字号:
/*  eXosip - This is the eXtended osip library.  Copyright (C) 2002,2003,2004,2005,2006,2007  Aymeric MOIZARD  - jack@atosc.org    eXosip is free software; you can redistribute it and/or modify  it under the terms of the GNU General Public License as published by  the Free Software Foundation; either version 2 of the License, or  (at your option) any later version.    eXosip is distributed in the hope that it will be useful,  but WITHOUT ANY WARRANTY; without even the implied warranty of  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the  GNU General Public License for more details.    You should have received a copy of the GNU General Public License  along with this program; if not, write to the Free Software  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA*/#ifdef ENABLE_MPATROL#include <mpatrol.h>#endif#include "eXosip2.h"#include "eXtransport.h"#ifdef _WIN32_WCE#include "inet_ntop.h"#elif WIN32#include "inet_ntop.h"#endifextern eXosip_t eXosip;#if defined(_WIN32_WCE)#define strerror(X) "-1"#endifstatic int udp_socket;static struct sockaddr_storage ai_addr;static char udp_firewall_ip[64];static char udp_firewall_port[10];static intudp_tl_init(void){  udp_socket=0;  memset(&ai_addr, 0, sizeof(struct sockaddr_storage));  memset(udp_firewall_ip, 0, sizeof(udp_firewall_ip));  memset(udp_firewall_port, 0, sizeof(udp_firewall_port));  return 0;}static intudp_tl_free(void){  memset(udp_firewall_ip, 0, sizeof(udp_firewall_ip));  memset(udp_firewall_port, 0, sizeof(udp_firewall_port));  memset(&ai_addr, 0, sizeof(struct sockaddr_storage));  if (udp_socket>0)    close(udp_socket);  return 0;}static intudp_tl_open(void){  int res;  struct addrinfo *addrinfo = NULL;  struct addrinfo *curinfo;  int sock = -1;  if (eXtl_udp.proto_port < 0)    eXtl_udp.proto_port = 5060;  res = eXosip_get_addrinfo (&addrinfo,			     eXtl_udp.proto_ifs,			     eXtl_udp.proto_port,			     eXtl_udp.proto_num);  if (res)    return -1;  for (curinfo = addrinfo; curinfo; curinfo = curinfo->ai_next)    {      socklen_t len;      if (curinfo->ai_protocol && curinfo->ai_protocol != eXtl_udp.proto_num)        {          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_INFO3, NULL,                       "eXosip: Skipping protocol %d\n", curinfo->ai_protocol));          continue;        }      sock = (int) socket (curinfo->ai_family, curinfo->ai_socktype,                           curinfo->ai_protocol);      if (sock < 0)        {          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_ERROR, NULL,                       "eXosip: Cannot create socket %s!\n", strerror (errno)));          continue;        }      if (curinfo->ai_family == AF_INET6)        {#ifdef IPV6_V6ONLY          if (setsockopt_ipv6only (sock))            {              close (sock);              sock = -1;              OSIP_TRACE (osip_trace                          (__FILE__, __LINE__, OSIP_ERROR, NULL,                           "eXosip: Cannot set socket option %s!\n",                           strerror (errno)));              continue;            }#endif /* IPV6_V6ONLY */        }      res = bind (sock, curinfo->ai_addr, curinfo->ai_addrlen);      if (res < 0)        {          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_ERROR, NULL,                       "eXosip: Cannot bind socket node:%s family:%d %s\n",                       eXtl_udp.proto_ifs, curinfo->ai_family, strerror (errno)));          close (sock);          sock = -1;          continue;        }      len = sizeof (ai_addr);      res = getsockname (sock, (struct sockaddr *) &ai_addr, &len);      if (res != 0)        {          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_ERROR, NULL,                       "eXosip: Cannot get socket name (%s)\n", strerror (errno)));          memcpy (&ai_addr, curinfo->ai_addr, curinfo->ai_addrlen);        }      if (eXtl_udp.proto_num != IPPROTO_UDP)        {          res = listen (sock, SOMAXCONN);          if (res < 0)            {              OSIP_TRACE (osip_trace                          (__FILE__, __LINE__, OSIP_ERROR, NULL,                           "eXosip: Cannot bind socket node:%s family:%d %s\n",                           eXtl_udp.proto_ifs, curinfo->ai_family, strerror (errno)));              close (sock);              sock = -1;              continue;            }        }      break;    }  eXosip_freeaddrinfo (addrinfo);  if (sock < 0)    {      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_ERROR, NULL,                   "eXosip: Cannot bind on port: %i\n", eXtl_udp.proto_port));      return -1;    }  udp_socket = sock;  if (eXtl_udp.proto_port == 0)    {      /* get port number from socket */      if (eXtl_udp.proto_family == AF_INET)        eXtl_udp.proto_port = ntohs (((struct sockaddr_in *) &ai_addr)->sin_port);      else        eXtl_udp.proto_port = ntohs (((struct sockaddr_in6 *) &ai_addr)->sin6_port);      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_INFO1, NULL,                   "eXosip: Binding on port %i!\n", eXtl_udp.proto_port));    }  snprintf(udp_firewall_port, sizeof(udp_firewall_port), "%i", eXtl_udp.proto_port);  return 0;}static intudp_tl_set_fdset(fd_set *osip_fdset, int *fd_max){  if (udp_socket<=0)    return -1;  eXFD_SET (udp_socket, osip_fdset);  if (udp_socket > *fd_max)    *fd_max = udp_socket;  return 0;}voidudp_tl_learn_port_from_via(osip_message_t * sip){    /* EXOSIP_OPT_UDP_LEARN_PORT option set */     if (eXosip.learn_port > 0)    {        osip_via_t *via = NULL;        osip_generic_param_t *br;        osip_message_get_via (sip, 0, &via);        if (via != NULL && via->protocol != NULL            && (osip_strcasecmp (via->protocol, "udp") == 0		|| osip_strcasecmp (via->protocol, "dtls-udp") == 0))        {            osip_via_param_get_byname (via, "rport", &br);            if (br != NULL && br->gvalue != NULL)            {                snprintf (udp_firewall_port, 20, "%s", br->gvalue);                OSIP_TRACE (osip_trace                            (__FILE__, __LINE__, OSIP_INFO1, NULL,                            "SIP port modified from rport in SIP answer\r\n"));            }        }    }    return;}static intudp_tl_read_message(fd_set *osip_fdset){  char *buf;  int i;  if (udp_socket<=0)    return -1;    if (FD_ISSET (udp_socket, osip_fdset))    {      struct sockaddr_storage sa;      #ifdef __linux      socklen_t slen;#else      int slen;#endif      if (eXtl_udp.proto_family == AF_INET)	slen = sizeof (struct sockaddr_in);      else	slen = sizeof (struct sockaddr_in6);            buf = (char *) osip_malloc (SIP_MESSAGE_MAX_LENGTH * sizeof (char) + 1);      if (buf==NULL)	return -1;      i = recvfrom (udp_socket, buf,		    SIP_MESSAGE_MAX_LENGTH, 0,		    (struct sockaddr *) &sa, &slen);            if (i > 5)	{	  char src6host[NI_MAXHOST];	  int recvport = 0;	  int err;	  	  osip_strncpy (buf + i, "\0", 1);	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,				  "Received message: \n%s\n", buf));	  memset (src6host, 0, sizeof (src6host));	  	  if (eXtl_udp.proto_family == AF_INET)	    recvport = ntohs (((struct sockaddr_in *) &sa)->sin_port);	  else	    recvport = ntohs (((struct sockaddr_in6 *) &sa)->sin6_port);		  #if defined(__arc__)	  {	    struct sockaddr_in *fromsa = (struct sockaddr_in *) &sa;	    char *tmp;	    tmp = inet_ntoa(fromsa->sin_addr);	    if (tmp==NULL)	      {		OSIP_TRACE (osip_trace			    (__FILE__, __LINE__, OSIP_ERROR, NULL,			     "Message received from: NULL:%i inet_ntoa failure\n",			     recvport));	      }	    else	      {		snprintf(src6host, sizeof(src6host), "%s", tmp);		OSIP_TRACE (osip_trace			    (__FILE__, __LINE__, OSIP_INFO1, NULL,			     "Message received from: %s:%i\n", src6host, recvport));	      }	  }#else	  err = getnameinfo ((struct sockaddr *) &sa, slen,			     src6host, NI_MAXHOST,			     NULL, 0, NI_NUMERICHOST);	  	  if (err != 0)	    {	      OSIP_TRACE (osip_trace			  (__FILE__, __LINE__, OSIP_ERROR, NULL,			   "Message received from: NULL:%i getnameinfo failure\n",			   recvport));	      snprintf(src6host, sizeof(src6host), "127.0.0.1");	    }	  else	    {	      OSIP_TRACE (osip_trace			  (__FILE__, __LINE__, OSIP_INFO1, NULL,			   "Message received from: %s:%i\n",			   src6host, recvport));	    }#endif	  	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_INFO1, NULL,		       "Message received from: %s:%i\n",		       src6host, recvport));

⌨️ 快捷键说明

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