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 + -
显示快捷键?