From: Gustavo André dos Santos Lopes <cataphract@php.net> Date: Mon, 11 Oct 2010 02:48:23 +0000 (+0000) Subject: - [DOC] Added a 5th parameter to dns_get_record, a boolean that tells whether to... X-Git-Tag: php-5.4.0alpha1~191^2~801 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=91f64706c2579764e23664812897ca2a466d7218;p=php - [DOC] Added a 5th parameter to dns_get_record, a boolean that tells whether to activate "raw mode". In this mide, $type (2nd parameter) is the numeric type of the record, and the responses are not parsed -- the "type" element will be numeric and there will be a "data" element with the raw data of the response buffer, which the programmer will have to parse. - Fixed bug in the Win32 implementation of dns_get_record, where the 3rd and 4th arguments would only be filled if the 2nd ($type) was DNS_ANY. - [DOC] The 3rd and 4th parameters can now be NULL (changed their arginfo). --- diff --git a/ext/standard/basic_functions.c b/ext/standard/basic_functions.c index a70a5b222b..6991972119 100644 --- a/ext/standard/basic_functions.c +++ b/ext/standard/basic_functions.c @@ -996,11 +996,12 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_check_record, 0, 0, 1) ZEND_END_ARG_INFO() # if defined(PHP_WIN32) || HAVE_FULL_DNS_FUNCS -ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_record, 1, 0, 1) +ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_record, 0, 0, 1) ZEND_ARG_INFO(0, hostname) ZEND_ARG_INFO(0, type) - ZEND_ARG_INFO(1, authns) /* ARRAY_INFO(1, authns, 1) */ - ZEND_ARG_INFO(1, addtl) /* ARRAY_INFO(1, addtl, 1) */ + ZEND_ARG_ARRAY_INFO(1, authns, 1) + ZEND_ARG_ARRAY_INFO(1, addtl, 1) + ZEND_ARG_INFO(0, raw) ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO_EX(arginfo_dns_get_mx, 0, 0, 2) diff --git a/ext/standard/dns.c b/ext/standard/dns.c index 22c44525e4..dfbe7defd0 100644 --- a/ext/standard/dns.c +++ b/ext/standard/dns.c @@ -403,7 +403,7 @@ PHP_FUNCTION(dns_check_record) #if HAVE_FULL_DNS_FUNCS /* {{{ php_parserr */ -static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int store, zval **subarray) +static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int store, int raw, zval **subarray) { u_short type, class, dlen; u_long ttl; @@ -439,6 +439,16 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int array_init(*subarray); add_assoc_string(*subarray, "host", name, 1); + add_assoc_string(*subarray, "class", "IN", 1); + add_assoc_long(*subarray, "ttl", ttl); + + if (raw) { + add_assoc_long(*subarray, "type", type); + add_assoc_stringl(*subarray, "data", (char*) cp, (uint) dlen, 1); + cp += dlen; + return cp; + } + switch (type) { case DNS_T_A: add_assoc_string(*subarray, "type", "A", 1); @@ -679,20 +689,12 @@ static u_char *php_parserr(u_char *cp, querybuf *answer, int type_to_fetch, int add_assoc_string(*subarray, "replacement", name, 1); break; default: - { - char buf[10]; /* max length of short + sizeof(id #) */ - snprintf(buf, 10, "id #%hu", type); - buf[10-1] = '\0'; - add_assoc_string(*subarray, "type", buf, 1); - add_assoc_stringl(*subarray, "data", (char*) cp, (uint) dlen, 1); - cp += dlen; - break; - } + zval_ptr_dtor(subarray); + *subarray = NULL; + cp += dlen; + break; } - add_assoc_string(*subarray, "class", "IN", 1); - add_assoc_long(*subarray, "ttl", ttl); - return cp; } /* }}} */ @@ -720,8 +722,10 @@ PHP_FUNCTION(dns_get_record) u_char *cp = NULL, *end = NULL; int n, qd, an, ns = 0, ar = 0; int type, first_query = 1, store_results = 1; + zend_bool raw = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzz", &hostname, &hostname_len, &type_param, &authns, &addtl) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz!z!b", + &hostname, &hostname_len, &type_param, &authns, &addtl, &raw) == FAILURE) { return; } @@ -735,9 +739,17 @@ PHP_FUNCTION(dns_get_record) addtl_recs = 1; } - if (type_param & ~PHP_DNS_ALL && type_param != PHP_DNS_ANY) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type '%ld' not supported", type_param); - RETURN_FALSE; + if (!raw) { + if ((type_param & ~PHP_DNS_ALL) && (type_param != PHP_DNS_ANY)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type '%ld' not supported", type_param); + RETURN_FALSE; + } + } else { + if ((type_param < 1) || (type_param > 0xFFFF)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Numeric DNS record type must be between 1 and 65535, '%ld' given", type_param); + RETURN_FALSE; + } } /* Initialize the return array */ @@ -748,13 +760,29 @@ PHP_FUNCTION(dns_get_record) * 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 ) + * - In case of raw mode, we query only the requestd type instead of looping type by type + * before going with the additional info stuff. */ - for (type = (type_param == PHP_DNS_ANY ? (PHP_DNS_NUM_TYPES + 1) : 0); + + if (raw) { + type = -1; + } else if (type_param == PHP_DNS_ANY) { + type = PHP_DNS_NUM_TYPES + 1; + } else { + type = 0; + } + + for ( ; type < (addtl_recs ? (PHP_DNS_NUM_TYPES + 2) : PHP_DNS_NUM_TYPES) || first_query; type++ ) { first_query = 0; switch (type) { + case -1: /* raw */ + type_to_fetch = type_param; + /* skip over the rest and go directly to additional records */ + type = PHP_DNS_NUM_TYPES - 1; + break; case 0: type_to_fetch = type_param&PHP_DNS_A ? DNS_T_A : 0; break; @@ -846,7 +874,7 @@ PHP_FUNCTION(dns_get_record) while (an-- && cp && cp < end) { zval *retval; - cp = php_parserr(cp, &answer, type_to_fetch, store_results, &retval); + cp = php_parserr(cp, &answer, type_to_fetch, store_results, raw, &retval); if (retval != NULL && store_results) { add_next_index_zval(return_value, retval); } @@ -859,7 +887,7 @@ PHP_FUNCTION(dns_get_record) while (ns-- > 0 && cp && cp < end) { zval *retval = NULL; - cp = php_parserr(cp, &answer, DNS_T_ANY, authns != NULL, &retval); + cp = php_parserr(cp, &answer, DNS_T_ANY, authns != NULL, raw, &retval); if (retval != NULL) { add_next_index_zval(authns, retval); } @@ -871,7 +899,7 @@ PHP_FUNCTION(dns_get_record) while (ar-- > 0 && cp && cp < end) { zval *retval = NULL; - cp = php_parserr(cp, &answer, DNS_T_ANY, 1, &retval); + cp = php_parserr(cp, &answer, DNS_T_ANY, 1, raw, &retval); if (retval != NULL) { add_next_index_zval(addtl, retval); } diff --git a/ext/standard/dns_win32.c b/ext/standard/dns_win32.c index a86cc06a1e..ba1c5a1abf 100644 --- a/ext/standard/dns_win32.c +++ b/ext/standard/dns_win32.c @@ -133,7 +133,7 @@ PHP_FUNCTION(dns_check_record) /* }}} */ /* {{{ php_parserr */ -static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, zval **subarray) +static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, int raw, zval **subarray) { int type; u_long ttl; @@ -153,6 +153,15 @@ static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, zval **s array_init(*subarray); add_assoc_string(*subarray, "host", pRec->pName, 1); + add_assoc_string(*subarray, "class", "IN", 1); + add_assoc_long(*subarray, "ttl", ttl); + + if (raw) { + add_assoc_long(*subarray, "type", type); + add_assoc_stringl(*subarray, "data", (char*) &pRec->Data, (uint) pRec->wDataLength, 1); + return; + } + switch (type) { case DNS_TYPE_A: { IN_ADDR ipaddr; @@ -303,9 +312,9 @@ static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, zval **s } break; +#if _MSC_VER >= 1500 case DNS_TYPE_NAPTR: { -#if _MSC_VER >= 1500 DNS_NAPTR_DATA * data_naptr = &pRec->Data.Naptr; add_assoc_string(*subarray, "type", "NAPTR", 1); @@ -315,23 +324,17 @@ static void php_parserr(PDNS_RECORD pRec, int type_to_fetch, int store, zval **s add_assoc_string(*subarray, "services", data_naptr->pService, 1); add_assoc_string(*subarray, "regex", data_naptr->pRegularExpression, 1); add_assoc_string(*subarray, "replacement", data_naptr->pReplacement, 1); -#endif } break; +#endif default: - { - char buf[10]; /* max length of short + sizeof(id #) */ - snprintf(buf, 10, "id #%hu", (unsigned short) type); - buf[10-1] = '\0'; - add_assoc_string(*subarray, "type", buf, 1); - add_assoc_stringl(*subarray, "data", (char*) &pRec->Data, (uint) pRec->wDataLength, 1); - break; - } + /* unkown type */ + zval_ptr_dtor(subarray); + *subarray = NULL; + return; } - add_assoc_string(*subarray, "class", "IN", 1); - add_assoc_long(*subarray, "ttl", ttl); } /* }}} */ @@ -345,8 +348,10 @@ PHP_FUNCTION(dns_get_record) zval *authns = NULL, *addtl = NULL; int type, type_to_fetch, first_query = 1, store_results = 1; int addtl_recs = 0; + zend_bool raw = 0; - if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lzz", &hostname, &hostname_len, &type_param, &authns, &addtl) == FAILURE) { + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|lz!z!b", + &hostname, &hostname_len, &type_param, &authns, &addtl, &raw) == FAILURE) { return; } @@ -357,17 +362,34 @@ PHP_FUNCTION(dns_get_record) if (addtl) { zval_dtor(addtl); array_init(addtl); + addtl_recs = 1; } - if (type_param & ~PHP_DNS_ALL && type_param != PHP_DNS_ANY) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type '%ld' not supported", type_param); - RETURN_FALSE; + if (!raw) { + if ((type_param & ~PHP_DNS_ALL) && (type_param != PHP_DNS_ANY)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Type '%ld' not supported", type_param); + RETURN_FALSE; + } + } else { + if ((type_param < 1) || (type_param > 0xFFFF)) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, + "Numeric DNS record type must be between 1 and 65535, '%ld' given", type_param); + RETURN_FALSE; + } } /* Initialize the return array */ array_init(return_value); - for (type = (type_param == PHP_DNS_ANY ? (PHP_DNS_NUM_TYPES + 1) : 0); + if (raw) { + type = -1; + } else if (type_param == PHP_DNS_ANY) { + type = PHP_DNS_NUM_TYPES + 1; + } else { + type = 0; + } + + for ( ; type < (addtl_recs ? (PHP_DNS_NUM_TYPES + 2) : PHP_DNS_NUM_TYPES) || first_query; type++ ) { @@ -376,6 +398,11 @@ PHP_FUNCTION(dns_get_record) first_query = 0; switch (type) { + case -1: /* raw */ + type_to_fetch = type_param; + /* skip over the rest and go directly to additional records */ + type = PHP_DNS_NUM_TYPES - 1; + break; case 0: type_to_fetch = type_param&PHP_DNS_A ? DNS_TYPE_A : 0; break; @@ -439,7 +466,7 @@ PHP_FUNCTION(dns_get_record) zval *retval = NULL; if (pRec->Flags.S.Section == DnsSectionAnswer) { - php_parserr(pRec, type_to_fetch, store_results, &retval); + php_parserr(pRec, type_to_fetch, store_results, raw, &retval); if (retval != NULL && store_results) { add_next_index_zval(return_value, retval); } @@ -447,7 +474,7 @@ PHP_FUNCTION(dns_get_record) if (authns && pRec->Flags.S.Section == DnsSectionAuthority) { - php_parserr(pRec, type_to_fetch, store_results, &retval); + php_parserr(pRec, type_to_fetch, 1, raw, &retval); if (retval != NULL) { add_next_index_zval(authns, retval); } @@ -462,7 +489,7 @@ PHP_FUNCTION(dns_get_record) # endif #endif if (addtl && pRec->Flags.S.Section == DnsSectionAdditional) { - php_parserr(pRec, type_to_fetch, store_results, &retval); + php_parserr(pRec, type_to_fetch, 1, raw, &retval); if (retval != NULL) { add_next_index_zval(addtl, retval); }