From: Michał Kępień Date: Wed, 22 Aug 2018 08:12:53 +0000 (+0200) Subject: Do not treat a referral with a non-empty ANSWER section as an error X-Git-Tag: v9.13.3~52^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=24b9ec555ab3fe73f456a27d092f89794e6d7ae8;p=thirdparty%2Fbind9.git Do not treat a referral with a non-empty ANSWER section as an error As part of resquery_response() refactoring [1], a goto statement was replaced [2] with a call to a new function - originally called rctx_delegation(), now folded into rctx_answer_none() - extracted from existing code. However, one call site of that refactored function does not reset the "result" variable, causing a referral with a non-empty ANSWER section to be inadvertently treated as an error, which prevents resolution of names reliant on servers sending such responses. Fix by resetting the "result" variable to ISC_R_SUCCESS when a response containing a non-empty ANSWER section can be treated as a delegation. [1] see RT #45362 [2] see commit e1380a16741a3b4a57e54d7a9ce09dd12691522f --- diff --git a/bin/tests/system/resolver/ans2/ans.pl b/bin/tests/system/resolver/ans2/ans.pl index 79bb10205c8..9d5251e8b4c 100644 --- a/bin/tests/system/resolver/ans2/ans.pl +++ b/bin/tests/system/resolver/ans2/ans.pl @@ -107,6 +107,10 @@ for (;;) { # expected to be accepted regardless of the filter setting. $packet->push("authority", new Net::DNS::RR("sub.example.org 300 NS ns.sub.example.org")); $packet->push("additional", new Net::DNS::RR("ns.sub.example.org 300 A 10.53.0.3")); + } elsif ($qname =~ /glue-in-answer\.example\.org/) { + $packet->push("answer", new Net::DNS::RR("ns.glue-in-answer.example.org 300 A 10.53.0.3")); + $packet->push("authority", new Net::DNS::RR("glue-in-answer.example.org 300 NS ns.glue-in-answer.example.org")); + $packet->push("additional", new Net::DNS::RR("ns.glue-in-answer.example.org 300 A 10.53.0.3")); } elsif ($qname =~ /\.broken/ || $qname =~ /^broken/) { # Delegation to broken TLD. $packet->push("authority", new Net::DNS::RR("broken 300 NS ns.broken")); diff --git a/bin/tests/system/resolver/ans3/ans.pl b/bin/tests/system/resolver/ans3/ans.pl index 972ca5c8de5..097ced4b2dd 100644 --- a/bin/tests/system/resolver/ans3/ans.pl +++ b/bin/tests/system/resolver/ans3/ans.pl @@ -107,6 +107,8 @@ for (;;) { } elsif ($qname eq "www.ok.sub.example.org") { $packet->push("answer", new Net::DNS::RR($qname . " 300 A 192.0.2.1")); + } elsif ($qname eq "foo.glue-in-answer.example.org") { + $packet->push("answer", new Net::DNS::RR($qname . " 300 A 192.0.2.1")); } else { $packet->push("answer", new Net::DNS::RR("www.example.com 300 A 1.2.3.4")); } diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh index 12d2819e300..2bea476f1be 100755 --- a/bin/tests/system/resolver/tests.sh +++ b/bin/tests/system/resolver/tests.sh @@ -247,6 +247,15 @@ if [ -x ${RESOLVE} ] ; then status=`expr $status + $ret` fi +n=`expr $n + 1` +echo_i "check that the resolver accepts a referral response with a non-empty ANSWER section ($n)" +ret=0 +$DIG $DIGOPTS @10.53.0.1 foo.glue-in-answer.example.org. A > dig.ns1.out.${n} || ret=1 +grep "status: NOERROR" dig.ns1.out.${n} > /dev/null || ret=1 +grep "foo.glue-in-answer.example.org.*192.0.2.1" dig.ns1.out.${n} > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=`expr $status + $ret` + n=`expr $n + 1` echo_i "RT21594 regression test check setup ($n)" ret=0 diff --git a/lib/dns/resolver.c b/lib/dns/resolver.c index a71ece63014..cbc1aa8348a 100644 --- a/lib/dns/resolver.c +++ b/lib/dns/resolver.c @@ -7881,7 +7881,9 @@ rctx_answer(respctx_t *rctx) { } } - if (result != DNS_R_DELEGATION) { + if (result == DNS_R_DELEGATION) { + result = ISC_R_SUCCESS; + } else { /* * At this point, AA is not set, the response * is not a referral, and the server is not a