diff --git a/bin/tests/system/resolver/ans2/ans.pl b/bin/tests/system/resolver/ans2/ans.pl index 94f645151f..aa1d51b57a 100644 --- a/bin/tests/system/resolver/ans2/ans.pl +++ b/bin/tests/system/resolver/ans2/ans.pl @@ -73,6 +73,15 @@ for (;;) { # Data for the "cname + other data / 2" test: same RRs in opposite order $packet->push("answer", new Net::DNS::RR("cname2.example.com 300 A 1.2.3.4")); $packet->push("answer", new Net::DNS::RR("cname2.example.com 300 CNAME cname2.example.com")); + } elsif ($qname =~ /redirect\.com/) { + $packet->push("authority", new Net::DNS::RR("redirect.com 300 NS ns.redirect.com")); + $packet->push("additional", new Net::DNS::RR("ns.redirect.com 300 A 10.53.0.6")); + } elsif ($qname =~ /\.tld1/) { + $packet->push("authority", new Net::DNS::RR("tld1 300 NS ns.tld1")); + $packet->push("additional", new Net::DNS::RR("ns.tld1 300 A 10.53.0.6")); + } elsif ($qname =~ /\.tld2/) { + $packet->push("authority", new Net::DNS::RR("tld2 300 NS ns.tld2")); + $packet->push("additional", new Net::DNS::RR("ns.tld2 300 A 10.53.0.7")); } elsif ($qname eq "org" && $qtype eq "NS") { $packet->header->aa(1); $packet->push("answer", new Net::DNS::RR("org 300 NS a.root-servers.nil.")); diff --git a/bin/tests/system/resolver/ans3/ans.pl b/bin/tests/system/resolver/ans3/ans.pl index dbd10d944d..893c9ed8d5 100644 --- a/bin/tests/system/resolver/ans3/ans.pl +++ b/bin/tests/system/resolver/ans3/ans.pl @@ -20,11 +20,21 @@ use IO::Socket; use Net::DNS; use Net::DNS::Packet; +# Ignore SIGPIPE so we won't fail if peer closes a TCP socket early +local $SIG{PIPE} = 'IGNORE'; + +# Flush logged output after every line +local $| = 1; + my $localport = int($ENV{'PORT'}); if (!$localport) { $localport = 5300; } -my $sock = IO::Socket::INET->new(LocalAddr => "10.53.0.3", - LocalPort => $localport, Proto => "udp") or die "$!"; +my $server_addr = "10.53.0.3"; + +my $udpsock = IO::Socket::INET->new(LocalAddr => "$server_addr", + LocalPort => $localport, Proto => "udp", Reuse => 1) or die "$!"; +my $tcpsock = IO::Socket::INET->new(LocalAddr => "$server_addr", + LocalPort => $localport, Proto => "tcp", Listen => 5, Reuse => 1) or die "$!"; my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!"; print $pidf "$$\n" or die "cannot write pid file: $!"; @@ -34,11 +44,8 @@ sub rmpid { unlink "ans.pid"; exit 1; }; $SIG{INT} = \&rmpid; $SIG{TERM} = \&rmpid; -for (;;) { - $sock->recv($buf, 512); - - print "**** request from " , $sock->peerhost, " port ", $sock->peerport, "\n"; - +sub handleQuery { + my $buf = shift; my $packet; if ($Net::DNS::VERSION > 0.68) { @@ -105,6 +112,13 @@ for (;;) { $packet->header->aa(0); $packet->push("authority", new Net::DNS::RR("lame.example.org 300 NS ns.lame.example.org")); $packet->push("additional", new Net::DNS::RR("ns.lame.example.org 300 A 10.53.0.3")); + } elsif ($qname eq "large-referral.example.net") { + for (my $i = 1; $i < 1000; $i++) { + $packet->push("authority", new Net::DNS::RR("large-referral.example.net 300 NS ns" . $i . ".fake.redirect.com")); + } + # No glue records + } elsif ($qname eq "foo.bar.sub.tld1") { + $packet->push("answer", new Net::DNS::RR("$qname 300 TXT baz")); } elsif ($qname eq "cname.sub.example.org") { $packet->push("answer", new Net::DNS::RR($qname . @@ -132,9 +146,46 @@ for (;;) { $packet->push("answer", new Net::DNS::RR("www.example.com 300 A 1.2.3.4")); } - $sock->send($packet->data); - print "RESPONSE:\n"; $packet->print; - print "\n"; + + return $packet->data; +} + +# Main +my $rin; +my $rout; +for (;;) { + $rin = ''; + vec($rin, fileno($tcpsock), 1) = 1; + vec($rin, fileno($udpsock), 1) = 1; + + select($rout = $rin, undef, undef, undef); + + if (vec($rout, fileno($udpsock), 1)) { + printf "UDP request\n"; + my $buf; + $udpsock->recv($buf, 512); + my $result = handleQuery($buf); + my $num_chars = $udpsock->send($result); + print " Sent $num_chars bytes via UDP\n"; + } elsif (vec($rout, fileno($tcpsock), 1)) { + my $conn = $tcpsock->accept; + my $buf; + for (;;) { + my $lenbuf; + my $n = $conn->sysread($lenbuf, 2); + last unless $n == 2; + my $len = unpack("n", $lenbuf); + $n = $conn->sysread($buf, $len); + last unless $n == $len; + print "TCP request\n"; + my $result = handleQuery($buf); + $len = length($result); + $conn->syswrite(pack("n", $len), 2); + $n = $conn->syswrite($result, $len); + print " Sent: $n chars via TCP\n"; + } + $conn->close; + } } diff --git a/bin/tests/system/resolver/ns1/named.conf.in b/bin/tests/system/resolver/ns1/named.conf.in index 89625f8139..7ca1cafd38 100644 --- a/bin/tests/system/resolver/ns1/named.conf.in +++ b/bin/tests/system/resolver/ns1/named.conf.in @@ -31,6 +31,10 @@ options { attach-cache "globalcache"; }; +server 10.53.0.3 { + tcp-only yes; +}; + server 10.42.23.3/32 { notify-source 10.42.22.1; query-source address 10.42.22.1 port 0; @@ -64,3 +68,12 @@ view "default" { file "root.hint"; }; }; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff --git a/bin/tests/system/resolver/ns6/named.conf.in b/bin/tests/system/resolver/ns6/named.conf.in index 4f9145923b..a069e00a49 100644 --- a/bin/tests/system/resolver/ns6/named.conf.in +++ b/bin/tests/system/resolver/ns6/named.conf.in @@ -62,6 +62,16 @@ zone "broken" { allow-update { any; }; }; +zone "redirect.com" { + type primary; + file "redirect.com.db"; +}; + +zone "tld1" { + type primary; + file "tld1.db"; +}; + zone "no-edns-version.tld" { type primary; file "no-edns-version.tld.db"; diff --git a/bin/tests/system/resolver/ns6/redirect.com.db b/bin/tests/system/resolver/ns6/redirect.com.db new file mode 100644 index 0000000000..f79f6dd0a8 --- /dev/null +++ b/bin/tests/system/resolver/ns6/redirect.com.db @@ -0,0 +1,27 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; SPDX-License-Identifier: MPL-2.0 +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, you can obtain one at https://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 600 +@ IN SOA ns hostmaster 1 1800 900 604800 600 +@ IN NS ns +ns IN A 10.53.0.6 + +; 10.53.1.* are non-responsive IP addresses +$GENERATE 1-100 ns$.fake IN A 10.53.1.$ +$GENERATE 101-200 ns$.fake IN A 10.53.1.${-100} +$GENERATE 201-300 ns$.fake IN A 10.53.1.${-200} +$GENERATE 301-400 ns$.fake IN A 10.53.1.${-300} +$GENERATE 401-500 ns$.fake IN A 10.53.1.${-400} +$GENERATE 501-600 ns$.fake IN A 10.53.1.${-500} +$GENERATE 601-700 ns$.fake IN A 10.53.1.${-600} +$GENERATE 701-800 ns$.fake IN A 10.53.1.${-700} +$GENERATE 801-900 ns$.fake IN A 10.53.1.${-800} +$GENERATE 901-1000 ns$.fake IN A 10.53.1.${-900} diff --git a/bin/tests/system/resolver/ns6/tld1.db b/bin/tests/system/resolver/ns6/tld1.db new file mode 100644 index 0000000000..412509b3c5 --- /dev/null +++ b/bin/tests/system/resolver/ns6/tld1.db @@ -0,0 +1,17 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; SPDX-License-Identifier: MPL-2.0 +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, you can obtain one at https://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 600 +@ IN SOA ns hostmaster 1 1800 900 604800 600 +@ IN NS ns +ns IN A 10.53.0.6 + +$GENERATE 1-21 sub IN NS sub-ns$.tld2. diff --git a/bin/tests/system/resolver/ns7/named1.conf.in b/bin/tests/system/resolver/ns7/named1.conf.in index 7af5345f8f..2d6cc842ab 100644 --- a/bin/tests/system/resolver/ns7/named1.conf.in +++ b/bin/tests/system/resolver/ns7/named1.conf.in @@ -63,3 +63,13 @@ zone "all-cnames" { type primary; file "all-cnames.db"; }; + +zone "tld2" { + type primary; + file "tld2.db"; +}; + +zone "sub.tld1" { + type primary; + file "sub.tld1.db"; +}; diff --git a/bin/tests/system/resolver/ns7/named2.conf.in b/bin/tests/system/resolver/ns7/named2.conf.in index 7af5345f8f..2d6cc842ab 100644 --- a/bin/tests/system/resolver/ns7/named2.conf.in +++ b/bin/tests/system/resolver/ns7/named2.conf.in @@ -63,3 +63,13 @@ zone "all-cnames" { type primary; file "all-cnames.db"; }; + +zone "tld2" { + type primary; + file "tld2.db"; +}; + +zone "sub.tld1" { + type primary; + file "sub.tld1.db"; +}; diff --git a/bin/tests/system/resolver/ns7/sub.tld1.db b/bin/tests/system/resolver/ns7/sub.tld1.db new file mode 100644 index 0000000000..b2d46c6a87 --- /dev/null +++ b/bin/tests/system/resolver/ns7/sub.tld1.db @@ -0,0 +1,17 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; SPDX-License-Identifier: MPL-2.0 +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, you can obtain one at https://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 600 +@ IN SOA ns hostmaster 1 1800 900 604800 600 + +$GENERATE 1-21 @ IN NS sub-ns$.tld2. + +$GENERATE 1-21 bar IN NS bar-sub-ns$.tld2. diff --git a/bin/tests/system/resolver/ns7/tld2.db b/bin/tests/system/resolver/ns7/tld2.db new file mode 100644 index 0000000000..1f31b51c6c --- /dev/null +++ b/bin/tests/system/resolver/ns7/tld2.db @@ -0,0 +1,18 @@ +; Copyright (C) Internet Systems Consortium, Inc. ("ISC") +; +; SPDX-License-Identifier: MPL-2.0 +; +; This Source Code Form is subject to the terms of the Mozilla Public +; License, v. 2.0. If a copy of the MPL was not distributed with this +; file, you can obtain one at https://mozilla.org/MPL/2.0/. +; +; See the COPYRIGHT file distributed with this work for additional +; information regarding copyright ownership. + +$TTL 600 +@ IN SOA ns hostmaster 1 1800 900 604800 600 +@ IN NS ns +ns IN A 10.53.0.7 + +$GENERATE 1-21 sub-ns$ IN A 10.53.0.7 +$GENERATE 1-21 bar-sub-ns$ IN A 10.53.0.3 diff --git a/bin/tests/system/resolver/tests.sh b/bin/tests/system/resolver/tests.sh index 6f50c08b8a..3862db6492 100755 --- a/bin/tests/system/resolver/tests.sh +++ b/bin/tests/system/resolver/tests.sh @@ -812,5 +812,36 @@ grep "status: SERVFAIL" dig.out.ns1.${n} > /dev/null || ret=1 if [ $ret != 0 ]; then echo_i "failed"; fi status=$((status + ret)) +n=$((n+1)) +echo_i "check handling of large referrals to unresponsive name servers ($n)" +ret=0 +dig_with_opts +timeout=15 large-referral.example.net @10.53.0.1 a > dig.out.ns1.test${n} || ret=1 +grep "status: SERVFAIL" dig.out.ns1.test${n} > /dev/null || ret=1 +# Check the total number of findname() calls triggered by a single query +# for large-referral.example.net/A. +findname_call_count="$(grep -c "large-referral\.example\.net.*FINDNAME" ns1/named.run)" +if [ "${findname_call_count}" -gt 1000 ]; then + echo_i "failed: ${findname_call_count} (> 1000) findname() calls detected for large-referral.example.net" + ret=1 +fi +# Check whether the limit of NS RRs processed for any delegation +# encountered was not exceeded. +if grep -Eq "dns_adb_createfind: started (A|AAAA) fetch for name ns21.fake.redirect.com" ns1/named.run; then + echo_i "failed: unexpected address fetch(es) were triggered for ns21.fake.redirect.com" + ret=1 +fi +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + +n=$((n+1)) +echo_i "checking query resolution for a domain with a valid glueless delegation chain ($n)" +ret=0 +rndccmd 10.53.0.1 flush || ret=1 +dig_with_opts foo.bar.sub.tld1 @10.53.0.1 TXT > dig.out.ns1.test${n} || ret=1 +grep "status: NOERROR" dig.out.ns1.test${n} > /dev/null || ret=1 +grep "IN.*TXT.*baz" dig.out.ns1.test${n} > /dev/null || ret=1 +if [ $ret != 0 ]; then echo_i "failed"; fi +status=$((status + ret)) + echo_i "exit status: $status" [ $status -eq 0 ] || exit 1