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.
This commit is contained in:
Mark Andrews
2023-10-19 14:38:59 +11:00
parent aacea440c3
commit 84fd3e3808
5 changed files with 112 additions and 12 deletions

View 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

View File

@@ -70,6 +70,16 @@
#
# 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);
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

View File

@@ -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

View File

@@ -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

View File

@@ -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