]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add test for serve-stale /w fetch-limits
authorMatthijs Mekking <matthijs@isc.org>
Thu, 28 Jan 2021 11:30:08 +0000 (12:30 +0100)
committerMatthijs Mekking <matthijs@isc.org>
Thu, 28 Jan 2021 15:39:30 +0000 (16:39 +0100)
Add a test case when fetch-limits are reached and we have stale data
in cache.

This test starts with a positive answer for 'data.example/TXT' in
cache.

1. Reload named.conf to set fetch limits.
2. Disable responses from the authoritative server.
3. Now send a batch of queries to the resolver, until hitting the
   fetch limits. We can detect this by looking at the response RCODE,
   at some point we will see SERVFAIL responses.
4. At that point we will turn on serve-stale.
5. Clients should see stale answers now.
6. An incoming query should not set the stale-refresh-time window,
   so a following query should still get a stale answer because of a
   resolver failure (and not because it was in the stale-refresh-time
   window).

bin/tests/system/serve-stale/ans2/ans.pl
bin/tests/system/serve-stale/ns3/named6.conf.in [new file with mode: 0644]
bin/tests/system/serve-stale/tests.sh

index 8be8392f28912484cb5c081658f54ae53f5dbf09..4bb9f896ffe10bfa4608b4fbde420d82a352aed5 100644 (file)
@@ -145,7 +145,7 @@ sub reply_handler {
        $rcode = "NXDOMAIN";
     }
 
-    # mark the answer as authoritative (by setting the 'aa' flag
+    # mark the answer as authoritative (by setting the 'aa' flag)
     return ($rcode, \@ans, \@auth, \@add, { aa => 1 });
 }
 
diff --git a/bin/tests/system/serve-stale/ns3/named6.conf.in b/bin/tests/system/serve-stale/ns3/named6.conf.in
new file mode 100644 (file)
index 0000000..1aea7c8
--- /dev/null
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
+ *
+ * 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 http://mozilla.org/MPL/2.0/.
+ *
+ * See the COPYRIGHT file distributed with this work for additional
+ * information regarding copyright ownership.
+ */
+
+
+/*
+ * Test stale-answer-client-timeout 0.
+ */
+
+key rndc_key {
+       secret "1234abcd8765";
+       algorithm hmac-sha256;
+};
+
+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; };
+       dnssec-validation no;
+       recursion yes;
+       stale-answer-enable no;
+       stale-cache-enable yes;
+       stale-answer-ttl 3;
+       stale-answer-client-timeout disabled;
+       stale-refresh-time 4;
+       resolver-query-timeout 10;
+       fetches-per-zone 1 fail;
+       fetches-per-server 1 fail;
+       max-stale-ttl 3600;
+};
+
+zone "." {
+       type hint;
+       file "root.db";
+};
index 92263d86dff617df45bf4ae7821ef6f2189b149c..47a117308e7c378bbd0fb4caeeba6ab40f3b5d1a 100755 (executable)
@@ -2010,5 +2010,104 @@ grep "data\.example\..*[12].*IN.*TXT.*A text record with a 2 second ttl" dig.out
 if [ $ret != 0 ]; then echo_i "failed"; fi
 status=$((status+ret))
 
+####################################################################
+# Test if fetch-limits quota is reached, stale data is served.     #
+####################################################################
+echo_i "test stale data with fetch-limits"
+
+n=$((n+1))
+echo_i "updating ns3/named.conf ($n)"
+ret=0
+copy_setports ns3/named6.conf.in ns3/named.conf
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "running 'rndc reload' ($n)"
+ret=0
+rndc_reload ns3 10.53.0.3
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+# Disable responses from authoritative server.
+n=$((n+1))
+echo_i "disable responses from authoritative server ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.2 txt disable  > dig.out.test$n
+grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
+grep "TXT.\"0\"" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+# Hit the fetch-limits.
+burst() {
+       num=${1}
+       rm -f burst.input.$$
+       while [ $num -gt 0 ]; do
+               num=`expr $num - 1`
+               echo "${num}.data.example A" >> burst.input.$$
+       done
+       $PERL ../ditch.pl -p ${PORT} -s 10.53.0.3 burst.input.$$
+       rm -f burst.input.$$
+}
+
+wait_for_fetchlimits() {
+       burst 20
+       $DIG -p ${PORT} @10.53.0.3 data.example A > dig.out.test$n
+       grep "status: SERVFAIL" dig.out.test$n > /dev/null || return 1
+}
+
+n=$((n+1))
+echo_i "hit fetch limits ($n)"
+ret=0
+retry_quiet 10 wait_for_fetchlimits || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+# Allow RRset to become stale.
+sleep 2
+
+# Turn on serve-stale.
+n=$((n+1))
+echo_i "running 'rndc serve-stale on' ($n)"
+ret=0
+$RNDCCMD 10.53.0.3 serve-stale on || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+n=$((n+1))
+echo_i "check 'rndc serve-stale status' ($n)"
+ret=0
+$RNDCCMD 10.53.0.3 serve-stale status > rndc.out.test$n 2>&1 || ret=1
+grep '_default: on (rndc) (stale-answer-ttl=3 max-stale-ttl=3600 stale-refresh-time=4)' rndc.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+# Expect stale data now.
+n=$((n+1))
+ret=0
+echo_i "check stale data.example comes from cache (fetch-limits) ($n)"
+nextpart ns3/named.run > /dev/null
+$DIG -p ${PORT} @10.53.0.3 data.example TXT > dig.out.test$n
+wait_for_log 5 "data.example resolver failure, stale answer used" ns3/named.run || ret=1
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
+grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n > /dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status+ret))
+
+# The previous query should not have started the stale-refresh-time window.
+n=$((n+1))
+ret=0
+echo_i "check stale data.example comes from cache again (fetch-limits) ($n)"
+nextpart ns3/named.run > /dev/null
+$DIG -p ${PORT} @10.53.0.3 data.example TXT > dig.out.test$n
+wait_for_log 5 "data.example resolver failure, stale answer used" ns3/named.run || ret=1
+grep "status: NOERROR" dig.out.test$n > /dev/null || ret=1
+grep "ANSWER: 1," dig.out.test$n > /dev/null || ret=1
+grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.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