From: Mark Andrews Date: Thu, 19 Oct 2023 03:38:59 +0000 (+1100) Subject: Test xfrin's handing of EDNS failure scenarios X-Git-Tag: v9.19.18~30^2~1 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=84fd3e38085ab589d791ab22ca4ef2138150e4c4;p=thirdparty%2Fbind9.git Test xfrin's handing of EDNS failure scenarios 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. --- diff --git a/.reuse/dep5 b/.reuse/dep5 index 4cf9906f81f..d90b537d9e5 100644 --- a/.reuse/dep5 +++ b/.reuse/dep5 @@ -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 diff --git a/bin/tests/system/ans.pl b/bin/tests/system/ans.pl index 946d2ae01fe..bfd36bc0f17 100644 --- a/bin/tests/system/ans.pl +++ b/bin/tests/system/ans.pl @@ -70,6 +70,16 @@ # # Return a NOTIMP response # +# /pattern EDNS=NOTIMP / +# /pattern EDNS=NOTIMP/ +# +# Return a NOTIMP response to an EDNS request +# +# /pattern EDNS=FORMERR / +# /pattern EDNS=FORMERR/ +# +# Return a FORMERR response to an EDNS request +# # /pattern bad-id / # /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 index 00000000000..6ea77bef784 --- /dev/null +++ b/bin/tests/system/xfer/ans5/ednsformerr @@ -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 index 00000000000..a1df16b4069 --- /dev/null +++ b/bin/tests/system/xfer/ans5/ednsnotimp @@ -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 diff --git a/bin/tests/system/xfer/tests.sh b/bin/tests/system/xfer/tests.sh index f6984fd4234..8a691b613ff 100755 --- a/bin/tests/system/xfer/tests.sh +++ b/bin/tests/system/xfer/tests.sh @@ -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