exutils.c
来自「mediastreamer2是开源的网络传输媒体流的库」· C语言 代码 · 共 1,770 行 · 第 1/4 页
C
1,770 行
return OSIP_SUCCESS;}#endif#ifdef SRV_RECORDstatic void osip_srv_record_sort(struct osip_srv_record *rec, int n){ int i; int permuts; struct osip_srv_entry swap; do{ struct osip_srv_entry *s1,*s2; permuts=0; for(i=0;i<n-1;++i){ s1=&rec->srventry[i]; s2=&rec->srventry[i+1]; if (s1->priority>s2->priority){ memcpy(&swap,s1,sizeof(swap)); memcpy(s1,s2,sizeof(swap)); memcpy(s2,&swap,sizeof(swap)); permuts++; } } }while(permuts!=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 OSIP_BADPARAMETER; 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 { /* search for maddr parameter */ osip_uri_param_t *maddr_param = NULL; osip_uri_uparam_get_byname (sip->req_uri, "maddr", &maddr_param); host = NULL; if (maddr_param != NULL && maddr_param->gvalue != NULL) host = maddr_param->gvalue; port = 5060; if (sip->req_uri->port != NULL) { use_srv = 0; port = osip_atoi (sip->req_uri->port); } if (host == NULL) 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); } /* check if we have an IPv4 or IPv6 address */ if (strchr (host, ':') || (INADDR_NONE != inet_addr (host))) { return OSIP_UNKNOWN_HOST; } if (use_srv == 1) { int i; i = eXosip_get_srv_record (record, host, via->protocol); return i; } return OSIP_SUCCESS;}#if defined(WIN32) && !defined(_WIN32_WCE)int_eX_dn_expand (unsigned char *msg, unsigned char *eomorig, unsigned char *comp_dn, unsigned char *exp_dn, int length){ unsigned char *cp; unsigned char *dest; unsigned char *eom; int len = -1; int len_copied = 0; dest = exp_dn; cp = comp_dn; eom = exp_dn + length; while (*cp != '\0') { int w = *cp; int comp = w & 0xc0; cp++; if (comp == 0) { if (dest != exp_dn) { if (dest >= eom) return -1; *dest = '.'; dest++; } if (dest + w >= eom) return -1; len_copied++; len_copied = len_copied + w; w--; for (; w >= 0; w--, cp++) { if ((*cp == '.') || (*cp == '\\')) { if (dest + w + 2 >= eom) return -1; *dest = '\\'; dest++; } *dest = *cp; dest++; if (cp >= eomorig) return -1; } } else if (comp == 0xc0) { if (len < 0) len = cp - comp_dn + 1; cp = msg + (((w & 0x3f) << 8) | (*cp & 0xff)); if (cp < msg || cp >= eomorig) return -1; len_copied = len_copied + 2; if (len_copied >= eomorig - msg) return -1; } else return -1; } *dest = '\0'; if (len < 0) len = cp - comp_dn; return len;}inteXosip_get_naptr (char *domain, char *protocol, char *srv_record, int max_length){ char zone[1024]; PDNS_RECORD answer, tmp; /* answer buffer from nameserver */ int n; char tr[100]; if (domain == NULL || protocol == NULL) return OSIP_BADPARAMETER; memset (srv_record, 0, max_length); 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 NAPTR'\n", zone)); if (DnsQuery (zone, DNS_TYPE_NAPTR, DNS_QUERY_STANDARD, NULL, &answer, NULL) != 0) { return OSIP_UNKNOWN_HOST; } n = 0; for (tmp = answer; tmp != NULL; tmp = tmp->pNext) { char *buf = (char *) &tmp->Data; 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; if (tmp->wType != DNS_TYPE_NAPTR) continue; memset (&anaptr, 0, sizeof (osip_naptr_t)); memcpy ((void *) &anaptr.order, buf, 2); anaptr.order = ntohs (anaptr.order); /* ((unsigned short)buf[0] << 8) | ((unsigned short)buf[1]); */ buf += sizeof (unsigned short); memcpy ((void *) &anaptr.pref, buf, 2); anaptr.pref = ntohs (anaptr.pref); /* ((unsigned short)buf[0] << 8) | ((unsigned short)buf[1]); */ buf += sizeof (unsigned short); len = *buf; if (len < 0 || len > 255) break; buf++; strncpy (anaptr.flag, buf, len); anaptr.flag[len] = '\0'; buf += len; len = *buf; if (len < 0 || len > 1023) break; buf++; strncpy (anaptr.service, buf, len); anaptr.service[len] = '\0'; buf += len; len = *buf; if (len < 0 || len > 1023) break; buf++; strncpy (anaptr.regexp, buf, len); anaptr.regexp[len] = '\0'; buf += len; len = _eX_dn_expand ((char *) &tmp->Data, ((char *) &tmp->Data) + tmp->wDataLength, buf, anaptr.replacement, 1024 - 1); if (len < 0) break; buf += len; 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); DnsRecordListFree (answer, DnsFreeRecordList); 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); DnsRecordListFree (answer, DnsFreeRecordList); 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); DnsRecordListFree (answer, DnsFreeRecordList); 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); DnsRecordListFree (answer, DnsFreeRecordList); return OSIP_SUCCESS; } n++; } DnsRecordListFree (answer, DnsFreeRecordList); if (n == 0) return OSIP_UNKNOWN_HOST; return OSIP_UNDEFINED_ERROR;}inteXosip_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]; 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)); if (DnsQuery (zone, DNS_TYPE_SRV, DNS_QUERY_STANDARD, NULL, &answer, NULL) != 0) { return OSIP_UNKNOWN_HOST; } 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++; } DnsRecordListFree (answer, DnsFreeRecordList); if (n == 0) return OSIP_UNKNOWN_HOST; osip_srv_record_sort(record,n); snprintf (record->name, sizeof (record->name), "%s", domain); return OSIP_SUCCESS;}#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;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?