exutils.c

来自「mediastreamer2是开源的网络传输媒体流的库」· C语言 代码 · 共 1,770 行 · 第 1/4 页

C
1,770
字号
  u_char buf[MAXPACKET];}querybuf;#ifndef T_SRV#define T_SRV		33#endif#ifndef T_NAPTR#define T_NAPTR	35#endifinteXosip_get_naptr (char *domain, char *protocol, char *srv_record, int max_length){  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;  long ttl;  int answerno;  char tr[100];  memset (srv_record, 0, max_length);  if (domain == NULL || protocol == NULL)    return OSIP_BADPARAMETER;  if (strlen (domain) + strlen (protocol) > 1000)    return OSIP_BADPARAMETER;  if (strlen (protocol) >= 100)    return OSIP_BADPARAMETER;  snprintf (tr, 100, protocol);  osip_tolower (tr);  snprintf (zone, 1024, "%s", domain);  OSIP_TRACE (osip_trace              (__FILE__, __LINE__, OSIP_INFO2, NULL,               "About to ask for '%s IN NAPTR\n", zone));  n = res_query (zone, C_IN, T_NAPTR, (unsigned char *) &answer, sizeof (answer));  if (n < (int) sizeof (HEADER))    {      return OSIP_UNKNOWN_HOST;    }  /* 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 OSIP_UNDEFINED_ERROR;        }      cp += n + QFIXEDSZ;    }  /* browse DNS answers */  answerno = 0;  /* loop through the answer buffer and extract SRV records */  while (ancount-- > 0 && cp < eom)    {      int len;      typedef struct      {        unsigned short order;        unsigned short pref;        char flag[256];        char service[1024];        char regexp[1024];        char replacement[1024];      } osip_naptr_t;      osip_naptr_t anaptr;      n = dn_expand (msg, eom, cp, (char *) hostbuf, 256);      if (n < 0)        {          OSIP_TRACE (osip_trace                      (__FILE__, __LINE__, OSIP_ERROR, NULL,                       "Invalid NAPTR answer for '%s': bad format\n", zone));          return OSIP_UNDEFINED_ERROR;        }      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_NAPTR)        {          cp += dlen;          continue;        }      memset (&anaptr, 0, sizeof (osip_naptr_t));      memcpy ((void *) &anaptr.order, cp, 2);      anaptr.order = ntohs (anaptr.order);      /*((unsigned short)cp[0] << 8) | ((unsigned short)cp[1]); */      cp += sizeof (unsigned short);      memcpy ((void *) &anaptr.pref, cp, 2);      anaptr.pref = ntohs (anaptr.pref);        /* ((unsigned short)cp[0] << 8) | ((unsigned short)cp[1]); */      cp += sizeof (unsigned short);      len = *cp;      cp++;      strncpy (anaptr.flag, (char *) cp, len);      anaptr.flag[len] = '\0';      cp += len;      len = *cp;      cp++;      strncpy (anaptr.service, (char *) cp, len);      anaptr.service[len] = '\0';      cp += len;      len = *cp;      cp++;      strncpy (anaptr.regexp, (char *) cp, len);      anaptr.regexp[len] = '\0';      cp += len;      n = dn_expand (msg, eom, cp, anaptr.replacement, 1024 - 1);      if (n < 0)        break;      cp += n;      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_INFO2, NULL,                   "NAPTR %s ->%i/%i/%s/%s/%s/%s\n",                   zone, anaptr.order, anaptr.pref, anaptr.flag,                   anaptr.service, anaptr.regexp, anaptr.replacement));      if (osip_strncasecmp (tr, "udp", 4) == 0          && osip_strncasecmp (anaptr.service, "SIP+D2U", 8) == 0)        {          snprintf (srv_record, max_length, "%s", anaptr.replacement);          return OSIP_SUCCESS;      } else if (osip_strncasecmp (tr, "tcp", 4) == 0                 && osip_strncasecmp (anaptr.service, "SIP+D2T", 8) == 0)        {          snprintf (srv_record, max_length, "%s", anaptr.replacement);          return OSIP_SUCCESS;      } else if (osip_strncasecmp (tr, "udp-tls", 8) == 0                 && osip_strncasecmp (anaptr.service, "SIPS+D2U", 9) == 0)        {          snprintf (srv_record, max_length, "%s", anaptr.replacement);          return OSIP_SUCCESS;      } else if (osip_strncasecmp (tr, "tls", 4) == 0                 && osip_strncasecmp (anaptr.service, "SIPS+D2T", 9) == 0)        {          snprintf (srv_record, max_length, "%s", anaptr.replacement);          return OSIP_SUCCESS;      } else if (osip_strncasecmp (tr, "sctp", 5) == 0                 && osip_strncasecmp (anaptr.service, "SIP+D2S", 8) == 0)        {          snprintf (srv_record, max_length, "%s", anaptr.replacement);          return OSIP_SUCCESS;        }      answerno++;    }  if (answerno == 0)    return OSIP_UNKNOWN_HOST;  return OSIP_UNDEFINED_ERROR;}inteXosip_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];  if (domain == NULL || protocol == NULL)    return OSIP_BADPARAMETER;  memset (record, 0, sizeof (struct osip_srv_record));  if (strlen (domain) + strlen (protocol) > 1000)    return OSIP_BADPARAMETER;  if (strlen (protocol) >= 100)    return OSIP_BADPARAMETER;  snprintf (tr, 100, protocol);  osip_tolower (tr);  if (eXosip.use_naptr)    n = eXosip_get_naptr (domain, protocol, zone, sizeof (zone) - 1);  else n=-1;  if (n != OSIP_SUCCESS)    {      snprintf (zone, sizeof (zone) - 1, "_sip._%s.%s", tr, domain);      OSIP_TRACE (osip_trace                  (__FILE__, __LINE__, OSIP_INFO2, NULL,                   "Using locally generated SRV record %s\n", zone));    }  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 OSIP_UNKNOWN_HOST;    }  /* 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 OSIP_UNDEFINED_ERROR;        }      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 OSIP_UNDEFINED_ERROR;        }      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 OSIP_UNKNOWN_HOST;  osip_srv_record_sort(record,answerno);  snprintf (record->name, sizeof (record->name), "%s", domain);  return OSIP_SUCCESS;}#elseinteXosip_get_srv_record (struct osip_srv_record *record, char *domain,                       char *protocol){  return OSIP_UNDEFINED_ERROR;}#endif#endif

⌨️ 快捷键说明

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