dns_core: Allow zero-length DNS responses.
authorMark Michelson <mmichelson@digium.com>
Wed, 29 Jul 2015 17:58:23 +0000 (12:58 -0500)
committerMark Michelson <mmichelson@digium.com>
Fri, 31 Jul 2015 14:44:20 +0000 (09:44 -0500)
A testsuite test recently failed due to a crash that occurred in the DNS
core. The problem was that the test could not resolve an address, did
not set a result on the DNS query, and then indicated the query was
completed. The DNS core does not handle the case of a query with no
result gracefully, and so there is a crash.

This changeset makes the DNS system resolver set a result with a
zero-length answer in the case that a DNS resolution failure occurs
early. The DNS core now also will accept such a response without
treating it as invalid input. A unit test was updated to no longer treat
setting a zero-length response as off-nominal.

Change-Id: Ie56641e22debdaa61459e1c9a042e23b78affbf6

include/asterisk/dns_resolver.h
main/dns.c
main/dns_core.c
tests/test_dns.c

index 819ce7a..2d5f57f 100644 (file)
@@ -90,6 +90,10 @@ void *ast_dns_resolver_get_data(const struct ast_dns_query *query);
  * \param answer The raw DNS answer
  * \param answer_size The size of the raw DNS answer
  *
+ * Zero-sized and NULL answers are permitted by this function. This may be
+ * necessary if the query fails at an early stage and no actual DNS response
+ * has been received from a DNS server.
+ *
  * \retval 0 success
  * \retval -1 failure
  */
index 409ed44..e1b7770 100644 (file)
@@ -559,6 +559,7 @@ enum ast_dns_search_result ast_search_dns_ex(void *context, const char *dname, i
 
        if (dns_response_len < 0) {
                ast_log(LOG_ERROR, "DNS search failed for %s\n", dname);
+               response_handler(context, (unsigned char *)"", 0, ns_r_nxdomain);
                return AST_DNS_SEARCH_FAILURE;
        }
 
index 0b471db..cfce8ef 100644 (file)
@@ -399,10 +399,10 @@ int ast_dns_resolver_set_result(struct ast_dns_query *query, unsigned int secure
                return -1;
        }
 
-       if (!answer || answer_size == 0) {
-               ast_debug(2, "Query '%p': Could not set result information since no DNS answer was provided\n",
-                       query);
-               return -1;
+       if (!answer) {
+               answer = "";
+               answer_size = 0;
+               ast_debug(2, "Query '%p': Assuming zero-sized answer on NULL input\n", query);
        }
 
        ast_dns_result_free(query->result);
index 4e2c4a4..9bbb7da 100644 (file)
@@ -365,9 +365,7 @@ AST_TEST_DEFINE(resolver_set_result_off_nominal)
                info->description =
                        "This test performs the following:\n"
                        "\t* Attempt to add a DNS result that is both bogus and secure\n"
-                       "\t* Attempt to add a DNS result that has no canonical name\n"
-                       "\t* Attempt to add a DNS result that has no answer\n"
-                       "\t* Attempt to add a DNS result with a zero answer size";
+                       "\t* Attempt to add a DNS result that has no canonical name";
                return AST_TEST_NOT_RUN;
        case TEST_EXECUTE:
                break;
@@ -391,22 +389,6 @@ AST_TEST_DEFINE(resolver_set_result_off_nominal)
                return AST_TEST_FAIL;
        }
 
-       if (!ast_dns_resolver_set_result(&some_query, 0, 0, ns_r_noerror, NULL,
-                               NULL, DNS_ANSWER_SIZE)) {
-               ast_test_status_update(test, "Successfully added result with no answer\n");
-               result = ast_dns_query_get_result(&some_query);
-               ast_dns_result_free(result);
-               return AST_TEST_FAIL;
-       }
-
-       if (!ast_dns_resolver_set_result(&some_query, 0, 0, ns_r_noerror, NULL,
-                               DNS_ANSWER, 0)) {
-               ast_test_status_update(test, "Successfully added result with answer size of zero\n");
-               result = ast_dns_query_get_result(&some_query);
-               ast_dns_result_free(result);
-               return AST_TEST_FAIL;
-       }
-
        return AST_TEST_PASS;
 }