]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Add reproducer as test case
authorMatthijs Mekking <matthijs@isc.org>
Thu, 10 Jul 2025 12:47:06 +0000 (14:47 +0200)
committerMatthijs Mekking <matthijs@isc.org>
Wed, 23 Jul 2025 07:18:48 +0000 (07:18 +0000)
The issue provided a reproducer that can be easily converted into a
test case.

bin/tests/system/serve-stale/ns1/stale.test.db
bin/tests/system/serve-stale/tests.sh

index d389e7c6a6c43c1686bf73bba840fa9325017845..128fb25a105e2776d6585c4b9ef09b7370d26a4f 100644 (file)
@@ -17,3 +17,11 @@ cname1.stale.test.   1       CNAME   a1.stale.test.
 a1.stale.test.         1       A       192.0.2.1
 cname2.stale.test.     1       CNAME   a2.stale.test.
 a2.stale.test.         300     A       192.0.2.2
+
+cname-a1               1       CNAME   cname-a2
+cname-a2               300     CNAME   cname-a3
+cname-a3               300     A       192.0.2.1
+
+cname-b1               300     CNAME   cname-b2
+cname-b2               1       CNAME   cname-b3
+cname-b3               1       A       192.0.2.2
index 73aa288d3a2ca84e12740a286d89d966e7902a4e..eea4ef7142e6b821b49ba2d5ffda53f117d3ddb3 100755 (executable)
@@ -2097,6 +2097,73 @@ if [ $ret != 0 ]; then
 fi
 status=$((status + ret))
 
+# New CNAME scenario (GL #5243)
+n=$((n + 1))
+echo_i "prime cache cname-a1.stale.test A (stale-answer-client-timeout 0) ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.3 cname-a1.stale.test A >dig.out.test$n || ret=1
+grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
+grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1
+grep "cname-a1\.stale\.test\..*1.*IN.*CNAME.*cname-a2\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-a2\.stale\.test\..*300.*IN.*CNAME.*cname-a3\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-a3\.stale\.test\..*300.*IN.*A.*192\.0\.2\.1" dig.out.test$n >/dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+
+n=$((n + 1))
+echo_i "prime cache cname-b1.stale.test A (stale-answer-client-timeout 0) ($n)"
+ret=0
+$DIG -p ${PORT} @10.53.0.3 cname-b1.stale.test A >dig.out.test$n || ret=1
+grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
+grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1
+grep "cname-b1\.stale\.test\..*300.*IN.*CNAME.*cname-b2\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-b2\.stale\.test\..*1.*IN.*CNAME.*cname-b3\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-b3\.stale\.test\..*1.*IN.*A.*192\.0\.2\.2" dig.out.test$n >/dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+
+# Allow RRset to become stale.
+sleep 1
+
+n=$((n + 1))
+ret=0
+echo_i "check stale cname-a1.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)"
+nextpart ns3/named.run >/dev/null
+$DIG -p ${PORT} @10.53.0.3 cname-a1.stale.test A >dig.out.test$n || ret=1
+wait_for_log 5 "cname-a1.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
+# Other records in chain are still good, so do not attempt a refresh
+grep "cname-a2.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run && ret=1
+grep "cname-a3.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run && ret=1
+# Check answer
+grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
+grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1
+grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1
+grep "cname-a1\.stale\.test\..*3.*IN.*CNAME.*cname-a2\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-a2\.stale\.test\..*29[0-9].*IN.*CNAME.*cname-a3\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-a3\.stale\.test\..*29[0-9].*IN.*A.*192\.0\.2\.1" dig.out.test$n >/dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+
+n=$((n + 1))
+ret=0
+echo_i "check stale cname-b1.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)"
+nextpart ns3/named.run >/dev/null
+$DIG -p ${PORT} @10.53.0.3 cname-b1.stale.test A >dig.out.test$n || ret=1
+wait_for_log 5 "cname-b2.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
+# The next one in the chain (cname-b3.stale.test) is likely not logged because
+# there is already a refresh in progress. And the first record in the chain is
+# still good, so do not attempt a refresh.
+grep "cname-b1.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run && ret=1
+# Check answer
+grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
+grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1
+grep "ANSWER: 3," dig.out.test$n >/dev/null || ret=1
+grep "cname-b1\.stale\.test\..*29[0-9].*IN.*CNAME.*cname-b2\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-b2\.stale\.test\..*3.*IN.*CNAME.*cname-b3\.stale\.test\." dig.out.test$n >/dev/null || ret=1
+grep "cname-b3\.stale\.test\..*3.*IN.*A.*192\.0\.2\.2" dig.out.test$n >/dev/null || ret=1
+if [ $ret != 0 ]; then echo_i "failed"; fi
+status=$((status + ret))
+
 ####################################################################
 # Test for stale-answer-client-timeout 0 and stale-refresh-time 4. #
 ####################################################################