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

📄 udp.c

📁 用于linux环境下的SIP服务器
💻 C
📖 第 1 页 / 共 2 页
字号:
    FD_SET (ctx->out_socket, &memo_fdset);  if (ctx->mcast_socket>0      &&ctx->mcast_socket!=ctx->in_socket)    FD_SET (ctx->mcast_socket, &memo_fdset);  /* create a set of file descritor to control the stack */  for (; max != 0; max--)    {      osip_fdset = memo_fdset;      max_fd = ctx->in_socket;      if (max_fd < ctx->out_socket)	max_fd = ctx->out_socket;      if (max_fd < ctx->mcast_socket)	max_fd = ctx->mcast_socket;      i = select (max_fd + 1, &osip_fdset, NULL, NULL, NULL);      buf = (char *) osip_malloc (SIP_MESSAGE_MAX_LENGTH * sizeof (char) + 3);      if (ipv6_enable==1)	{	  slen = sizeof (sa6);	  sa = (struct sockaddr *)&sa6;	}      else	{	  slen = sizeof (sa4);	  sa = (struct sockaddr *)&sa4;	}      if (0 == i)	{	  osip_free (buf);	  return -1;		/* no message: timout expires */	}      else if (-1 == i)	{	  osip_free (buf);	  return -2;		/* error */	}      else if (FD_ISSET (ctx->in_socket, &osip_fdset))	{	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_INFO2, NULL,		       "UDP MESSAGE RECEIVED\n"));	  i = ppl_socket_recv (ctx->in_socket, buf, SIP_MESSAGE_MAX_LENGTH, 0,			       sa, &slen);	}      else if (ctx->out_socket!=ctx->in_socket	       &&FD_ISSET (ctx->out_socket, &osip_fdset))	{	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_INFO2, NULL,		       "UDP MESSAGE RECEIVED\n"));	  i = ppl_socket_recv (ctx->out_socket, buf, SIP_MESSAGE_MAX_LENGTH, 0,			       sa, &slen);	}      else if (ctx->mcast_socket>0	       &&FD_ISSET (ctx->mcast_socket, &osip_fdset))	{	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_INFO2, NULL,		       "UDP MULTICAST MESSAGE RECEIVED\n"));	  i =	    ppl_socket_recv (ctx->mcast_socket, buf, SIP_MESSAGE_MAX_LENGTH, 0,			     sa, &slen);	}      if (i > 0)	{	  char *ip_address = ppl_inet_ntop (sa);	  /* Message might not end with a "\0" but we know the number of */	  /* char received! */	  osip_strncpy (buf + i, "\0", 1);	  if (ip_address==NULL)	    {	      osip_free(buf);	      return -1; /* missing information from socket?? */	    }	  if (ipv6_enable==1)	    {	      OSIP_TRACE (osip_trace			  (__FILE__, __LINE__, OSIP_INFO2, NULL,			   "udp plugin: RCV UDP MESSAGE (from %s:%i)\n",			   ip_address, ntohs (sa6.sin6_port)));	    }	  else	    {	      OSIP_TRACE (osip_trace			  (__FILE__, __LINE__, OSIP_INFO2, NULL,			   "udp plugin: RCV UDP MESSAGE (from %s:%i)\n",			   /* inet_ntoa (sa.sin_addr), ntohs (sa.sin_port))); */			   ip_address, ntohs (sa4.sin_port)));	    }	  if (ctx->mcast_socket>0)	    {	      /* check maddr parameter to detect multicast data */	      /* do they need special processing? */	    }#ifndef HIDE_MESSAGE	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_INFO1, NULL, "\n%s\n", buf));#endif	  if (ipv6_enable==1)	    udp_process_message (buf, ip_address,				 ntohs (sa6.sin6_port), i);	  else	    udp_process_message (buf, ip_address,				 /* inet_ntoa (sa.sin_addr), */				 ntohs (sa4.sin_port), i);	  osip_free(ip_address);	}      else if (i == -1)	{	  if (errno == EAGAIN)	    {	      osip_free (buf);	      return 0;	    }	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_ERROR, NULL,		       "udp plugin: error while receiving data!\n"));	  osip_free (buf);	  return -1;	}    }  /* max is reached */  return 1;}static int__osip_message_fix_last_via_header (osip_message_t * request, char *ip_addr, int port){  osip_generic_param_t *rport;  osip_via_t *via;  /* get Top most Via header: */  if (request == NULL || request == NULL)    return -1;  if (MSG_IS_RESPONSE (request))    return 0;			/* Don't fix Via header */  via = osip_list_get (request->vias, 0);  if (via == NULL || via->host == NULL)    /* Hey, we could build it? */    return -1;  osip_via_param_get_byname (via, "rport", &rport);  /* detect rport */  if (rport != NULL)    {      if (rport->gvalue == NULL)	{	  rport->gvalue = (char *) osip_malloc (9);#ifdef WIN32	  _snprintf (rport->gvalue, 8, "%i", port);#else	  snprintf (rport->gvalue, 8, "%i", port);#endif	}			/* else bug? */    }  /* only add the received parameter if the 'sent-by' value does not contains     this ip address */  if (0 == osip_strcasecmp (via->host, ip_addr))	/* don't need the received parameter */    return 0;  else    osip_via_set_received (via, osip_strdup (ip_addr));  return 0;}intudp_process_message (char *buf, char *ip_addr, int port, int length){  osip_event_t *evt;  if (buf == NULL      || *buf == '\0'      || buf[1] == '\0'      || buf[2] == '\0' || buf[3] == '\0' || buf[4] == '\0' || buf[5] == '\0')    {      osip_free (buf);      return -1;    }  evt = osip_parse (buf, length);  osip_free (buf);  if (evt == NULL)    /* discard... */    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "udp module: Could not parse response!\n"));      return -1;    }  if (evt->sip == NULL)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "udp module: Could not parse response!\n"));      osip_event_free (evt);      return -1;    }  udp_log_event (evt);  /* modify the request to add a "received" parameter in the last Via. */  /* for libosip>0.9.2 use osip_message_fix_last_via_header from osip */  __osip_message_fix_last_via_header (evt->sip, ip_addr, port);  if (evt->sip == NULL)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_ERROR, NULL,		   "udp module: Probably a bad via header!\n"));      osip_event_free (evt);      return -1;    }  /* modify the request so it's compliant with the latest draft */  psp_core_fix_strict_router_issue (evt);  psp_core_event_add_sip_message (evt);  return 0;}intudp_log_event (osip_event_t * evt){#ifdef SHOW_LIMITED_MESSAGE  osip_via_t *via;  osip_generic_param_t *b;  via = osip_list_get (evt->sip->vias, 0);  osip_via_param_get_byname (via, "branch", &b);  if (b == NULL)    {      if (MSG_IS_REQUEST (evt->sip))	{	}      else	{	}      return -1;    }  if (MSG_IS_REQUEST (evt->sip))    {    }  else    {    }#endif  return 0;}static int udp_plugin_get_new_socket(struct sockaddr_storage *addr){  struct sockaddr_in6 raddr6;  struct sockaddr_in raddr;  int option;  int i;  int socket;  OSIP_TRACE (osip_trace	      (__FILE__, __LINE__, OSIP_WARNING, NULL,	       "udp plugin: Building a new connect socket %i!\n",	       ctx->in_port));		  if (ipv6_enable==1)    socket = ppl_socket (PF_INET6, SOCK_DGRAM, IPPROTO_UDP);  else    socket = ppl_socket (PF_INET, SOCK_DGRAM, IPPROTO_UDP);  if (socket == -1)    {      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,			      "udp plugin: cannot create descriptor for port %i!\n"));      return -1;    }  option = 1;  i = setsockopt (socket, SOL_SOCKET, SO_REUSEADDR,		  OPTVALCAST &option, sizeof option);  if (i!=0)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_WARNING, NULL,		   "upd plugin; UDP listener SO_REUSE_ADDR failed %i (%i)!\n",		   ctx->in_port, i));    }  if (ipv6_enable==1)    {      memcpy ((void *)&(raddr6.sin6_addr.s6_addr), (const void *)&in6addr_any, 16);      raddr6.sin6_port = htons (0);      raddr6.sin6_family = AF_INET6;      i = ppl_socket_bind (socket,			   (struct sockaddr *) &raddr6, sizeof (raddr6));    }  else    {      raddr.sin_addr.s_addr = htons (INADDR_ANY);      raddr.sin_port = htons (0);      raddr.sin_family = AF_INET;      i = ppl_socket_bind (socket,			   (struct sockaddr *) &raddr, sizeof (raddr));    }  if (i < 0)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_WARNING, NULL,		   "udp plugin: cannot bind on port %i!\n",		   ctx->in_port));      ppl_socket_close(socket);      return -1;    }  i = connect(socket,(struct sockaddr *) addr,sizeof(struct sockaddr));  if (i < 0)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_WARNING, NULL,		   "udp plugin: cannot connect socket %i!\n",		   ctx->in_port));      ppl_socket_close(socket);      return -1;    }  return socket;}/* return   -1 on error   0  on success*/intcb_snd_udp_message (osip_transaction_t * transaction,	/* read only element */		    osip_message_t * message,	/* message to send           */		    char *host,	/* proposed destination host */		    int port,	/* proposed destination port */		    int socket)	/* proposed socket (if any)  */{  size_t length;  int i;  char *buf;  int sock;  struct addrinfo *addrinfo;  struct sockaddr_storage addr;  if (ctx == NULL)    return -1;  i = osip_message_to_str (message, &buf, &length);  if (i != 0)    return -1;#ifndef HIDE_MESSAGE  OSIP_TRACE (osip_trace	      (__FILE__, __LINE__, OSIP_INFO1, NULL, "\n%s\n", buf));#endif  /* For RESPONSE, oSIP ALWAYS provide host and port from the top via */  /* For REQUEST,  oSIP SOMETIMES provide host and port to use which     may be different from the request uri */  if (host == NULL)    {				/* when host is NULL, we use the request uri value */      host = message->req_uri->host;      if (message->req_uri->port != NULL)	port = osip_atoi (message->req_uri->port);      else	port = 5060;    }  i = ppl_dns_get_addrinfo(&addrinfo, host, port);  if (i!=PPL_SUCCESS)    {      osip_free (buf);      return -1;    }#if 0  memcpy (&addr, addrinfo->ai_addr, addrinfo->ai_addrlen);  freeaddrinfo (addrinfo);#endif  /* #define SUPPORT_ICMP */#ifdef SUPPORT_ICMP  sock = 0; /* use the default */  if (transaction!=NULL)  {    if (MSG_IS_ACK(message))      {	if (transaction->out_socket!=0 && transaction->out_socket!=-1)	  {	    ppl_socket_close(transaction->out_socket);	    transaction->out_socket = 0;	  }      }    if (MSG_IS_REQUEST(message))      {	if (transaction->out_socket==0 || transaction->out_socket==-1)	  transaction->out_socket = udp_plugin_get_new_socket(&addr);	if (transaction->out_socket==0 || transaction->out_socket==-1) /* use default for ACK */	  transaction->out_socket = 0;      }  }  /* connect(sock,(struct sockaddr *) &addr,sizeof(addr)); */#endif#ifdef SUPPORT_ICMP  if (MSG_IS_RESPONSE(message)      || MSG_IS_ACK(message)      || transaction->out_socket==0)    i = sendto (ctx->out_socket, (const void *) buf, length, 0,		(struct sockaddr *) &addr, sizeof (addr));  else    i = send (transaction->out_socket, (const void *) buf, length, 0);  #else  sock = ctx->out_socket;  i = sendto (sock, (const void *) buf, length, 0,	      addrinfo->ai_addr, addrinfo->ai_addrlen);  /*(struct sockaddr *) &addr, sizeof (addr)); */  freeaddrinfo (addrinfo);#endif  if (0 > i)    {      osip_free (buf);#ifdef WIN32      i = WSAGetLastError ();      if (WSAECONNREFUSED == i)	{	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,				  "SIP_ECONNREFUSED - No remote server.\n"));	  return 1;		/* I prefer to answer 1 by now..				   we'll see later what's better */	}#else      i = errno;      if (ECONNREFUSED == i)	{	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,				  "SIP_ECONNREFUSED - No remote server.\n"));	  return 1;		/* I prefer to answer 1 by now..				   we'll see later what's better */	}#endif#ifdef WIN32      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,			      "SIP_NETWORK_ERROR - Network error %i sending message to %s on port %i.\n",			      i, host, port));#else      /* XXX use some configure magic to detect if we have the right strerror_r()       * function (the one that returns int, not char *) and then use strerror_r()       * instead.       */      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,			      "SIP_NETWORK_ERROR - Network error %i (%s) sending message to %s on port %i.\n",			      i, strerror (i), host, port));#endif      /* SIP_NETWORK_ERROR; */      return -1;    }#ifdef WIN32  i = WSAGetLastError ();  if (WSAECONNREFUSED == i)    {      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,			      "SIP_ECONNREFUSED - No remote server.\n"));      return 1;    }  if (WSAECONNRESET == i)    {      OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,			      "SIP_ECONNREFUSED - No remote server.\n"));      return 1;    }  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_ERROR, NULL,			  "WSAGetLastError returned : %i.\n", i));#endif  OSIP_TRACE (osip_trace	      (__FILE__, __LINE__, OSIP_INFO1, NULL,	       "udp_plugin: message sent to %s on port %i\n", host, port));  osip_free (buf);  return 0;}

⌨️ 快捷键说明

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