]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Test xfrin's handing of EDNS failure scenarios
authorMark Andrews <marka@isc.org>
Thu, 19 Oct 2023 03:38:59 +0000 (14:38 +1100)
committerMark Andrews <marka@isc.org>
Fri, 20 Oct 2023 07:16:25 +0000 (18:16 +1100)
We test EDNS requests returning FORMERR where named is expected
to retry without EDNS.

We test EDNS requests returning NOTIMP where named is expected
to fail the transfer as the remote end is not protocol compliant.

.reuse/dep5
bin/tests/system/ans.pl
bin/tests/system/xfer/ans5/ednsformerr [new file with mode: 0644]
bin/tests/system/xfer/ans5/ednsnotimp [new file with mode: 0644]
bin/tests/system/xfer/tests.sh

index 4cf9906f81f498df87706bc293e593f6a83a37b9..d90b537d9e5d267385476c14065692f18b26160d 100644 (file)
@@ -81,6 +81,8 @@ Files: **/*.after*
        bin/tests/system/unknown/large.out
        bin/tests/system/xfer/ans5/badkeydata
        bin/tests/system/xfer/ans5/badmessageid
+       bin/tests/system/xfer/ans5/ednsformerr
+       bin/tests/system/xfer/ans5/ednsnotimp
        bin/tests/system/xfer/ans5/goodaxfr
        bin/tests/system/xfer/ans5/ixfrnotimp
        bin/tests/system/xfer/ans5/partial
index 946d2ae01febc919631b65a2d7e9a5a53cdb5298..bfd36bc0f17748e97d91a750bd39ec9fb6462c8e 100644 (file)
 #
 # Return a NOTIMP response
 #
+# /pattern EDNS=NOTIMP <key> <key_data>/
+# /pattern EDNS=NOTIMP/
+#
+# Return a NOTIMP response to an EDNS request
+#
+# /pattern EDNS=FORMERR <key> <key_data>/
+# /pattern EDNS=FORMERR/
+#
+# Return a FORMERR response to an EDNS request
+#
 # /pattern bad-id <key> <key_data>/
 # /pattern bad-id/
 #
@@ -350,6 +360,11 @@ sub handleTCP {
        my $qtype = $questions[0]->qtype;
        my $qclass = $questions[0]->qclass;
        my $id = $request->header->id;
+       my @additional = $request->additional;
+       my $has_opt = 0;
+       foreach (@additional) {
+               $has_opt = 1 if (ref($_) eq 'Net::DNS::RR::OPT');
+       }
 
        my $opaque;
 
@@ -382,20 +397,49 @@ sub handleTCP {
                        $count_these++;
                        my $a;
                        my $done = 0;
-                       foreach $a (@{$r->{answer}}) {
-                               $packet->push("answer", $a);
-                       }
-                       if (defined($key_name) && $key_name eq "NOTIMP") {
-                               $packet->header->rcode('NOTIMP');
-                               $key_name = $key_data;
-                               ($key_data, $tname) = split(/ /,$tname);
-                               $done = 1;
+
+                       while (defined($key_name) &&
+                              ($key_name eq "NOTIMP" || $key_name eq "EDNS=NOTIMP" ||
+                               $key_name eq "EDNS=FORMERR" || $key_name eq "bad-id")) {
+
+                               if (defined($key_name) && $key_name eq "NOTIMP") {
+                                       $packet->header->rcode('NOTIMP') if (!$done);
+                                       $key_name = $key_data;
+                                       ($key_data, $tname) = split(/ /,$tname);
+                                       $done = 1;
+                               }
+
+                               if (defined($key_name) && $key_name eq "EDNS=NOTIMP") {
+                                       if ($has_opt) {
+                                               $packet->header->rcode('NOTIMP') if (!$done);
+                                               $done = 1;
+                                       }
+                                       $key_name = $key_data;
+                                       ($key_data, $tname) = split(/ /,$tname);
+                               }
+
+                               if (defined($key_name) && $key_name eq "EDNS=FORMERR") {
+                                       if ($has_opt) {
+                                               $packet->header->rcode('FORMERR') if (!$done);
+                                               $done = 1;
+                                       }
+                                       $key_name = $key_data;
+                                       ($key_data, $tname) = split(/ /,$tname);
+                               }
+
+                               if (defined($key_name) && $key_name eq "bad-id") {
+                                       $packet->header->id(($id+50)%0xffff);
+                                       $key_name = $key_data;
+                                       ($key_data, $tname) = split(/ /,$tname);
+                               }
                        }
-                       if (defined($key_name) && $key_name eq "bad-id") {
-                               $packet->header->id(($id+50)%0xffff);
-                               $key_name = $key_data;
-                               ($key_data, $tname) = split(/ /,$tname);
+
+                       if (!$done) {
+                               foreach $a (@{$r->{answer}}) {
+                                       $packet->push("answer", $a);
+                               }
                        }
+
                        if (defined($key_name) && defined($key_data)) {
                                my $tsig;
                                # sign the packet
diff --git a/bin/tests/system/xfer/ans5/ednsformerr b/bin/tests/system/xfer/ans5/ednsformerr
new file mode 100644 (file)
index 0000000..6ea77be
--- /dev/null
@@ -0,0 +1,10 @@
+/SOA tsig_key LSAnCU+Z/
+nil.           300     SOA     ns.nil. root.nil. 1 300 300 604800 300
+/AXFR EDNS=FORMERR tsig_key LSAnCU+Z/
+nil.           300     SOA     ns.nil. root.nil. 1 300 300 604800 300
+/AXFR EDNS=FORMERR tsig_key LSAnCU+Z/
+nil.           300     NS      ns.nil.
+nil.           300     TXT     "EDNS FORMERR"
+a.nil.         60      A       10.0.0.61
+/AXFR EDNS=FORMERR tsig_key LSAnCU+Z/
+nil.           300     SOA     ns.nil. root.nil. 1 300 300 604800 300
diff --git a/bin/tests/system/xfer/ans5/ednsnotimp b/bin/tests/system/xfer/ans5/ednsnotimp
new file mode 100644 (file)
index 0000000..a1df16b
--- /dev/null
@@ -0,0 +1,12 @@
+/SOA tsig_key LSAnCU+Z/
+nil.           300     SOA     ns.nil. root.nil. 1 300 300 604800 300
+/AXFR EDNS=NOTIMP tsig_key LSAnCU+Z/
+nil.           300     SOA     ns.nil. root.nil. 1 300 300 604800 300
+/AXFR tsig_key LSAnCU+Z/
+nil.           300     SOA     ns.nil. root.nil. 1 300 300 604800 300
+/AXFR tsig_key LSAnCU+Z/
+nil.           300     NS      ns.nil.
+nil.           300     TXT     "EDNS NOTIMP"
+a.nil.         60      A       10.0.0.61
+/AXFR tsig_key LSAnCU+Z/
+nil.           300     SOA     ns.nil. root.nil. 1 300 300 604800 300
index f6984fd4234c005089726b73f810be969979800b..8a691b613ff3a8209639e1f92a9c44f57f520c02 100755 (executable)
@@ -482,6 +482,38 @@ $DIGCMD nil. TXT | grep 'SOA mismatch AXFR' >/dev/null && {
     status=$((status+1))
 }
 
+n=$((n+1))
+echo_i "handle EDNS NOTIMP ($n)"
+
+$RNDCCMD 10.53.0.4 null testing EDNS NOTIMP | sed 's/^/ns4 /' | cat_i
+
+sendcmd < ans5/ednsnotimp
+
+$RNDCCMD 10.53.0.4 retransfer nil | sed 's/^/ns4 /' | cat_i
+
+sleep 2
+
+nextpart ns4/named.run | grep "Transfer status: NOTIMP" > /dev/null || {
+    echo_i "failed: expected status was not logged"
+    status=$((status+1))
+}
+
+n=$((n+1))
+echo_i "handle EDNS FORMERR ($n)"
+
+$RNDCCMD 10.53.0.4 null testing EDNS FORMERR | sed 's/^/ns4 /' | cat_i
+
+sendcmd < ans5/ednsformerr
+
+$RNDCCMD 10.53.0.4 retransfer nil | sed 's/^/ns4 /' | cat_i
+
+sleep 10
+
+$DIGCMD nil. TXT | grep 'EDNS FORMERR' >/dev/null || {
+    echo_i "failed"
+    status=$((status+1))
+}
+
 n=$((n+1))
 echo_i "check that we ask for and got a EDNS EXPIRE response when transfering from a secondary ($n)"
 tmp=0