]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
back out change 2740
authorEvan Hunt <each@isc.org>
Wed, 28 Oct 2009 18:04:29 +0000 (18:04 +0000)
committerEvan Hunt <each@isc.org>
Wed, 28 Oct 2009 18:04:29 +0000 (18:04 +0000)
CHANGES
lib/dns/resolver.c

diff --git a/CHANGES b/CHANGES
index 4977009acecd81258b2a081274d53fc74a39f61c..db1504162372d7e3964b9a8a198c612b01ef91da 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -6,8 +6,7 @@
                        suppress the progress messages when stdin is not
                        a tty. [RT #20474]
 
-2740.  [func]          Identify bad answers from GTLD servers and treat them
-                       as referrals. [RT #18884]
+2740.  [placeholder]
 
 2739.  [cleanup]       Clean up API for initializing and clearing trust
                        anchors for a view. [RT #20211]
index 1f5d7796b73bda3ac0e5a2ce42b74917a2e686ea..bf9c42859c614c8089073aaf21774820fa68ad22 100644 (file)
@@ -15,7 +15,7 @@
  * PERFORMANCE OF THIS SOFTWARE.
  */
 
-/* $Id: resolver.c,v 1.407 2009/10/27 23:05:53 marka Exp $ */
+/* $Id: resolver.c,v 1.408 2009/10/28 18:04:29 each Exp $ */
 
 /*! \file */
 
@@ -4819,9 +4819,7 @@ mark_related(dns_name_t *name, dns_rdataset_t *rdataset,
 }
 
 static isc_result_t
-check_section(void *arg, dns_name_t *addname, dns_rdatatype_t type,
-             dns_section_t section)
-{
+check_related(void *arg, dns_name_t *addname, dns_rdatatype_t type) {
        fetchctx_t *fctx = arg;
        isc_result_t result;
        dns_name_t *name;
@@ -4832,19 +4830,15 @@ check_section(void *arg, dns_name_t *addname, dns_rdatatype_t type,
 
        REQUIRE(VALID_FCTX(fctx));
 
-#if CHECK_FOR_GLUE_IN_ANSWER
-       if (section == DNS_SECTION_ANSWER && type != dns_rdatatype_a)
-               return (ISC_R_SUCCESS);
-#endif
-
        if (GLUING(fctx))
                gluing = ISC_TRUE;
        else
                gluing = ISC_FALSE;
        name = NULL;
        rdataset = NULL;
-       result = dns_message_findname(fctx->rmessage, section, addname,
-                                     dns_rdatatype_any, 0, &name, NULL);
+       result = dns_message_findname(fctx->rmessage, DNS_SECTION_ADDITIONAL,
+                                     addname, dns_rdatatype_any, 0, &name,
+                                     NULL);
        if (result == ISC_R_SUCCESS) {
                external = ISC_TF(!dns_name_issubdomain(name, &fctx->domain));
                if (type == dns_rdatatype_a) {
@@ -4882,21 +4876,6 @@ check_section(void *arg, dns_name_t *addname, dns_rdatatype_t type,
        return (ISC_R_SUCCESS);
 }
 
-static isc_result_t
-check_related(void *arg, dns_name_t *addname, dns_rdatatype_t type) {
-       return (check_section(arg, addname, type, DNS_SECTION_ADDITIONAL));
-}
-
-#ifndef CHECK_FOR_GLUE_IN_ANSWER
-#define CHECK_FOR_GLUE_IN_ANSWER 0
-#endif
-#if CHECK_FOR_GLUE_IN_ANSWER
-static isc_result_t
-check_answer(void *arg, dns_name_t *addname, dns_rdatatype_t type) {
-       return (check_section(arg, addname, type, DNS_SECTION_ANSWER));
-}
-#endif
-
 static void
 chase_additional(fetchctx_t *fctx) {
        isc_boolean_t rescan;
@@ -5124,13 +5103,14 @@ is_answertarget_allowed(dns_view_t *view, dns_name_t *name,
 
 /*
  * Handle a no-answer response (NXDOMAIN, NXRRSET, or referral).
- * If look_in_answer is ISC_TRUE then we look in the answer section
- * for the NS RRset if the query type is NS or look for glue incorrectly
- * returned in the answer section for A and AAAA queries.
+ * If bind8_ns_resp is ISC_TRUE, this is a suspected BIND 8
+ * response to an NS query that should be treated as a referral
+ * even though the NS records occur in the answer section
+ * rather than the authority section.
  */
 static isc_result_t
 noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
-                 isc_boolean_t look_in_answer)
+                 isc_boolean_t bind8_ns_resp)
 {
        isc_result_t result;
        dns_message_t *message;
@@ -5138,15 +5118,11 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
        dns_rdataset_t *rdataset, *ns_rdataset;
        isc_boolean_t aa, negative_response;
        dns_rdatatype_t type;
-       dns_section_t section;
+       dns_section_t section =
+               bind8_ns_resp ? DNS_SECTION_ANSWER : DNS_SECTION_AUTHORITY;
 
        FCTXTRACE("noanswer_response");
 
-       if (fctx->type == dns_rdatatype_ns && look_in_answer)
-               section = DNS_SECTION_ANSWER;
-       else
-               section = DNS_SECTION_AUTHORITY;
-
        message = fctx->rmessage;
 
        /*
@@ -5427,20 +5403,6 @@ noanswer_response(fetchctx_t *fctx, dns_name_t *oqname,
                fctx->attributes |= FCTX_ATTR_GLUING;
                (void)dns_rdataset_additionaldata(ns_rdataset, check_related,
                                                  fctx);
-#if CHECK_FOR_GLUE_IN_ANSWER
-               /*
-                * Look in the answer section for "glue" that is incorrectly
-                * returned as a answer.  This is needed if the server also
-                * minimizes the response size by not adding records to the
-                * additional section that are in the answer section or if
-                * the record gets dropped due to message size constraints.
-                */
-               if (look_in_answer &&
-                   (fctx->type == dns_rdatatype_aaaa ||
-                    fctx->type == dns_rdatatype_a))
-                       (void)dns_rdataset_additionaldata(ns_rdataset,
-                                                         check_answer, fctx);
-#endif
                fctx->attributes &= ~FCTX_ATTR_GLUING;
                /*
                 * NS rdatasets with 0 TTL cause problems.
@@ -6175,16 +6137,6 @@ log_packet(dns_message_t *message, int level, isc_mem_t *mctx) {
                isc_mem_put(mctx, buf, len);
 }
 
-static isc_boolean_t
-iscname(fetchctx_t *fctx) {
-       isc_result_t result;
-
-       result = dns_message_findname(fctx->rmessage, DNS_SECTION_ANSWER,
-                                     &fctx->name, dns_rdatatype_cname, 0,
-                                     NULL, NULL);
-       return (result == ISC_R_SUCCESS ? ISC_TRUE : ISC_FALSE);
-}
-
 static void
 resquery_response(isc_task_t *task, isc_event_t *event) {
        isc_result_t result = ISC_R_SUCCESS;
@@ -6624,51 +6576,27 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
            (message->rcode == dns_rcode_noerror ||
             message->rcode == dns_rcode_nxdomain)) {
                /*
-                * [normal case]
-                * We've got answers.  If it has an authoritative answer or an
-                * answer from a forwarder, we're done.
+                * We've got answers.  However, if we sent
+                * a BIND 8 server an NS query, it may have
+                * incorrectly responded with a non-authoritative
+                * answer instead of a referral.  Since this
+                * answer lacks the SIGs necessary to do DNSSEC
+                * validation, we must invoke the following special
+                * kludge to treat it as a referral.
                 */
-               if ((message->flags & DNS_MESSAGEFLAG_AA) != 0 ||
-                   ISFORWARDER(query->addrinfo))
-                       result = answer_response(fctx);
-               else if (iscname(fctx) &&
-                        fctx->type != dns_rdatatype_any &&
-                        fctx->type != dns_rdatatype_cname) {
-                       /*
-                        * A BIND8 server could return a non-authoritative
-                        * answer when a CNAME is followed.  We should treat
-                        * it as a valid answer.
-                        */
-                       result = answer_response(fctx);
-               } else {
-                       if (fctx->type == dns_rdatatype_ns) {
-                               /*
-                                * A BIND 8 server could incorrectly return a
-                                * non-authoritative answer to an NS query
-                                * instead of a referral. Since this answer
-                                * lacks the SIGs necessary to do DNSSEC
-                                * validation, we must invoke the following
-                                * special kludge to treat it as a referral.
-                                */
-                               result = noanswer_response(fctx, NULL,
-                                                          ISC_TRUE);
-                       } else {
-                               /*
-                                * Some other servers may still somehow include
-                                * an answer when it should return a referral
-                                * with an empty answer.  Check to see if we can
-                                * treat this as a referral by ignoring the
-                                * answer.
-                                */
-                               result = noanswer_response(fctx, NULL,
-                                                          ISC_TRUE);
-                       }
+               if (fctx->type == dns_rdatatype_ns &&
+                   (message->flags & DNS_MESSAGEFLAG_AA) == 0 &&
+                   !ISFORWARDER(query->addrinfo))
+               {
+                       result = noanswer_response(fctx, NULL, ISC_TRUE);
                        if (result != DNS_R_DELEGATION) {
                                /*
-                                * At this point, AA is not set, the response
-                                * is not a referral, and the server is not a
-                                * forwarder.  It is technically lame and it's
-                                * easier to treat it as such than to figure out
+                                * The answer section must have contained
+                                * something other than the NS records
+                                * we asked for.  Since AA is not set
+                                * and the server is not a forwarder,
+                                * it is technically lame and it's easier
+                                * to treat it as such than to figure out
                                 * some more elaborate course of action.
                                 */
                                broken_server = DNS_R_LAME;
@@ -6677,6 +6605,7 @@ resquery_response(isc_task_t *task, isc_event_t *event) {
                        }
                        goto force_referral;
                }
+               result = answer_response(fctx);
                if (result != ISC_R_SUCCESS) {
                        if (result == DNS_R_FORMERR)
                                keep_trying = ISC_TRUE;