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

📄 ppldnsv6.c

📁 用于linux环境下的SIP服务器
💻 C
📖 第 1 页 / 共 3 页
字号:
 * @param domain Domain to search */PPL_DECLARE (ppl_status_t) ppl_dns_add_domain_query (char *domain){  if (domain == NULL)    return -1;  osip_fifo_add (dns_entries, domain);  return 0;}PPL_DECLARE (ppl_status_t)ppl_dns_get_result (ppl_dns_entry_t ** dns, char *domain){  ppl_dns_entry_t *res;  ppl_dns_entry_t *resnext;  ppl_time_t now;  now = ppl_time ();  *dns = NULL;  ppl_dns_lock_result_access ();  res = dns_results;  resnext = res;  { /* free some unusfull memory */    ppl_dns_error_t *error;    ppl_dns_error_t *enext;    int now;    now = time(NULL);    for (error = dns_errors;	 error != NULL;	 error = enext)      {	enext = error->next;	if ( now-error->expires > 120 )	  {	    OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL,				    "release old bad resolution info for '%s'\n",				    error->domain));	    REMOVE_ELEMENT (dns_errors, error);	    osip_free(error->domain);	    osip_free(error);	  }      }  }    for (; res != NULL && 0 != strcmp (res->name, domain); res = resnext)    {      resnext = res->next;      if (res->dns_ips != NULL)	{	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_INFO4, NULL,		       "time to live: %li, date: %i\n",		       res->dns_ips->ttl, res->date));	  if (now - res->date > res->dns_ips->ttl)	/* expired entry! */	    {	      OSIP_TRACE (osip_trace			  (__FILE__, __LINE__, OSIP_INFO4, NULL,			   "ENTRY REMOVED1\n"));	      ppl_dns_remove_entry (res);	    }	}    }  if (res == NULL)    {      ppl_dns_unlock_result_access ();      return -1;    }  if (res->dns_ips != NULL)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_INFO4, NULL,		   "time to live: %li, date: %i\n",		   res->dns_ips->ttl, res->date));      if (now - res->date > res->dns_ips->ttl)	/* expired entry! */	{	  OSIP_TRACE (osip_trace		      (__FILE__, __LINE__, OSIP_INFO4, NULL,		       "ENTRY REMOVED2\n"));	  ppl_dns_remove_entry (res);	  res = NULL;	  ppl_dns_unlock_result_access ();	  return -1;	}    }  /*  REMOVE_ELEMENT(dns_results, res); We could keep it for a while? */  ppl_dns_unlock_result_access ();  *dns = res;  return 0;}PPL_DECLARE (ppl_status_t)ppl_dns_query (ppl_dns_entry_t ** dest, char *domain, char *protocol){  ppl_dns_entry_t *dns;  ppl_dns_ip_t *next;  ppl_dns_ip_t *ip;  querybuf answer;		/* answer buffer from nameserver */  int n;  char *zone;  *dest = NULL;  if (!domain || !*domain || !protocol || !*protocol)    return -1;  zone = (char *) malloc (strlen (domain) + 5 + strlen (protocol) + 20);  if (zone == NULL)    return -1;  *zone = '\0';  strcat (zone, "_sip");  strcat (zone, ".");  strcat (zone, "_");  strcat (zone, protocol);  strcat (zone, ".");  strcat (zone, domain);  OSIP_TRACE (osip_trace	      (__FILE__, __LINE__, OSIP_INFO2, NULL,	       "About to ask for '%s IN SRV'\n", zone));  n =    res_query (zone, C_IN, T_SRV, (unsigned char *) &answer, sizeof (answer));  if (n < (int) sizeof (HEADER))    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_INFO2, NULL,		   "Did not get a valid response for query '%s IN SRV'\n",		   zone));      (void) free (zone);      return -1;    }  OSIP_TRACE (osip_trace	      (__FILE__, __LINE__, OSIP_INFO2, NULL,	       "Got valid response for query '%s IN SRV'\n", zone));  (void) free (zone);  dns = (ppl_dns_entry_t *) osip_malloc (sizeof (ppl_dns_entry_t));  dns->name = domain;  dns->protocol = osip_strdup(protocol);  dns->date = ppl_time ();  dns->dns_ips = NULL;  dns->ref = 0;  dns->next = NULL;  dns->parent = NULL;  n = ppl_dns_resolv (&(dns->dns_ips), &answer, n);  if (n != 0)    {      dns->name = NULL; /* fix bug: keep the name allocated after a failure. */      ppl_dns_entry_free (dns);      return -1;    }  for (ip = dns->dns_ips; ip != NULL; ip = ip->next)    {      n = ppl_dns_get_addrinfo (&(ip->addrinfo), ip->name, ip->port);      if (n != PPL_SUCCESS)	{	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL,				  "Hostname '%s' does not resolve",				  ip->name));	  if (ip->addrinfo!=NULL)	    {	      freeaddrinfo(ip->addrinfo);	    }	  osip_free (ip->name);	  ip->name = NULL;	/* mark for deletion */	}    }  /* delete ppl_dns_ip_t elements marked for deletion */  for (ip = dns->dns_ips; ip != NULL; ip = next)    {      if (ip->name == NULL)	{	  next = ip->next;	  REMOVE_ELEMENT (dns->dns_ips, ip);	  osip_free (ip);	}      else	{	  next = ip->next;	  OSIP_TRACE (osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL,				  "Hostname '%s' resolved to '%s'\n",				  ip->name, ip->addrinfo->ai_canonname));	}    }  *dest = dns;  return 0;}#define BUFLEN 512PPL_DECLARE (char *)ppl_inet_ntop (struct sockaddr *sockaddr){  char buf[BUFLEN];  char *ptr = NULL;  switch (sockaddr->sa_family) {  case AF_INET:    ptr = (char*)inet_ntop(sockaddr->sa_family,			   &((struct sockaddr_in *)sockaddr)->sin_addr,			   buf, BUFLEN-1);    break;  case AF_INET6:    ptr = (char*)inet_ntop(sockaddr->sa_family,			   &((struct sockaddr_in6 *)sockaddr)->sin6_addr,			   buf, BUFLEN-1);    break;  default:    return NULL;  }  if (ptr==NULL)    return NULL;  return osip_strdup(buf);}PPL_DECLARE (int)ppl_inet_pton (const char *src, void *dst){  if (strchr (src, ':')) /* possible IPv6 address */	return (inet_pton(AF_INET6, src, dst));  else if (strchr (src, '.')) /* possible IPv4 address */	return (inet_pton(AF_INET, src, dst));  else /* Impossibly a valid ip address */	return INADDR_NONE;}PPL_DECLARE (ppl_status_t)ppl_dns_get_addrinfo (struct addrinfo **addrinfo, char *hostname, int service){  struct in_addr addr;  struct in6_addr addrv6;  struct addrinfo hints;  int error;  char portbuf[10];  if (service!=0)    snprintf(portbuf, sizeof(portbuf), "%d", service);  memset (&hints, 0, sizeof (hints));#if 0  if (inet_pton(AF_INET, hostname, &addr)>0)    {      /* ipv4 address detected */      struct addrinfo *_addrinfo;      _addrinfo = (struct addrinfo *)osip_malloc(sizeof(struct addrinfo)						 + sizeof (struct sockaddr_in)						 + 0); /* no cannonname */      _addrinfo->ai_flags = AI_NUMERICHOST;      _addrinfo->ai_family = AF_INET;      _addrinfo->ai_socktype = SOCK_DGRAM;      _addrinfo->ai_protocol = IPPROTO_UDP;      _addrinfo->ai_addrlen = sizeof(struct sockaddr_in);      _addrinfo->ai_addr = (void *) (_addrinfo) + sizeof (struct addrinfo);            memset(_addrinfo->ai_addr, 0, sizeof(struct sockaddr_in));      ((struct sockaddr_in*)_addrinfo->ai_addr)->sin_family = AF_INET;      ((struct sockaddr_in*)_addrinfo->ai_addr)->sin_addr.s_addr = inet_addr(hostname);      if (service==0)	((struct sockaddr_in*)_addrinfo->ai_addr)->sin_port   = htons (5060);      else	((struct sockaddr_in*)_addrinfo->ai_addr)->sin_port   = htons (service);      _addrinfo->ai_canonname = NULL;      _addrinfo->ai_next = NULL;            OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_INFO2, NULL,		   "No DNS resolution needed for %s:%i\n", hostname, service));      *addrinfo = _addrinfo;      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_INFO2, NULL,		   "IPv4 address detected: %s\n", hostname));      return 0;    }  else if (inet_pton(AF_INET6, hostname, &addrv6)>0)    {      hints.ai_flags = AI_CANONNAME;      hints.ai_family = PF_INET6; /* ipv6 support */    }  else#endif    {      hints.ai_flags = AI_CANONNAME;      hints.ai_family = PF_UNSPEC; /* ipv4 & ipv6 support */#if 0  hints.ai_family = PF_UNSPEC; /* ipv4 & ipv6 support */#endif    }  hints.ai_socktype = SOCK_DGRAM;  hints.ai_protocol = IPPROTO_UDP;  if (service==0)    {      error = getaddrinfo (hostname, "sip", &hints, addrinfo);      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_INFO2, NULL,		   "SRV resolution with udp-sip-%s\n", hostname));    }  else    {      error = getaddrinfo (hostname, portbuf, &hints, addrinfo);      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_INFO2, NULL,		   "DNS resolution with %s:%i\n", hostname, service));    }  if (error || *addrinfo == NULL)    {       OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_INFO2, NULL,		   "getaddrinfo failure. %s:%i\n", hostname, service));     return -1;    }  /*    fprintf (stdout, "canonnical name is: %s\n", (*addrinfo)->ai_canonname);    fprintf (stdout, "ai_addrlen is: %i\n", (*addrinfo)->ai_addrlen);  */  /* memcpy (sin, res0->ai_addr, res0->ai_addrlen); */  /* freeaddrinfo (res0); */  return PPL_SUCCESS;}PPL_DECLARE (int)ppl_dns_query_host (ppl_dns_entry_t ** dest, char *hostname, int port){  struct addrinfo *addr;  ppl_dns_ip_t *dns_ip;  ppl_dns_entry_t *dns;  int my_error;  char portbuf[10];  *dest = NULL;  snprintf(portbuf, sizeof(portbuf), "%d", port);  my_error = ppl_dns_get_addrinfo (&addr, hostname, port);  if (my_error)    return my_error;  dns_ip = (ppl_dns_ip_t *) osip_malloc (sizeof (ppl_dns_ip_t));  dns_ip->srv_ns_flag = PSP_NS_LOOKUP;  dns_ip->ttl = 60;  dns_ip->pref = 10;  dns_ip->weight = 0;  dns_ip->rweight = 0;  dns_ip->port = port;  dns_ip->next = NULL;  dns_ip->parent = NULL;  /*  dns_ip->sin.sin_family = addr.sin_family; */  /*  dns_ip->sin.sin_addr = addr.sin_addr; */  /*  dns_ip->sin.sin_port = htons (port); */  dns_ip->addrinfo = addr;  /* dns_ip->name = osip_strdup(addr->ai_canonname); */  dns_ip->name = ppl_inet_ntop ((struct sockaddr *)(addr->ai_addr));  if (dns_ip->name==NULL)    {      OSIP_TRACE (osip_trace		  (__FILE__, __LINE__, OSIP_INFO2, NULL,		   "getaddrinfo failure. could not get printable version\n"));	  return -1;    }      dns = (ppl_dns_entry_t *) osip_malloc (sizeof (ppl_dns_entry_t));  if (dns == NULL)    {      /* MLEAK! I have to free first_ip and following dns_ip!! */      if (dns_ip->addrinfo!=NULL)	{	  freeaddrinfo(dns_ip->addrinfo);	}      osip_free (dns_ip->name);      osip_free (dns_ip);      return -1;    }  dns->name = hostname;  dns->protocol = NULL;  dns->date = ppl_time ();  dns->dns_ips = dns_ip;  dns->ref = 0;  dns->next = NULL;  dns->parent = NULL;  *dest = dns;  return 0;}#include <sys/ioctl.h>#include <net/if.h>static int ppl_dns_default_gateway_ipv4 (char *address, int size);static int ppl_dns_default_gateway_ipv6 (char *address, int size);intppl_dns_default_gateway (int familiy, char *address, int size){  if (familiy==AF_INET6)    {      return ppl_dns_default_gateway_ipv6 (address, size);    }  else    {      return ppl_dns_default_gateway_ipv4 (address, size);    }}/* This is a portable way to find the default gateway. * The ip of the default interface is returned. */static intppl_dns_default_gateway_ipv4 (char *address, int size){  unsigned int len;  int sock_rt, on=1;  struct sockaddr_in iface_out;  struct sockaddr_in remote;    memset(&remote, 0, sizeof(struct sockaddr_in));  remote.sin_family = AF_INET;  remote.sin_addr.s_addr = inet_addr("217.12.3.11");  remote.sin_port = htons(11111);    memset(&iface_out, 0, sizeof(iface_out));  sock_rt = socket(AF_INET, SOCK_DGRAM, 0 );    if (setsockopt(sock_rt, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on))      == -1) {    perror("DEBUG: [get_output_if] setsockopt(SOL_SOCKET, SO_BROADCAST");    close(sock_rt);    return -1;  }    if (connect(sock_rt, (struct sockaddr*)&remote, sizeof(struct sockaddr_in))      == -1 ) {    perror("DEBUG: [get_output_if] connect");    close(sock_rt);    return -1;  }    len = sizeof(iface_out);  if (getsockname(sock_rt, (struct sockaddr *)&iface_out, &len) == -1 ) {    perror("DEBUG: [get_output_if] getsockname");    close(sock_rt);    return -1;  }  close(sock_rt);  if (iface_out.sin_addr.s_addr == 0)    { /* what is this case?? */      return -1;    }  osip_strncpy(address, inet_ntoa(iface_out.sin_addr), size-1);  return 0;}/* This is a portable way to find the default gateway. * The ip of the default interface is returned. */static intppl_dns_default_gateway_ipv6 (char *address, int size){  unsigned int len;  int sock_rt, on=1;  struct sockaddr_in6 iface_out;  struct sockaddr_in6 remote;    memset(&remote, 0, sizeof(struct sockaddr_in));  remote.sin6_family = AF_INET6;  inet_pton(AF_INET6, "2001:638:500:101:2e0:81ff:fe24:37c6",	    &remote.sin6_addr);  remote.sin6_port = htons(11111);    memset(&iface_out, 0, sizeof(iface_out));  sock_rt = socket(AF_INET6, SOCK_DGRAM, 0 );  

⌨️ 快捷键说明

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