bool HHVM_FUNCTION(checkdnsrr, const String& host, const String& type /* = null_string */) { int ntype; if (!validate_dns_arguments(host, type, ntype)) { return false; } unsigned char ans[MAXPACKET]; struct __res_state *res; res = ResolverInit::s_res.get()->getResolver(); if (res == NULL) { return false; } int i = res_nsearch(res, host.data(), C_IN, ntype, ans, sizeof(ans)); res_nclose(res); php_dns_free_res(res); return (i >= 0); }
bool HHVM_FUNCTION(checkdnsrr, const String& host, const String& type /* = null_string */) { IOStatusHelper io("dns_check_record", host.data()); const char *stype; if (type.empty()) { stype = "MX"; } else { stype = type.data(); } if (host.empty()) { throw_invalid_argument("host: [empty]"); } int ntype; if (!strcasecmp("A", stype)) ntype = DNS_T_A; else if (!strcasecmp("NS", stype)) ntype = DNS_T_NS; else if (!strcasecmp("MX", stype)) ntype = DNS_T_MX; else if (!strcasecmp("PTR", stype)) ntype = DNS_T_PTR; else if (!strcasecmp("ANY", stype)) ntype = DNS_T_ANY; else if (!strcasecmp("SOA", stype)) ntype = DNS_T_SOA; else if (!strcasecmp("TXT", stype)) ntype = DNS_T_TXT; else if (!strcasecmp("CNAME", stype)) ntype = DNS_T_CNAME; else if (!strcasecmp("AAAA", stype)) ntype = DNS_T_AAAA; else if (!strcasecmp("SRV", stype)) ntype = DNS_T_SRV; else if (!strcasecmp("NAPTR", stype)) ntype = DNS_T_NAPTR; else if (!strcasecmp("A6", stype)) ntype = DNS_T_A6; else { throw_invalid_argument("type: %s", stype); return false; } unsigned char ans[MAXPACKET]; struct __res_state *res; res = ResolverInit::s_res.get()->getResolver(); if (res == NULL) { return false; } int i = res_nsearch(res, host.data(), C_IN, ntype, ans, sizeof(ans)); res_nclose(res); php_dns_free_res(res); return (i >= 0); }
bool HHVM_FUNCTION(getmxrr, const String& hostname, VRefParam mxhostsRef, VRefParam weightsRef /* = null */) { IOStatusHelper io("dns_get_mx", hostname.data()); int count, qdc; unsigned short type, weight; unsigned char ans[MAXPACKET]; char buf[MAXHOSTNAMELEN]; unsigned char *cp, *end; Array mxhosts; Array weights; SCOPE_EXIT { mxhostsRef = mxhosts; weightsRef = weights; }; /* Go! */ struct __res_state *res; res = ResolverInit::s_res.get()->getResolver(); if (res == NULL) { return false; } int i = res_nsearch(res, hostname.data(), C_IN, DNS_T_MX, (unsigned char*)&ans, sizeof(ans)); if (i < 0) { res_nclose(res); php_dns_free_res(res); return false; } if (i > (int)sizeof(ans)) { i = sizeof(ans); } HEADER *hp = (HEADER *)&ans; cp = (unsigned char *)&ans + HFIXEDSZ; end = (unsigned char *)&ans +i; for (qdc = ntohs((unsigned short)hp->qdcount); qdc--; cp += i + QFIXEDSZ) { if ((i = dn_skipname(cp, end)) < 0 ) { res_nclose(res); php_dns_free_res(res); return false; } } count = ntohs((unsigned short)hp->ancount); while (--count >= 0 && cp < end) { if ((i = dn_skipname(cp, end)) < 0 ) { res_nclose(res); php_dns_free_res(res); return false; } cp += i; GETSHORT(type, cp); cp += INT16SZ + INT32SZ; GETSHORT(i, cp); if (type != DNS_T_MX) { cp += i; continue; } GETSHORT(weight, cp); if ((i = dn_expand(ans, end, cp, buf, sizeof(buf)-1)) < 0) { res_nclose(res); php_dns_free_res(res); return false; } cp += i; mxhosts.append(String(buf, CopyString)); weights.append(weight); } res_nclose(res); php_dns_free_res(res); return true; }
Variant HHVM_FUNCTION(dns_get_record, const String& hostname, int type /*= -1*/, VRefParam authnsRef /* = null */, VRefParam addtlRef /* = null */) { IOStatusHelper io("dns_get_record", hostname.data(), type); if (type < 0) type = PHP_DNS_ALL; if (type & ~PHP_DNS_ALL && type != PHP_DNS_ANY) { raise_warning("Type '%d' not supported", type); return false; } unsigned char *cp = NULL, *end = NULL; int qd, an, ns = 0, ar = 0; querybuf answer; /* - We emulate an or'ed type mask by querying type by type. * (Steps 0 - NUMTYPES-1 ) * If additional info is wanted we check again with DNS_T_ANY * (step NUMTYPES / NUMTYPES+1 ) * store_results is used to skip storing the results retrieved in step * NUMTYPES+1 when results were already fetched. * - In case of PHP_DNS_ANY we use the directly fetch DNS_T_ANY. * (step NUMTYPES+1 ) */ Array ret; bool first_query = true; bool store_results = true; for (int t = (type == PHP_DNS_ANY ? (PHP_DNS_NUM_TYPES + 1) : 0); t < PHP_DNS_NUM_TYPES + 2 || first_query; t++) { first_query = false; int type_to_fetch; switch (t) { case 0: type_to_fetch = type & PHP_DNS_A ? DNS_T_A : 0; break; case 1: type_to_fetch = type & PHP_DNS_NS ? DNS_T_NS : 0; break; case 2: type_to_fetch = type & PHP_DNS_CNAME ? DNS_T_CNAME : 0; break; case 3: type_to_fetch = type & PHP_DNS_SOA ? DNS_T_SOA : 0; break; case 4: type_to_fetch = type & PHP_DNS_PTR ? DNS_T_PTR : 0; break; case 5: type_to_fetch = type & PHP_DNS_HINFO ? DNS_T_HINFO : 0; break; case 6: type_to_fetch = type & PHP_DNS_MX ? DNS_T_MX : 0; break; case 7: type_to_fetch = type & PHP_DNS_TXT ? DNS_T_TXT : 0; break; case 8: type_to_fetch = type & PHP_DNS_AAAA ? DNS_T_AAAA : 0; break; case 9: type_to_fetch = type & PHP_DNS_SRV ? DNS_T_SRV : 0; break; case 10: type_to_fetch = type & PHP_DNS_NAPTR ? DNS_T_NAPTR : 0; break; case 11: type_to_fetch = type & PHP_DNS_A6 ? DNS_T_A6 : 0; break; case PHP_DNS_NUM_TYPES: store_results = false; continue; default: case (PHP_DNS_NUM_TYPES + 1): type_to_fetch = DNS_T_ANY; break; } if (!type_to_fetch) continue; struct __res_state *res; res = ResolverInit::s_res.get()->getResolver(); if (res == NULL) { return false; } int n = res_nsearch(res, hostname.data(), C_IN, type_to_fetch, answer.qb2, sizeof answer); if (n < 0) { res_nclose(res); php_dns_free_res(res); continue; } HEADER *hp; cp = answer.qb2 + HFIXEDSZ; end = answer.qb2 + n; hp = (HEADER *)&answer; qd = ntohs(hp->qdcount); an = ntohs(hp->ancount); ns = ntohs(hp->nscount); ar = ntohs(hp->arcount); /* Skip QD entries, they're only used by dn_expand later on */ while (qd-- > 0) { n = dn_skipname(cp, end); if (n < 0) { raise_warning("Unable to parse DNS data received"); res_nclose(res); php_dns_free_res(res); return false; } cp += n + QFIXEDSZ; } /* YAY! Our real answers! */ while (an-- && cp && cp < end) { Array retval; cp = php_parserr(cp, end, &answer, type_to_fetch, store_results, retval); if (!retval.empty() && store_results) { ret.append(retval); } } res_nclose(res); php_dns_free_res(res); } Array authns; Array addtl; /* List of Authoritative Name Servers */ while (ns-- > 0 && cp && cp < end) { Array retval; cp = php_parserr(cp, end, &answer, DNS_T_ANY, true, retval); if (!retval.empty()) { authns.append(retval); } } /* Additional records associated with authoritative name servers */ while (ar-- > 0 && cp && cp < end) { Array retval; cp = php_parserr(cp, end, &answer, DNS_T_ANY, true, retval); if (!retval.empty()) { addtl.append(retval); } } authnsRef = authns; addtlRef = addtl; return ret; }