LocalPort => $localport, Proto => "udp", Reuse => 1) or die "$!";
#
-# Delegation
+# Delegations
#
my $SOA = "example 300 IN SOA . . 0 0 0 0 300";
my $NS = "example 300 IN NS ns.example";
my $A = "ns.example 300 IN A $localaddr";
+my $ssSOA = "delegated.serve.stale 300 IN SOA . . 0 0 0 0 300";
+my $ssNS = "delegated.serve.stale 300 IN NS ns.delegated.serve.stale";
+my $ssA = "ns.delegated.serve.stale 300 IN A $localaddr";
#
# Slow delegation
my $LONGTXT = "longttl.example 600 IN TXT \"A text record with a 600 second ttl\"";
my $CAA = "othertype.example 2 IN CAA 0 issue \"ca1.example.net\"";
my $negSOA = "example 2 IN SOA . . 0 0 0 0 300";
+my $ssnegSOA = "delegated.serve.stale 2 IN SOA . . 0 0 0 0 300";
my $CNAME = "cname.example 7 IN CNAME target.example";
my $TARGET = "target.example 9 IN A $localaddr";
my $SHORTCNAME = "shortttl.cname.example 1 IN CNAME longttl.target.example";
push @auth, $rr;
}
$rcode = "NOERROR";
+ } elsif ($qname eq "ns.delegated.serve.stale" ) {
+ if ($qtype eq "A") {
+ my $rr = new Net::DNS::RR($ssA);
+ push @ans, $rr;
+ } else {
+ my $rr = new Net::DNS::RR($ssSOA);
+ push @auth, $rr;
+ }
+ $rcode = "NOERROR";
+ } elsif ($qname eq "delegated.serve.stale") {
+ if ($qtype eq "NS") {
+ my $rr = new Net::DNS::RR($ssNS);
+ push @auth, $rr;
+ $rr = new Net::DNS::RR($ssA);
+ push @add, $rr;
+ } elsif ($qtype eq "SOA") {
+ my $rr = new Net::DNS::RR($ssSOA);
+ push @ans, $rr;
+ } else {
+ my $rr = new Net::DNS::RR($ssSOA);
+ push @auth, $rr;
+ }
+ $rcode = "NOERROR";
+ } elsif ($qname eq "www.delegated.serve.stale") {
+ if ($qtype eq "A") {
+ my $rr = new Net::DNS::RR("www.delegated.serve.stale 2 IN A 10.53.0.99");
+ push @ans, $rr;
+ } else {
+ my $rr = new Net::DNS::RR($ssnegSOA);
+ push @auth, $rr;
+ }
+ $rcode = "NOERROR";
} elsif ($qname eq "ns.slow" ) {
if ($qtype eq "A") {
my $rr = new Net::DNS::RR($slowA);
--- /dev/null
+/*
+ * 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.
+ */
+
+key rndc_key {
+ secret "1234abcd8765";
+ algorithm @DEFAULT_HMAC@;
+};
+
+controls {
+ inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; };
+};
+
+options {
+ query-source address 10.53.0.3;
+ notify-source 10.53.0.3;
+ transfer-source 10.53.0.3;
+ port @PORT@;
+ pid-file "named.pid";
+ listen-on { 10.53.0.3; };
+ listen-on-v6 { none; };
+ recursion yes;
+ dnssec-validation no;
+ stale-answer-enable yes;
+ stale-cache-enable yes;
+ stale-answer-ttl 3;
+ stale-answer-client-timeout 0;
+};
+
+zone "." {
+ type secondary;
+ primaries { 10.53.0.1; };
+ file "root.bk";
+};
+
+zone "serve.stale" IN {
+ type primary;
+ notify no;
+ file "serve.stale.db";
+};
$ORIGIN serve.stale.
test IN NS nss1.example.nxd.
test IN NS nss2.example.nxd.
+
+delegated IN NS ns2.delegated.serve.stale.
+ns2.delegated IN A 10.53.0.2
if [ $ret != 0 ]; then echo_i "failed"; fi
status=$((status + ret))
+n=$((n + 1))
+echo_i "check serve-stale (stale-answer-client-timeout 0) with a delegation ($n)"
+ret=0
+# configure ns3 with stale-answer-client-timeout 0 and a delegated zone
+copy_setports ns3/named9.conf.in ns3/named.conf
+rndc_reload ns3 10.53.0.3
+# flush cache, enable ans2 responses, make sure serve-stale is on
+$RNDCCMD 10.53.0.3 flush >rndc.out.test$n.1 2>&1 || ret=1
+$DIG -p ${PORT} @10.53.0.2 txt enable >/dev/null || ret=1
+$RNDCCMD 10.53.0.3 serve-stale on >rndc.out.test$n.2 2>&1 || ret=1
+# prime the cache with the A response
+$DIG -p ${PORT} @10.53.0.3 www.delegated.serve.stale >dig.out.1.test$n || ret=1
+grep -F "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
+grep -F "10.53.0.99" dig.out.1.test$n >/dev/null || ret=1
+# disable responses from the auth server
+$DIG -p ${PORT} @10.53.0.2 txt disable >/dev/null || ret=1
+# wait two seconds for the previous answer to become stale
+sleep 2
+# resend the query; we should immediately get a stale answer
+$DIG -p ${PORT} @10.53.0.3 www.delegated.serve.stale >dig.out.2.test$n || ret=1
+grep -F "status: NOERROR" dig.out.2.test$n >/dev/null || ret=1
+grep -F "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.2.test$n >/dev/null || ret=1
+grep -F "10.53.0.99" dig.out.2.test$n >/dev/null || ret=1
+# re-enable responses
+$DIG -p ${PORT} @10.53.0.2 txt enable >/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