exutils.c

来自「libosip2-3版本的osip源代码」· C语言 代码 · 共 1,103 行 · 第 1/2 页

C
1,103
字号
  if (size > 256)    size = 256;#endif  if (eXosip.forced_localip)    {      if (size > sizeof (eXosip.net_interfaces[0].net_firewall_ip))        size = sizeof (eXosip.net_interfaces[0].net_firewall_ip);      strncpy (loc, eXosip.net_interfaces[0].net_firewall_ip, size);      return 0;    }  strcpy (loc, "127.0.0.1");    /* always fallback to local loopback */  memset (&hints, 0, sizeof (hints));  if(ipv6_enable)    hints.ai_family = PF_INET6;  else    hints.ai_family = PF_INET;    /* ipv4 only support */  hints.ai_socktype = SOCK_DGRAM;  /*hints.ai_flags=AI_NUMERICHOST|AI_CANONNAME; */  err = getaddrinfo (address_to_reach, "5060", &hints, &res);  if (err != 0)    {      eXosip_trace (OSIP_ERROR,                    ("Error in getaddrinfo for %s: %s\n", address_to_reach,                     gai_strerror (err)));      return -1;    }  if (res == NULL)    {      eXosip_trace (OSIP_ERROR, ("getaddrinfo reported nothing !"));      return -1;    }  sock = socket (res->ai_family, SOCK_DGRAM, 0);  tmp = 1;  err =    setsockopt (sock, SOL_SOCKET, SO_REUSEADDR, (const char *) &tmp, sizeof (int));  if (err < 0)    {      eXosip_trace (OSIP_ERROR, ("Error in setsockopt: %s\n", strerror (errno)));      freeaddrinfo (res);      close (sock);      return -1;    }  err = connect (sock, res->ai_addr, res->ai_addrlen);  if (err < 0)    {      eXosip_trace (OSIP_ERROR, ("Error in connect: %s\n", strerror (errno)));      freeaddrinfo (res);      close (sock);      return -1;    }  freeaddrinfo (res);  res = NULL;  s = sizeof (addr);  err = getsockname (sock, (struct sockaddr *) &addr, &s);  if (err != 0)    {      eXosip_trace (OSIP_ERROR, ("Error in getsockname: %s\n", strerror (errno)));      close (sock);      return -1;    }  err =    getnameinfo ((struct sockaddr *) &addr, s, loc, size, NULL, 0, NI_NUMERICHOST);  if (err != 0)    {      eXosip_trace (OSIP_ERROR, ("getnameinfo error:%s", strerror (errno)));      close (sock);      return -1;    }  close (sock);  eXosip_trace (OSIP_INFO1,                ("Outgoing interface to reach %s is %s.\n", address_to_reach,                 loc));  return 0;}voideXosip_get_localip_from_via (osip_message_t * mesg, char *locip, int size){  osip_via_t *via = NULL;  char *host;  via = (osip_via_t *) osip_list_get (mesg->vias, 0);  if (via == NULL)    {      host = "15.128.128.93";      eXosip_trace (OSIP_ERROR, ("Could not get via:%s"));  } else    host = via->host;  eXosip_get_localip_for (host, locip, size);}#endifchar *strdup_printf (const char *fmt, ...){  /* Guess we need no more than 100 bytes. */  int n, size = 100;  char *p;  va_list ap;  if ((p = osip_malloc (size)) == NULL)    return NULL;  while (1)    {      /* Try to print in the allocated space. */      va_start (ap, fmt);#ifdef WIN32      n = _vsnprintf (p, size, fmt, ap);#else      n = vsnprintf (p, size, fmt, ap);#endif      va_end (ap);      /* If that worked, return the string. */      if (n > -1 && n < size)        return p;      /* Else try again with more space. */      if (n > -1)               /* glibc 2.1 */        size = n + 1;           /* precisely what is needed */      else                      /* glibc 2.0 */        size *= 2;              /* twice the old size */      if ((p = realloc (p, size)) == NULL)        return NULL;    }}inteXosip_get_addrinfo (struct addrinfo **addrinfo, const char *hostname,                     int service, int protocol){  struct addrinfo hints;  int error;  char portbuf[10];  if (hostname == NULL)    return -1;  if (service != -1)            /* -1 for SRV record */    snprintf (portbuf, sizeof (portbuf), "%i", service);  memset (&hints, 0, sizeof (hints));  hints.ai_flags = 0;  if(ipv6_enable)    hints.ai_family = PF_INET6;  else    hints.ai_family = PF_INET;    /* ipv4 only support */  if (protocol == IPPROTO_UDP)    hints.ai_socktype = SOCK_DGRAM;  else    hints.ai_socktype = SOCK_STREAM;  hints.ai_protocol = protocol; /* IPPROTO_UDP or IPPROTO_TCP */  if (service == -1)            /* -1 for SRV record */    {      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:%s (%s)\n", hostname, portbuf,                   gai_strerror (error)));      return -1;    }  return 0;}int_eXosip_srv_lookup(osip_transaction_t * tr, osip_message_t * sip, struct osip_srv_record *record){	int use_srv=1;	int port;	char *host;	osip_via_t *via;	via = (osip_via_t *) osip_list_get (&sip->vias, 0);	if (via == NULL || via->protocol == NULL)		return -1;	if (MSG_IS_REQUEST(sip))	{	    osip_route_t *route;	    osip_message_get_route (sip, 0, &route);	    if (route != NULL)	    {			osip_uri_param_t *lr_param = NULL;						osip_uri_uparam_get_byname (route->url, "lr", &lr_param);			if (lr_param == NULL)				route = NULL;		}	    	    if (route != NULL)	    {			port = 5060;			if (route->url->port != NULL)			{				port = osip_atoi (route->url->port);				use_srv=0;			}			host = route->url->host;	    }	    else	    {			port = 5060;			if (sip->req_uri->port != NULL)			{				port = osip_atoi (sip->req_uri->port);				use_srv=0;			}			host = sip->req_uri->host;	    }	}	else	{		osip_generic_param_t *maddr;		osip_generic_param_t *received;		osip_generic_param_t *rport;		osip_via_param_get_byname (via, "maddr", &maddr);		osip_via_param_get_byname (via, "received", &received);		osip_via_param_get_byname (via, "rport", &rport);		if (maddr != NULL)			host = maddr->gvalue;		else if (received != NULL)			host = received->gvalue;		else			host = via->host;		if (via->port == NULL)			use_srv=0;		if (rport == NULL || rport->gvalue == NULL)		{			if (via->port != NULL)				port = osip_atoi (via->port);			else				port = 5060;		} else			port = osip_atoi (rport->gvalue);	}	if (use_srv==1)	{		int i;		i = _eXosip_get_srv_record(record, host, via->protocol);	}	return 0;}#if defined(WIN32) && !defined(_WIN32_WCE)int_eXosip_get_srv_record (struct osip_srv_record *record, char *domain, char *protocol){	char zone[1024];	PDNS_RECORD answer, tmp;      /* answer buffer from nameserver */	int n;	char tr[100];	memset(record, 0, sizeof(struct osip_srv_record));	if (strlen(domain)+strlen(protocol)>1000)		return -1;	if (strlen(protocol)>=100)	  return -1;	snprintf(tr, 100, protocol);	osip_tolower(tr);	snprintf(zone, 1024, "_sip._%s.%s", tr, domain);	OSIP_TRACE (osip_trace				(__FILE__, __LINE__, OSIP_INFO2, NULL,				"About to ask for '%s IN SRV'\n", zone));	if (DnsQuery (zone, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &answer, NULL) != 0)	{		return -1;    }	n = 0;	for (tmp = answer; tmp != NULL; tmp = tmp->pNext)	{		struct osip_srv_entry *srventry;		DNS_SRV_DATA * data;		if (tmp->wType != DNS_TYPE_SRV)			continue;		srventry = &record->srventry[n];		data=&tmp->Data.SRV;		snprintf(srventry->srv, sizeof(srventry->srv), "%s", data->pNameTarget);		srventry->priority = data->wPriority;		srventry->weight = data->wWeight;		if (srventry->weight)			srventry->rweight = 1 + rand () % (10000 * srventry->weight);		else			srventry->rweight = 0;		srventry->port = data->wPort;		OSIP_TRACE (osip_trace					(__FILE__, __LINE__, OSIP_INFO2, NULL,					"SRV record %s IN SRV -> %s:%i/%i/%i/%i\n",					zone, srventry->srv, srventry->port, srventry->priority,					srventry->weight, srventry->rweight));		n++;	}	if (n==0)		return -1;	snprintf(record->name, sizeof(record->name), "%s", domain);	return 0;}#elif defined(__linux)/* the biggest packet we'll send and receive */#if PACKETSZ > 1024#define	MAXPACKET PACKETSZ#else#define	MAXPACKET 1024#endif/* and what we send and receive */  typedef union  {    HEADER hdr;    u_char buf[MAXPACKET];  }  querybuf;#ifndef T_SRV#define T_SRV		33#endifint_eXosip_get_srv_record (struct osip_srv_record *record, char *domain, char *protocol){	querybuf answer;              /* answer buffer from nameserver */	int n;	char zone[1024];	int ancount, qdcount;         /* answer count and query count */	HEADER *hp;                   /* answer buffer header */	char hostbuf[256];	unsigned char *msg, *eom, *cp;        /* answer buffer positions */	int dlen, type, aclass, pref, weight, port;	long ttl;	int answerno;	char tr[100];	memset(record, 0, sizeof(struct osip_srv_record));	if (strlen(domain)+strlen(protocol)>1000)		return -1;	if (strlen(protocol)>=100)	  return -1;	snprintf(tr, 100, protocol);	osip_tolower(tr);	snprintf(zone, 1024, "_sip._%s.%s", tr, 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))	{		return -1;	}	/* browse message and search for DNS answers part */	hp = (HEADER *) &answer;	qdcount = ntohs (hp->qdcount);	ancount = ntohs (hp->ancount);	msg = (unsigned char *) (&answer);	eom = (unsigned char *) (&answer) + n;	cp = (unsigned char *) (&answer) + sizeof (HEADER);	while (qdcount-- > 0 && cp < eom)	{		n = dn_expand (msg, eom, cp, (char *) hostbuf, 256);		if (n < 0)		{			OSIP_TRACE (osip_trace						(__FILE__, __LINE__, OSIP_ERROR, NULL,						"Invalid SRV record answer for '%s': bad format\n", zone));			return -1;		}		cp += n + QFIXEDSZ;	}	/* browse DNS answers */	answerno = 0;	/* loop through the answer buffer and extract SRV records */	while (ancount-- > 0 && cp < eom)	{		struct osip_srv_entry *srventry;		n = dn_expand (msg, eom, cp, (char *) hostbuf, 256);		if (n < 0)		{			OSIP_TRACE (osip_trace						(__FILE__, __LINE__, OSIP_ERROR, NULL,						"Invalid SRV record answer for '%s': bad format\n", zone));			return -1;		}		cp += n;#if defined(__NetBSD__) || defined(__OpenBSD__) ||\defined(OLD_NAMESER) || defined(__FreeBSD__)		type = _get_short (cp);		cp += sizeof (u_short);#elif defined(__APPLE_CC__)		GETSHORT (type, cp);#else		NS_GET16 (type, cp);#endif#if defined(__NetBSD__) || defined(__OpenBSD__) ||\defined(OLD_NAMESER) || defined(__FreeBSD__)		aclass = _get_short (cp);		cp += sizeof (u_short);#elif defined(__APPLE_CC__)		GETSHORT (aclass, cp);#else		NS_GET16 (aclass, cp);#endif#if defined(__NetBSD__) || defined(__OpenBSD__) ||\defined(OLD_NAMESER) || defined(__FreeBSD__)		ttl = _get_long (cp);		cp += sizeof (u_long);#elif defined(__APPLE_CC__)		GETLONG (ttl, cp);#else		NS_GET32 (ttl, cp);#endif#if defined(__NetBSD__) || defined(__OpenBSD__) ||\defined(OLD_NAMESER) || defined(__FreeBSD__)		dlen = _get_short (cp);		cp += sizeof (u_short);#elif defined(__APPLE_CC__)		GETSHORT (dlen, cp);#else		NS_GET16 (dlen, cp);#endif		if (type != T_SRV)		{			cp += dlen;			continue;		}#if defined(__NetBSD__) || defined(__OpenBSD__) ||\defined(OLD_NAMESER) || defined(__FreeBSD__)		pref = _get_short (cp);		cp += sizeof (u_short);#elif defined(__APPLE_CC__)		GETSHORT (pref, cp);#else		NS_GET16 (pref, cp);#endif#if defined(__NetBSD__) || defined(__OpenBSD__) ||\defined(OLD_NAMESER) || defined(__FreeBSD__)		weight = _get_short (cp);		cp += sizeof (u_short);#elif defined(__APPLE_CC__)		GETSHORT (weight, cp);#else		NS_GET16 (weight, cp);#endif#if defined(__NetBSD__) || defined(__OpenBSD__) ||\defined(OLD_NAMESER) || defined(__FreeBSD__)		port = _get_short (cp);		cp += sizeof (u_short);#elif defined(__APPLE_CC__)		GETSHORT (port, cp);#else		NS_GET16 (port, cp);#endif		n = dn_expand (msg, eom, cp, (char *) hostbuf, 256);		if (n < 0)			break;		cp += n;		srventry = &record->srventry[answerno];		snprintf(srventry->srv, sizeof(srventry->srv), "%s", hostbuf);		srventry->priority = pref;		srventry->weight = weight;		if (weight)			srventry->rweight = 1 + random () % (10000 * srventry->weight);		else			srventry->rweight = 0;		srventry->port = port;		OSIP_TRACE (osip_trace					(__FILE__, __LINE__, OSIP_INFO2, NULL,					"SRV record %s IN SRV -> %s:%i/%i/%i/%i\n",					zone, srventry->srv, srventry->port, srventry->priority,					srventry->weight, srventry->rweight));		answerno++;	}	if (answerno == 0)		return -1;	snprintf(record->name, sizeof(record->name), "%s", domain);	return 0;}#elseint_eXosip_get_srv_record (struct osip_srv_record *record, char *domain, char *protocol){	return -1;}#endif

⌨️ 快捷键说明

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