]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Set result to SERVFAIL if upstream responded with FORMERR
authorWitold Kręcicki <wpk@isc.org>
Tue, 23 Oct 2018 11:45:30 +0000 (13:45 +0200)
committerMichał Kępień <michal@isc.org>
Tue, 23 Oct 2018 11:50:27 +0000 (13:50 +0200)
Commit ba912435427cf884fdc1ca26743eba6c00439106 causes the resolver to
respond to a client query with FORMERR when all upstream queries sent to
the servers authoritative for QNAME elicit FORMERR responses.  This
happens because resolver code returns DNS_R_FORMERR in such a case and
dns_result_torcode() acts as a pass-through for all arguments which are
already a valid RCODE.

The correct RCODE to set in the response returned to the client in the
case described above is SERVFAIL.  Make sure this happens by overriding
the RCODE in query_gotanswer(), on the grounds that any format errors in
the client query itself should be caught long before execution reaches
that point.  This change should not reduce query error logging accuracy
as the resolver code itself reports the exact reason for returning a
DNS_R_FORMERR result using log_formerr().

bin/tests/system/resolver/ans8/ans.pl
bin/tests/system/resolver/ns4/root.db
bin/tests/system/resolver/tests.sh
lib/ns/query.c

index a019e6cf5c558ec7d029524c652cdb0f6d31ad93..f3bf33fa6dea18ac624a3860dfd6b346ba890992 100644 (file)
@@ -74,6 +74,9 @@ sub handleUDP {
        } elsif ($qname eq "ns.no-questions") {
                $packet->push("answer", new Net::DNS::RR($qname . " 300 A 10.53.0.8"));
                return $packet->data;
+       } elsif ($qname =~ /\.formerr-to-all$/) {
+               $packet->header->rcode("FORMERR");
+               return $packet->data;
        }
 
        # don't use Net::DNS to construct the header only reply as early
index 721765d1be7146b627ac5c3989c24c6c252dd015..43e4bea4a601f34d3ecb5492d78ce79a132bf439 100644 (file)
@@ -24,3 +24,5 @@ example.net.          NS      ns.example.net.
 ns.example.net.                A       10.53.0.6
 no-questions.          NS      ns.no-questions.
 ns.no-questions.       A       10.53.0.8
+formerr-to-all.                NS      ns.formerr-to-all.
+ns.formerr-to-all.     A       10.53.0.8
index 2bea476f1be0b96e25740a6606132163f130ed8e..75ab5c066229f8a031299a63f04053af3435701d 100755 (executable)
@@ -788,5 +788,13 @@ grep "1.2.3.4" dig.ns5.out.${n} > /dev/null && ret=1
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=`expr $status + $ret`
 
+n=`expr $n + 1`
+echo_i "checking SERVFAIL is returned when all authoritative servers return FORMERR ($n)"
+ret=0
+$DIG $DIGOPTS @10.53.0.5 ns.formerr-to-all. a > dig.ns5.out.${n} || ret=1
+grep "status: SERVFAIL" dig.ns5.out.${n} > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=`expr $status + $ret`
+
 echo_i "exit status: $status"
 [ $status -eq 0 ] || exit 1
index e7ccb99586d5b478749a76a61749358c85d38d8f..a1fc0d3a94723279d0f2737cf59866badeee0e65 100644 (file)
@@ -6737,6 +6737,10 @@ query_gotanswer(query_ctx_t *qctx, isc_result_t result) {
        case DNS_R_DNAME:
                return (query_dname(qctx));
 
+       case DNS_R_FORMERR:
+               QUERY_ERROR(qctx, DNS_R_SERVFAIL);
+               return (query_done(qctx));
+
        default:
                /*
                 * Something has gone wrong.