From 84fd3e38085ab589d791ab22ca4ef2138150e4c4 Mon Sep 17 00:00:00 2001 From: Mark Andrews Date: Thu, 19 Oct 2023 14:38:59 +1100 Subject: [PATCH] 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. --- .reuse/dep5 | 2 + bin/tests/system/ans.pl | 68 +++++++++++++++++++++----- bin/tests/system/xfer/ans5/ednsformerr | 10 ++++ bin/tests/system/xfer/ans5/ednsnotimp | 12 +++++ bin/tests/system/xfer/tests.sh | 32 ++++++++++++ 5 files changed, 112 insertions(+), 12 deletions(-) create mode 100644 bin/tests/system/xfer/ans5/ednsformerr create mode 100644 bin/tests/system/xfer/ans5/ednsnotimp diff --git a/.reuse/dep5 b/.reuse/dep5 index 4cf9906f81..d90b537d9e 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 946d2ae01f..bfd36bc0f1 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); + + 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 "NOTIMP") { - $packet->header->rcode('NOTIMP'); - $key_name = $key_data; - ($key_data, $tname) = split(/ /,$tname); - $done = 1; - } - 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 0000000000..6ea77bef78 --- /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 0000000000..a1df16b406 --- /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 f6984fd423..8a691b613f 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