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

📄 extl_udp.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 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 OSIP_SUCCESS;}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 OSIP_SUCCESS;}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 OSIP_SUCCESS;}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 OSIP_SUCCESS;}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)            {              struct eXosip_account_info ainfo;              memset (&ainfo, 0, sizeof (struct eXosip_account_info));              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"));              osip_via_param_get_byname (via, "received", &br);              if (br != NULL && br->gvalue != NULL                  && sip->from != NULL && sip->from->url != NULL                  && sip->from->url->host != NULL)                {                  snprintf (ainfo.proxy, sizeof (ainfo.proxy), "%s",                            sip->from->url->host);                  ainfo.nat_port = atoi (udp_firewall_port);                  snprintf (ainfo.nat_ip, sizeof (ainfo.nat_ip), "%s", br->gvalue);                  eXosip_set_option (EXOSIP_OPT_ADD_ACCOUNT_INFO, &ainfo);                }            }        }    }  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 OSIP_NOMEM;      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));          _eXosip_handle_incoming_message (buf, i, udp_socket, src6host, recvport);        }#ifndef MINISIZE      else if (i < 0)        {          OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,                                  "Could not read socket\n"));      } else        {          OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO1, NULL,                                  "Dummy SIP message received\n"));        }#endif      osip_free (buf);    }  return OSIP_SUCCESS;}

⌨️ 快捷键说明

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