int 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(zone, 0, sizeof(zone)); memset(record, 0, sizeof(struct osip_srv_record)); if (domain == NULL || protocol == NULL) return OSIP_BADPARAMETER; if (eXosip.dns_capabilities <= 0) return OSIP_UNKNOWN_HOST; /* disabled */ 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.dns_capabilities >= 2) n = eXosip_get_naptr(domain, protocol, zone, sizeof(zone) - 1); else n = -1; /* avoid NAPTR */ if (n == OSIP_SUCCESS && zone[0] == '\0') { /* protocol is not listed in NAPTR answer: not supported */ return OSIP_UNKNOWN_HOST; } 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 == 10) break; } if (answerno == 0) return OSIP_UNKNOWN_HOST; osip_srv_record_sort(record, answerno); snprintf(record->name, sizeof(record->name), "%s", domain); return OSIP_SUCCESS; }
size_t FileManager::_read(void *buf, size_t len) { // starting point for crc computation uint8_t *start = reinterpret_cast<uint8_t *>(buf); if (_z_err == Z_DATA_ERROR || _z_err == Z_ERRNO) { return -1; } if (_z_err == Z_STREAM_END) { return 0; // EOF } _stream->next_out = reinterpret_cast<uint8_t *>(buf); _stream->avail_out = len; int got; while (_stream->avail_out != 0) { if (!_compressed) { // Copy first the lookahead bytes uint32_t n = _stream->avail_in; if (n > _stream->avail_out) n = _stream->avail_out; if (n > 0) { memcpy(_stream->next_out, _stream->next_in, n); _stream->next_out += n; _stream->next_in += n; _stream->avail_out -= n; _stream->avail_in -= n; } if (_stream->avail_out > 0) { got = _file->read(_stream->next_out, _stream->avail_out); if (got == -1) { return(got); } _stream->avail_out -= got; } return(int)(len - _stream->avail_out); } if (_stream->avail_in == 0 && !_z_eof) { got = _file->read(_inbuf, Z_BUFSIZE); if (got <= 0) _z_eof = 1; _stream->avail_in = got; _stream->next_in = _inbuf; } _z_err = inflate(_stream, Z_NO_FLUSH); if (_z_err == Z_STREAM_END) { /* Check CRC and original size */ _crc = crc32(_crc, start,(unsigned int) (_stream->next_out - start)); start = _stream->next_out; if (_get_long() != _crc || _get_long() != _stream->total_out) { _z_err = Z_DATA_ERROR; } else { /* Check for concatenated .gz files: */ _check_header(); if (_z_err == Z_OK) { inflateReset(_stream); _crc = crc32(0L, Z_NULL, 0); } } } if (_z_err != Z_OK || _z_eof) break; } _crc = crc32(_crc, start,(unsigned int)(_stream->next_out - start)); return(int)(len - _stream->avail_out); }
int eXosip_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; OSIP_TRACE(osip_trace (__FILE__, __LINE__, OSIP_INFO2, NULL, "protocol: %s is not supported by domain %s\n", protocol, domain)); return OSIP_SUCCESS; }