Home | History | Annotate | Line # | Download | only in serve-stale
tests.sh revision 1.1.1.14.2.1
      1 #!/bin/sh
      2 
      3 # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
      4 #
      5 # SPDX-License-Identifier: MPL-2.0
      6 #
      7 # This Source Code Form is subject to the terms of the Mozilla Public
      8 # License, v. 2.0.  If a copy of the MPL was not distributed with this
      9 # file, you can obtain one at https://mozilla.org/MPL/2.0/.
     10 #
     11 # See the COPYRIGHT file distributed with this work for additional
     12 # information regarding copyright ownership.
     13 
     14 set -e
     15 
     16 . ../conf.sh
     17 
     18 RNDCCMD="$RNDC -c ../_common/rndc.conf -p ${CONTROLPORT} -s"
     19 DIG="$DIG +time=12 +tries=1"
     20 
     21 max_stale_ttl=$(sed -ne 's,^[[:space:]]*max-stale-ttl \([[:digit:]]*\).*,\1,p' $TOP_SRCDIR/bin/named/config.c)
     22 stale_answer_ttl=$(sed -ne 's,^[[:space:]]*stale-answer-ttl \([[:digit:]]*\).*,\1,p' $TOP_SRCDIR/bin/named/config.c)
     23 
     24 status=0
     25 n=0
     26 
     27 #
     28 # First test server with serve-stale options set.
     29 #
     30 echo_i "test server with serve-stale options set"
     31 
     32 n=$((n + 1))
     33 echo_i "prime cache longttl.example TXT ($n)"
     34 ret=0
     35 $DIG -p ${PORT} @10.53.0.1 longttl.example TXT >dig.out.test$n || ret=1
     36 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
     37 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
     38 if [ $ret != 0 ]; then echo_i "failed"; fi
     39 status=$((status + ret))
     40 
     41 n=$((n + 1))
     42 echo_i "prime cache data.example TXT ($n)"
     43 ret=0
     44 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$n || ret=1
     45 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
     46 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
     47 if [ $ret != 0 ]; then echo_i "failed"; fi
     48 status=$((status + ret))
     49 
     50 n=$((n + 1))
     51 echo_i "prime cache othertype.example CAA ($n)"
     52 ret=0
     53 $DIG -p ${PORT} @10.53.0.1 othertype.example CAA >dig.out.test$n || ret=1
     54 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
     55 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
     56 if [ $ret != 0 ]; then echo_i "failed"; fi
     57 status=$((status + ret))
     58 
     59 n=$((n + 1))
     60 echo_i "prime cache nodata.example TXT ($n)"
     61 ret=0
     62 $DIG -p ${PORT} @10.53.0.1 nodata.example TXT >dig.out.test$n || ret=1
     63 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
     64 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
     65 if [ $ret != 0 ]; then echo_i "failed"; fi
     66 status=$((status + ret))
     67 
     68 n=$((n + 1))
     69 echo_i "prime cache nxdomain.example TXT ($n)"
     70 ret=0
     71 $DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT >dig.out.test$n || ret=1
     72 grep "status: NXDOMAIN" dig.out.test$n >/dev/null || ret=1
     73 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
     74 if [ $ret != 0 ]; then echo_i "failed"; fi
     75 status=$((status + ret))
     76 
     77 n=$((n + 1))
     78 echo_i "verify prime cache statistics ($n)"
     79 ret=0
     80 rm -f ns1/named.stats
     81 $RNDCCMD 10.53.0.1 stats >/dev/null 2>&1
     82 [ -f ns1/named.stats ] || ret=1
     83 cp ns1/named.stats ns1/named.stats.$n
     84 # Check first 10 lines of Cache DB statistics.  After prime queries, we expect
     85 # two active TXT, one active Others, one nxrrset TXT, and one NXDOMAIN.
     86 grep -A 10 "++ Cache DB RRsets ++" ns1/named.stats.$n >ns1/named.stats.$n.cachedb || ret=1
     87 grep "1 Others" ns1/named.stats.$n.cachedb >/dev/null || ret=1
     88 grep "2 TXT" ns1/named.stats.$n.cachedb >/dev/null || ret=1
     89 grep "1 !TXT" ns1/named.stats.$n.cachedb >/dev/null || ret=1
     90 grep "1 NXDOMAIN" ns1/named.stats.$n.cachedb >/dev/null || ret=1
     91 if [ $ret != 0 ]; then echo_i "failed"; fi
     92 status=$((status + ret))
     93 
     94 n=$((n + 1))
     95 echo_i "disable responses from authoritative server ($n)"
     96 ret=0
     97 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
     98 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
     99 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
    100 if [ $ret != 0 ]; then echo_i "failed"; fi
    101 status=$((status + ret))
    102 
    103 n=$((n + 1))
    104 echo_i "check 'rndc serve-stale status' ($n)"
    105 ret=0
    106 $RNDCCMD 10.53.0.1 serve-stale status >rndc.out.test$n 2>&1 || ret=1
    107 grep '_default: stale cache enabled; stale answers enabled (stale-answer-ttl=4 max-stale-ttl=3600 stale-refresh-time=30)' rndc.out.test$n >/dev/null || ret=1
    108 if [ $ret != 0 ]; then echo_i "failed"; fi
    109 status=$((status + ret))
    110 
    111 sleep 2
    112 
    113 # Run rndc dumpdb, test whether the stale data has correct comment printed.
    114 # The max-stale-ttl is 3600 seconds, so the comment should say the data is
    115 # stale for somewhere between 3500-3599 seconds.
    116 echo_i "check rndc dump stale data.example ($n)"
    117 rndc_dumpdb ns1 || ret=1
    118 awk '/; stale since [0-9]*/ { x=$0; getline; print x, $0}' ns1/named_dump.db.test$n \
    119   | grep "; stale since [0-9]* data\.example.*3[56]...*TXT.*A text record with a 2 second ttl" >/dev/null 2>&1 || ret=1
    120 # Also make sure the not expired data does not have a stale comment.
    121 awk '/; authanswer/ { x=$0; getline; print x, $0}' ns1/named_dump.db.test$n \
    122   | grep "; authanswer longttl\.example.*[56]...*TXT.*A text record with a 600 second ttl" >/dev/null 2>&1 || ret=1
    123 if [ $ret != 0 ]; then echo_i "failed"; fi
    124 status=$((status + ret))
    125 
    126 echo_i "sending queries for tests $((n + 1))-$((n + 5))..."
    127 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$((n + 1)) &
    128 $DIG -p ${PORT} @10.53.0.1 longttl.example TXT >dig.out.test$((n + 2)) &
    129 $DIG -p ${PORT} @10.53.0.1 othertype.example CAA >dig.out.test$((n + 3)) &
    130 $DIG -p ${PORT} @10.53.0.1 nodata.example TXT >dig.out.test$((n + 4)) &
    131 $DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT >dig.out.test$((n + 5)) &
    132 
    133 wait
    134 
    135 n=$((n + 1))
    136 echo_i "check stale data.example TXT ($n)"
    137 ret=0
    138 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    139 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    140 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    141 grep "data\.example\..*4.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    142 if [ $ret != 0 ]; then echo_i "failed"; fi
    143 status=$((status + ret))
    144 
    145 n=$((n + 1))
    146 echo_i "check non-stale longttl.example TXT ($n)"
    147 ret=0
    148 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    149 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    150 grep "EDE" dig.out.test$n >/dev/null && ret=1
    151 grep "longttl\.example\..*59[0-9].*IN.*TXT.*A text record with a 600 second ttl" dig.out.test$n >/dev/null || ret=1
    152 if [ $ret != 0 ]; then echo_i "failed"; fi
    153 status=$((status + ret))
    154 
    155 n=$((n + 1))
    156 echo_i "check stale othertype.example CAA ($n)"
    157 ret=0
    158 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    159 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    160 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    161 grep "othertype\.example\..*4.*IN.*CAA.*0.*issue" dig.out.test$n >/dev/null || ret=1
    162 if [ $ret != 0 ]; then echo_i "failed"; fi
    163 status=$((status + ret))
    164 
    165 n=$((n + 1))
    166 echo_i "check stale nodata.example TXT ($n)"
    167 ret=0
    168 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    169 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    170 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    171 grep "example\..*4.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
    172 if [ $ret != 0 ]; then echo_i "failed"; fi
    173 status=$((status + ret))
    174 
    175 n=$((n + 1))
    176 echo_i "check stale nxdomain.example TXT ($n)"
    177 ret=0
    178 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    179 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    180 if [ $ret != 0 ]; then echo_i "failed"; fi
    181 status=$((status + ret))
    182 
    183 n=$((n + 1))
    184 echo_i "verify stale cache statistics ($n)"
    185 ret=0
    186 rm -f ns1/named.stats
    187 $RNDCCMD 10.53.0.1 stats >/dev/null 2>&1
    188 [ -f ns1/named.stats ] || ret=1
    189 cp ns1/named.stats ns1/named.stats.$n
    190 # Check first 10 lines of Cache DB statistics.  After serve-stale queries, we
    191 # expect one active TXT RRset, one stale TXT, one stale nxrrset TXT, and one
    192 # stale NXDOMAIN.
    193 grep -A 10 "++ Cache DB RRsets ++" ns1/named.stats.$n >ns1/named.stats.$n.cachedb || ret=1
    194 grep "1 TXT" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    195 grep "1 #Others" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    196 grep "1 #TXT" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    197 grep "1 #!TXT" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    198 status=$((status + ret))
    199 if [ $ret != 0 ]; then echo_i "failed"; fi
    200 
    201 # Test stale-refresh-time when serve-stale is enabled via configuration.
    202 # Steps for testing stale-refresh-time option (default).
    203 # 1. Prime cache data.example txt
    204 # 2. Disable responses from authoritative server.
    205 # 3. Sleep for TTL duration so rrset TTL expires (2 sec)
    206 # 4. Query data.example
    207 # 5. Check if response come from stale rrset (4 sec TTL)
    208 # 6. Enable responses from authoritative server.
    209 # 7. Query data.example
    210 # 8. Check if response come from stale rrset, since the query
    211 #    is still within stale-refresh-time window.
    212 n=$((n + 1))
    213 echo_i "check 'rndc serve-stale status' ($n)"
    214 ret=0
    215 $RNDCCMD 10.53.0.1 serve-stale status >rndc.out.test$n 2>&1 || ret=1
    216 grep '_default: stale cache enabled; stale answers enabled (stale-answer-ttl=4 max-stale-ttl=3600 stale-refresh-time=30)' rndc.out.test$n >/dev/null || ret=1
    217 if [ $ret != 0 ]; then echo_i "failed"; fi
    218 status=$((status + ret))
    219 
    220 # Step 1-3 done above.
    221 
    222 # Step 4.
    223 n=$((n + 1))
    224 echo_i "sending query for test ($n)"
    225 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$n || ret=1
    226 
    227 # Step 5.
    228 echo_i "check stale data.example TXT (stale-refresh-time) ($n)"
    229 ret=0
    230 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    231 grep "EDE: 3 (Stale Answer): (query within stale refresh time window)" dig.out.test$n >/dev/null || ret=1
    232 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    233 grep "data\.example\..*4.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    234 if [ $ret != 0 ]; then echo_i "failed"; fi
    235 status=$((status + ret))
    236 
    237 # Step 6.
    238 n=$((n + 1))
    239 echo_i "enable responses from authoritative server ($n)"
    240 ret=0
    241 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
    242 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    243 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
    244 if [ $ret != 0 ]; then echo_i "failed"; fi
    245 status=$((status + ret))
    246 
    247 # Step 7.
    248 echo_i "sending query for test $((n + 1))"
    249 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$((n + 1)) || true
    250 
    251 # Step 8.
    252 n=$((n + 1))
    253 echo_i "check stale data.example TXT comes from cache (stale-refresh-time) ($n)"
    254 ret=0
    255 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    256 grep "EDE: 3 (Stale Answer): (query within stale refresh time window)" dig.out.test$n >/dev/null || ret=1
    257 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    258 grep "data\.example\..*4.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    259 if [ $ret != 0 ]; then echo_i "failed"; fi
    260 status=$((status + ret))
    261 
    262 #
    263 # Test interaction with local zone
    264 #
    265 
    266 n=$((n + 1))
    267 echo_i "check that serve-stale does not recurse for local authoritative zone ($n)"
    268 ret=0
    269 
    270 num=0
    271 threshold=10
    272 while [ $num -lt $threshold ]; do
    273 
    274   echo_i "dig test.serve.stale TXT ($n)"
    275   $DIG -p ${PORT} @10.53.0.3 test.serve.stale TXT >dig.out.test$n.$num || ret=1
    276   grep "status: SERVFAIL" dig.out.test$n.$num >/dev/null || ret=1
    277   if [ $ret != 0 ]; then num=$threshold; fi
    278 
    279   sleep 1
    280   num=$((num + 1))
    281 done
    282 if [ $ret != 0 ]; then echo_i "failed"; fi
    283 status=$((status + ret))
    284 
    285 #
    286 # Test disabling serve-stale via rndc.
    287 #
    288 
    289 n=$((n + 1))
    290 echo_i "updating ns1/named.conf ($n)"
    291 ret=0
    292 copy_setports ns1/named2.conf.in ns1/named.conf
    293 if [ $ret != 0 ]; then echo_i "failed"; fi
    294 status=$((status + ret))
    295 
    296 n=$((n + 1))
    297 echo_i "running 'rndc reload' ($n)"
    298 ret=0
    299 rndc_reload ns1 10.53.0.1
    300 if [ $ret != 0 ]; then echo_i "failed"; fi
    301 status=$((status + ret))
    302 
    303 n=$((n + 1))
    304 echo_i "check 'rndc serve-stale status' ($n)"
    305 ret=0
    306 $RNDCCMD 10.53.0.1 serve-stale status >rndc.out.test$n 2>&1 || ret=1
    307 grep '_default: stale cache enabled; stale answers enabled (stale-answer-ttl=4 max-stale-ttl=3600 stale-refresh-time=0)' rndc.out.test$n >/dev/null || ret=1
    308 if [ $ret != 0 ]; then echo_i "failed"; fi
    309 status=$((status + ret))
    310 
    311 n=$((n + 1))
    312 echo_i "disable responses from authoritative server ($n)"
    313 ret=0
    314 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
    315 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    316 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
    317 if [ $ret != 0 ]; then echo_i "failed"; fi
    318 status=$((status + ret))
    319 
    320 n=$((n + 1))
    321 echo_i "running 'rndc serve-stale off' ($n)"
    322 ret=0
    323 $RNDCCMD 10.53.0.1 serve-stale off || ret=1
    324 if [ $ret != 0 ]; then echo_i "failed"; fi
    325 status=$((status + ret))
    326 
    327 n=$((n + 1))
    328 echo_i "check 'rndc serve-stale status' ($n)"
    329 ret=0
    330 $RNDCCMD 10.53.0.1 serve-stale status >rndc.out.test$n 2>&1 || ret=1
    331 grep '_default: stale cache enabled; stale answers disabled (stale-answer-ttl=4 max-stale-ttl=3600 stale-refresh-time=0)' rndc.out.test$n >/dev/null || ret=1
    332 if [ $ret != 0 ]; then echo_i "failed"; fi
    333 status=$((status + ret))
    334 
    335 echo_i "sending queries for tests $((n + 1))-$((n + 4))..."
    336 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$((n + 1)) &
    337 $DIG -p ${PORT} @10.53.0.1 othertype.example CAA >dig.out.test$((n + 2)) &
    338 $DIG -p ${PORT} @10.53.0.1 nodata.example TXT >dig.out.test$((n + 3)) &
    339 $DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT >dig.out.test$((n + 4)) &
    340 
    341 wait
    342 
    343 # no stale answers are used and the authoritative queries timed out. So no EDE 3
    344 # is not sent but EDE 22 is sent.
    345 
    346 n=$((n + 1))
    347 echo_i "check stale data.example TXT (serve-stale off) ($n)"
    348 ret=0
    349 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    350 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
    351 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
    352 if [ $ret != 0 ]; then echo_i "failed"; fi
    353 status=$((status + ret))
    354 
    355 n=$((n + 1))
    356 echo_i "check stale othertype.example CAA (serve-stale off) ($n)"
    357 ret=0
    358 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    359 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
    360 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
    361 if [ $ret != 0 ]; then echo_i "failed"; fi
    362 status=$((status + ret))
    363 
    364 n=$((n + 1))
    365 echo_i "check stale nodata.example TXT (serve-stale off) ($n)"
    366 ret=0
    367 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    368 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
    369 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
    370 if [ $ret != 0 ]; then echo_i "failed"; fi
    371 status=$((status + ret))
    372 
    373 n=$((n + 1))
    374 echo_i "check stale nxdomain.example TXT (serve-stale off) ($n)"
    375 ret=0
    376 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    377 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
    378 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
    379 if [ $ret != 0 ]; then echo_i "failed"; fi
    380 status=$((status + ret))
    381 
    382 #
    383 # Test enabling serve-stale via rndc.
    384 #
    385 n=$((n + 1))
    386 echo_i "running 'rndc serve-stale on' ($n)"
    387 ret=0
    388 $RNDCCMD 10.53.0.1 serve-stale on || ret=1
    389 if [ $ret != 0 ]; then echo_i "failed"; fi
    390 status=$((status + ret))
    391 
    392 n=$((n + 1))
    393 echo_i "check 'rndc serve-stale status' ($n)"
    394 ret=0
    395 $RNDCCMD 10.53.0.1 serve-stale status >rndc.out.test$n 2>&1 || ret=1
    396 grep '_default: stale cache enabled; stale answers enabled (stale-answer-ttl=4 max-stale-ttl=3600 stale-refresh-time=0)' rndc.out.test$n >/dev/null || ret=1
    397 if [ $ret != 0 ]; then echo_i "failed"; fi
    398 status=$((status + ret))
    399 
    400 echo_i "sending queries for tests $((n + 1))-$((n + 4))..."
    401 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$((n + 1)) &
    402 $DIG -p ${PORT} @10.53.0.1 othertype.example CAA >dig.out.test$((n + 2)) &
    403 $DIG -p ${PORT} @10.53.0.1 nodata.example TXT >dig.out.test$((n + 3)) &
    404 $DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT >dig.out.test$((n + 4)) &
    405 
    406 wait
    407 
    408 n=$((n + 1))
    409 echo_i "check stale data.example TXT (serve-stale on) ($n)"
    410 ret=0
    411 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    412 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    413 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    414 grep "data\.example\..*4.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    415 if [ $ret != 0 ]; then echo_i "failed"; fi
    416 status=$((status + ret))
    417 
    418 n=$((n + 1))
    419 echo_i "check stale othertype.example CAA (serve-stale on) ($n)"
    420 ret=0
    421 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    422 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    423 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    424 grep "othertype\.example\..*4.*IN.*CAA.*0.*issue" dig.out.test$n >/dev/null || ret=1
    425 if [ $ret != 0 ]; then echo_i "failed"; fi
    426 status=$((status + ret))
    427 
    428 n=$((n + 1))
    429 echo_i "check stale nodata.example TXT (serve-stale on) ($n)"
    430 ret=0
    431 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    432 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    433 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    434 grep "example\..*4.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
    435 if [ $ret != 0 ]; then echo_i "failed"; fi
    436 status=$((status + ret))
    437 
    438 n=$((n + 1))
    439 echo_i "check stale nxdomain.example TXT (serve-stale on) ($n)"
    440 ret=0
    441 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    442 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    443 if [ $ret != 0 ]; then echo_i "failed"; fi
    444 status=$((status + ret))
    445 
    446 n=$((n + 1))
    447 echo_i "running 'rndc serve-stale off' ($n)"
    448 ret=0
    449 $RNDCCMD 10.53.0.1 serve-stale off || ret=1
    450 if [ $ret != 0 ]; then echo_i "failed"; fi
    451 status=$((status + ret))
    452 
    453 n=$((n + 1))
    454 echo_i "running 'rndc serve-stale reset' ($n)"
    455 ret=0
    456 $RNDCCMD 10.53.0.1 serve-stale reset || ret=1
    457 if [ $ret != 0 ]; then echo_i "failed"; fi
    458 status=$((status + ret))
    459 
    460 n=$((n + 1))
    461 echo_i "check 'rndc serve-stale status' ($n)"
    462 ret=0
    463 $RNDCCMD 10.53.0.1 serve-stale status >rndc.out.test$n 2>&1 || ret=1
    464 grep '_default: stale cache enabled; stale answers enabled (stale-answer-ttl=4 max-stale-ttl=3600 stale-refresh-time=0)' rndc.out.test$n >/dev/null || ret=1
    465 if [ $ret != 0 ]; then echo_i "failed"; fi
    466 status=$((status + ret))
    467 
    468 echo_i "sending queries for tests $((n + 1))-$((n + 4))..."
    469 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$((n + 1)) &
    470 $DIG -p ${PORT} @10.53.0.1 othertype.example CAA >dig.out.test$((n + 2)) &
    471 $DIG -p ${PORT} @10.53.0.1 nodata.example TXT >dig.out.test$((n + 3)) &
    472 $DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT >dig.out.test$((n + 4)) &
    473 
    474 wait
    475 
    476 n=$((n + 1))
    477 echo_i "check stale data.example TXT (serve-stale reset) ($n)"
    478 ret=0
    479 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    480 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    481 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    482 grep "data\.example\..*4.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    483 if [ $ret != 0 ]; then echo_i "failed"; fi
    484 status=$((status + ret))
    485 
    486 n=$((n + 1))
    487 echo_i "check stale othertype.example CAA (serve-stale reset) ($n)"
    488 ret=0
    489 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    490 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    491 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    492 grep "othertype.example\..*4.*IN.*CAA.*0.*issue" dig.out.test$n >/dev/null || ret=1
    493 if [ $ret != 0 ]; then echo_i "failed"; fi
    494 status=$((status + ret))
    495 
    496 n=$((n + 1))
    497 echo_i "check stale nodata.example TXT (serve-stale reset) ($n)"
    498 ret=0
    499 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    500 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    501 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    502 grep "example\..*4.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
    503 if [ $ret != 0 ]; then echo_i "failed"; fi
    504 status=$((status + ret))
    505 
    506 n=$((n + 1))
    507 echo_i "check stale nxdomain.example TXT (serve-stale reset) ($n)"
    508 ret=0
    509 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    510 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    511 if [ $ret != 0 ]; then echo_i "failed"; fi
    512 status=$((status + ret))
    513 
    514 n=$((n + 1))
    515 echo_i "running 'rndc serve-stale off' ($n)"
    516 ret=0
    517 $RNDCCMD 10.53.0.1 serve-stale off || ret=1
    518 if [ $ret != 0 ]; then echo_i "failed"; fi
    519 status=$((status + ret))
    520 
    521 n=$((n + 1))
    522 echo_i "check 'rndc serve-stale status' ($n)"
    523 ret=0
    524 $RNDCCMD 10.53.0.1 serve-stale status >rndc.out.test$n 2>&1 || ret=1
    525 grep '_default: stale cache enabled; stale answers disabled (stale-answer-ttl=4 max-stale-ttl=3600 stale-refresh-time=0)' rndc.out.test$n >/dev/null || ret=1
    526 if [ $ret != 0 ]; then echo_i "failed"; fi
    527 status=$((status + ret))
    528 
    529 #
    530 # Update named.conf.
    531 # Test server with low max-stale-ttl.
    532 #
    533 echo_i "test server with serve-stale options set, low max-stale-ttl"
    534 
    535 n=$((n + 1))
    536 echo_i "updating ns1/named.conf ($n)"
    537 ret=0
    538 copy_setports ns1/named3.conf.in ns1/named.conf
    539 if [ $ret != 0 ]; then echo_i "failed"; fi
    540 status=$((status + ret))
    541 
    542 n=$((n + 1))
    543 echo_i "running 'rndc reload' ($n)"
    544 ret=0
    545 rndc_reload ns1 10.53.0.1
    546 if [ $ret != 0 ]; then echo_i "failed"; fi
    547 status=$((status + ret))
    548 
    549 n=$((n + 1))
    550 echo_i "check 'rndc serve-stale status' ($n)"
    551 ret=0
    552 $RNDCCMD 10.53.0.1 serve-stale status >rndc.out.test$n 2>&1 || ret=1
    553 grep '_default: stale cache enabled; stale answers disabled (stale-answer-ttl=3 max-stale-ttl=20 stale-refresh-time=30)' rndc.out.test$n >/dev/null || ret=1
    554 if [ $ret != 0 ]; then echo_i "failed"; fi
    555 status=$((status + ret))
    556 
    557 n=$((n + 1))
    558 echo_i "flush cache, re-enable serve-stale and query again ($n)"
    559 ret=0
    560 $RNDCCMD 10.53.0.1 flushtree example >rndc.out.test$n.1 2>&1 || ret=1
    561 $RNDCCMD 10.53.0.1 serve-stale on >rndc.out.test$n.2 2>&1 || ret=1
    562 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$n || ret=1
    563 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    564 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    565 if [ $ret != 0 ]; then echo_i "failed"; fi
    566 status=$((status + ret))
    567 
    568 n=$((n + 1))
    569 echo_i "check 'rndc serve-stale status' ($n)"
    570 ret=0
    571 $RNDCCMD 10.53.0.1 serve-stale status >rndc.out.test$n 2>&1 || ret=1
    572 grep '_default: stale cache enabled; stale answers enabled (stale-answer-ttl=3 max-stale-ttl=20 stale-refresh-time=30)' rndc.out.test$n >/dev/null || ret=1
    573 if [ $ret != 0 ]; then echo_i "failed"; fi
    574 status=$((status + ret))
    575 
    576 n=$((n + 1))
    577 echo_i "enable responses from authoritative server ($n)"
    578 ret=0
    579 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
    580 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    581 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
    582 if [ $ret != 0 ]; then echo_i "failed"; fi
    583 status=$((status + ret))
    584 
    585 n=$((n + 1))
    586 echo_i "prime cache longttl.example TXT (low max-stale-ttl) ($n)"
    587 ret=0
    588 $DIG -p ${PORT} @10.53.0.1 longttl.example TXT >dig.out.test$n || ret=1
    589 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    590 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    591 if [ $ret != 0 ]; then echo_i "failed"; fi
    592 status=$((status + ret))
    593 
    594 n=$((n + 1))
    595 echo_i "prime cache data.example TXT (low max-stale-ttl) ($n)"
    596 ret=0
    597 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$n || ret=1
    598 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    599 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    600 if [ $ret != 0 ]; then echo_i "failed"; fi
    601 status=$((status + ret))
    602 
    603 n=$((n + 1))
    604 echo_i "prime cache othertype.example CAA (low max-stale-ttl) ($n)"
    605 ret=0
    606 $DIG -p ${PORT} @10.53.0.1 othertype.example CAA >dig.out.test$n || ret=1
    607 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    608 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    609 if [ $ret != 0 ]; then echo_i "failed"; fi
    610 status=$((status + ret))
    611 
    612 n=$((n + 1))
    613 echo_i "prime cache nodata.example TXT (low max-stale-ttl) ($n)"
    614 ret=0
    615 $DIG -p ${PORT} @10.53.0.1 nodata.example TXT >dig.out.test$n || ret=1
    616 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    617 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    618 if [ $ret != 0 ]; then echo_i "failed"; fi
    619 status=$((status + ret))
    620 
    621 n=$((n + 1))
    622 echo_i "prime cache nxdomain.example TXT (low max-stale-ttl) ($n)"
    623 ret=0
    624 $DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT >dig.out.test$n || ret=1
    625 grep "status: NXDOMAIN" dig.out.test$n >/dev/null || ret=1
    626 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    627 if [ $ret != 0 ]; then echo_i "failed"; fi
    628 status=$((status + ret))
    629 
    630 # Keep track of time so we can access these RRset later, when we expect them
    631 # to become ancient.
    632 t1=$($PERL -e 'print time()')
    633 
    634 n=$((n + 1))
    635 echo_i "verify prime cache statistics (low max-stale-ttl) ($n)"
    636 ret=0
    637 rm -f ns1/named.stats
    638 $RNDCCMD 10.53.0.1 stats >/dev/null 2>&1
    639 [ -f ns1/named.stats ] || ret=1
    640 cp ns1/named.stats ns1/named.stats.$n
    641 # Check first 10 lines of Cache DB statistics.  After prime queries, we expect
    642 # two active TXT RRsets, one active Others, one nxrrset TXT, and one NXDOMAIN.
    643 grep -A 10 "++ Cache DB RRsets ++" ns1/named.stats.$n >ns1/named.stats.$n.cachedb || ret=1
    644 grep "2 TXT" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    645 grep "1 Others" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    646 grep "1 !TXT" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    647 grep "1 NXDOMAIN" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    648 status=$((status + ret))
    649 if [ $ret != 0 ]; then echo_i "failed"; fi
    650 
    651 n=$((n + 1))
    652 echo_i "disable responses from authoritative server ($n)"
    653 ret=0
    654 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
    655 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    656 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
    657 if [ $ret != 0 ]; then echo_i "failed"; fi
    658 status=$((status + ret))
    659 
    660 sleep 2
    661 
    662 echo_i "sending queries for tests $((n + 1))-$((n + 4))..."
    663 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$((n + 1)) &
    664 $DIG -p ${PORT} @10.53.0.1 othertype.example CAA >dig.out.test$((n + 2)) &
    665 $DIG -p ${PORT} @10.53.0.1 nodata.example TXT >dig.out.test$((n + 3)) &
    666 $DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT >dig.out.test$((n + 4)) &
    667 
    668 wait
    669 
    670 n=$((n + 1))
    671 echo_i "check stale data.example TXT (low max-stale-ttl) ($n)"
    672 ret=0
    673 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    674 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    675 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    676 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    677 if [ $ret != 0 ]; then echo_i "failed"; fi
    678 status=$((status + ret))
    679 
    680 n=$((n + 1))
    681 echo_i "check stale othertype.example CAA (low max-stale-ttl) ($n)"
    682 ret=0
    683 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    684 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    685 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    686 grep "othertype\.example\..*3.*IN.*CAA.*0.*issue" dig.out.test$n >/dev/null || ret=1
    687 if [ $ret != 0 ]; then echo_i "failed"; fi
    688 status=$((status + ret))
    689 
    690 n=$((n + 1))
    691 echo_i "check stale nodata.example TXT (low max-stale-ttl) ($n)"
    692 ret=0
    693 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    694 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    695 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    696 grep "example\..*3.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
    697 if [ $ret != 0 ]; then echo_i "failed"; fi
    698 status=$((status + ret))
    699 
    700 n=$((n + 1))
    701 echo_i "check stale nxdomain.example TXT (low max-stale-ttl) ($n)"
    702 ret=0
    703 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    704 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    705 if [ $ret != 0 ]; then echo_i "failed"; fi
    706 status=$((status + ret))
    707 
    708 n=$((n + 1))
    709 echo_i "verify stale cache statistics (low max-stale-ttl) ($n)"
    710 ret=0
    711 rm -f ns1/named.stats
    712 $RNDCCMD 10.53.0.1 stats >/dev/null 2>&1
    713 [ -f ns1/named.stats ] || ret=1
    714 cp ns1/named.stats ns1/named.stats.$n
    715 # Check first 10 lines of Cache DB statistics.  After serve-stale queries, we
    716 # expect one active TXT RRset, one stale TXT, one stale nxrrset TXT, and one
    717 # stale NXDOMAIN.
    718 grep -A 10 "++ Cache DB RRsets ++" ns1/named.stats.$n >ns1/named.stats.$n.cachedb || ret=1
    719 grep "1 TXT" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    720 grep "1 #TXT" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    721 grep "1 #Others" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    722 grep "1 #!TXT" ns1/named.stats.$n.cachedb >/dev/null || ret=1
    723 
    724 status=$((status + ret))
    725 if [ $ret != 0 ]; then echo_i "failed"; fi
    726 
    727 # Retrieve max-stale-ttl value.
    728 interval_to_ancient=$(grep 'max-stale-ttl' ns1/named3.conf.in | awk '{ print $2 }' | tr -d ';')
    729 # We add 2 seconds to it since this is the ttl value of the records being
    730 # tested.
    731 interval_to_ancient=$((interval_to_ancient + 2))
    732 t2=$($PERL -e 'print time()')
    733 elapsed=$((t2 - t1))
    734 
    735 # If elapsed time so far is less than max-stale-ttl + 2 seconds, then we sleep
    736 # enough to ensure that we'll ask for ancient RRsets in the next queries.
    737 if [ $elapsed -lt $interval_to_ancient ]; then
    738   sleep $((interval_to_ancient - elapsed))
    739 fi
    740 
    741 echo_i "sending queries for tests $((n + 1))-$((n + 4))..."
    742 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$((n + 1)) &
    743 $DIG -p ${PORT} @10.53.0.1 othertype.example CAA >dig.out.test$((n + 2)) &
    744 $DIG -p ${PORT} @10.53.0.1 nodata.example TXT >dig.out.test$((n + 3)) &
    745 $DIG -p ${PORT} @10.53.0.1 nxdomain.example TXT >dig.out.test$((n + 4)) &
    746 
    747 wait
    748 
    749 # stale-answer is enabled, but with a very low TTL so the following answer have
    750 # been removed from the stale cache. Hence, no EDE 3 anymore, but EDE 22.
    751 
    752 n=$((n + 1))
    753 echo_i "check ancient data.example TXT (low max-stale-ttl) ($n)"
    754 ret=0
    755 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    756 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
    757 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
    758 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    759 if [ $ret != 0 ]; then echo_i "failed"; fi
    760 status=$((status + ret))
    761 
    762 n=$((n + 1))
    763 echo_i "check ancient othertype.example CAA (low max-stale-ttl) ($n)"
    764 ret=0
    765 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    766 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
    767 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
    768 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    769 if [ $ret != 0 ]; then echo_i "failed"; fi
    770 status=$((status + ret))
    771 
    772 n=$((n + 1))
    773 echo_i "check ancient nodata.example TXT (low max-stale-ttl) ($n)"
    774 ret=0
    775 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    776 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
    777 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
    778 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    779 if [ $ret != 0 ]; then echo_i "failed"; fi
    780 status=$((status + ret))
    781 
    782 n=$((n + 1))
    783 echo_i "check ancient nxdomain.example TXT (low max-stale-ttl) ($n)"
    784 ret=0
    785 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
    786 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
    787 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
    788 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
    789 if [ $ret != 0 ]; then echo_i "failed"; fi
    790 status=$((status + ret))
    791 
    792 # Test stale-refresh-time when serve-stale is enabled via rndc.
    793 # Steps for testing stale-refresh-time option (default).
    794 # 1. Prime cache data.example txt
    795 # 2. Disable responses from authoritative server.
    796 # 3. Sleep for TTL duration so rrset TTL expires (2 sec)
    797 # 4. Query data.example
    798 # 5. Check if response come from stale rrset (3 sec TTL)
    799 # 6. Enable responses from authoritative server.
    800 # 7. Query data.example
    801 # 8. Check if response come from stale rrset, since the query
    802 #    is within stale-refresh-time window.
    803 n=$((n + 1))
    804 echo_i "flush cache, enable responses from authoritative server ($n)"
    805 ret=0
    806 $RNDCCMD 10.53.0.1 flushtree example >rndc.out.test$n.1 2>&1 || ret=1
    807 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
    808 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    809 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
    810 if [ $ret != 0 ]; then echo_i "failed"; fi
    811 status=$((status + ret))
    812 
    813 n=$((n + 1))
    814 echo_i "check 'rndc serve-stale status' ($n)"
    815 ret=0
    816 $RNDCCMD 10.53.0.1 serve-stale status >rndc.out.test$n 2>&1 || ret=1
    817 grep '_default: stale cache enabled; stale answers enabled (stale-answer-ttl=3 max-stale-ttl=20 stale-refresh-time=30)' rndc.out.test$n >/dev/null || ret=1
    818 if [ $ret != 0 ]; then echo_i "failed"; fi
    819 status=$((status + ret))
    820 
    821 # Step 1.
    822 n=$((n + 1))
    823 echo_i "prime cache data.example TXT (stale-refresh-time rndc) ($n)"
    824 ret=0
    825 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$n || ret=1
    826 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    827 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    828 grep "data\.example\..*2.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    829 if [ $ret != 0 ]; then echo_i "failed"; fi
    830 status=$((status + ret))
    831 
    832 # Step 2.
    833 n=$((n + 1))
    834 echo_i "disable responses from authoritative server ($n)"
    835 ret=0
    836 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
    837 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    838 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
    839 if [ $ret != 0 ]; then echo_i "failed"; fi
    840 status=$((status + ret))
    841 
    842 # Step 3.
    843 sleep 2
    844 
    845 # Step 4.
    846 n=$((n + 1))
    847 echo_i "sending query for test ($n)"
    848 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$n || ret=1
    849 
    850 # Step 5.
    851 echo_i "check stale data.example TXT (stale-refresh-time rndc) ($n)"
    852 ret=0
    853 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    854 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    855 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    856 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    857 if [ $ret != 0 ]; then echo_i "failed"; fi
    858 status=$((status + ret))
    859 
    860 # Step 6.
    861 n=$((n + 1))
    862 echo_i "enable responses from authoritative server ($n)"
    863 ret=0
    864 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
    865 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    866 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
    867 if [ $ret != 0 ]; then echo_i "failed"; fi
    868 status=$((status + ret))
    869 
    870 # Step 7.
    871 echo_i "sending query for test $((n + 1))"
    872 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$((n + 1)) || true
    873 
    874 # Step 8.
    875 n=$((n + 1))
    876 echo_i "check stale data.example TXT comes from cache (stale-refresh-time rndc) ($n)"
    877 ret=0
    878 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    879 grep "EDE: 3 (Stale Answer): (query within stale refresh time window)" dig.out.test$n >/dev/null || ret=1
    880 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    881 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    882 if [ $ret != 0 ]; then echo_i "failed"; fi
    883 status=$((status + ret))
    884 
    885 # Steps for testing stale-refresh-time option (disabled).
    886 # 1. Prime cache data.example txt
    887 # 2. Disable responses from authoritative server.
    888 # 3. Sleep for TTL duration so rrset TTL expires (2 sec)
    889 # 4. Query data.example
    890 # 5. Check if response come from stale rrset (3 sec TTL)
    891 # 6. Enable responses from authoritative server.
    892 # 7. Query data.example
    893 # 8. Check if response come from stale rrset, since the query
    894 #    is within stale-refresh-time window.
    895 n=$((n + 1))
    896 echo_i "updating ns1/named.conf ($n)"
    897 ret=0
    898 copy_setports ns1/named4.conf.in ns1/named.conf
    899 if [ $ret != 0 ]; then echo_i "failed"; fi
    900 status=$((status + ret))
    901 
    902 n=$((n + 1))
    903 echo_i "running 'rndc reload' ($n)"
    904 ret=0
    905 rndc_reload ns1 10.53.0.1
    906 if [ $ret != 0 ]; then echo_i "failed"; fi
    907 status=$((status + ret))
    908 
    909 n=$((n + 1))
    910 echo_i "check 'rndc serve-stale status' ($n)"
    911 ret=0
    912 $RNDCCMD 10.53.0.1 serve-stale status >rndc.out.test$n 2>&1 || ret=1
    913 grep '_default: stale cache enabled; stale answers enabled (stale-answer-ttl=3 max-stale-ttl=20 stale-refresh-time=0)' rndc.out.test$n >/dev/null || ret=1
    914 if [ $ret != 0 ]; then echo_i "failed"; fi
    915 status=$((status + ret))
    916 
    917 n=$((n + 1))
    918 echo_i "flush cache, enable responses from authoritative server ($n)"
    919 ret=0
    920 $RNDCCMD 10.53.0.1 flushtree example >rndc.out.test$n.1 2>&1 || ret=1
    921 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
    922 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    923 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
    924 if [ $ret != 0 ]; then echo_i "failed"; fi
    925 status=$((status + ret))
    926 
    927 # Step 1.
    928 n=$((n + 1))
    929 echo_i "prime cache data.example TXT (stale-refresh-time disabled) ($n)"
    930 ret=0
    931 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$n || ret=1
    932 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    933 grep "EDE" dig.out.test$n >/dev/null && ret=1
    934 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    935 grep "data\.example\..*2.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    936 if [ $ret != 0 ]; then echo_i "failed"; fi
    937 status=$((status + ret))
    938 
    939 # Step 2.
    940 n=$((n + 1))
    941 echo_i "disable responses from authoritative server ($n)"
    942 ret=0
    943 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
    944 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    945 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
    946 if [ $ret != 0 ]; then echo_i "failed"; fi
    947 status=$((status + ret))
    948 
    949 # Step 3.
    950 sleep 2
    951 
    952 # Step 4.
    953 n=$((n + 1))
    954 echo_i "sending query for test ($n)"
    955 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$n || ret=1
    956 
    957 # Step 5.
    958 echo_i "check stale data.example TXT (stale-refresh-time disabled) ($n)"
    959 ret=0
    960 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    961 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
    962 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    963 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    964 if [ $ret != 0 ]; then echo_i "failed"; fi
    965 status=$((status + ret))
    966 
    967 # Step 6.
    968 n=$((n + 1))
    969 echo_i "enable responses from authoritative server ($n)"
    970 ret=0
    971 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
    972 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    973 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
    974 if [ $ret != 0 ]; then echo_i "failed"; fi
    975 status=$((status + ret))
    976 
    977 # Step 7.
    978 echo_i "sending query for test $((n + 1))"
    979 $DIG -p ${PORT} @10.53.0.1 data.example TXT >dig.out.test$((n + 1)) || true
    980 
    981 # Step 8.
    982 n=$((n + 1))
    983 echo_i "check data.example TXT comes from authoritative (stale-refresh-time disabled) ($n)"
    984 ret=0
    985 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
    986 grep "EDE" dig.out.test$n >/dev/null && ret=1
    987 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
    988 grep "data\.example\..*2.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
    989 if [ $ret != 0 ]; then echo_i "failed"; fi
    990 status=$((status + ret))
    991 
    992 #
    993 # Now test server with no serve-stale options set.
    994 #
    995 echo_i "test server with no serve-stale options set"
    996 
    997 n=$((n + 1))
    998 echo_i "updating ns3/named.conf ($n)"
    999 ret=0
   1000 copy_setports ns3/named1.conf.in ns3/named.conf
   1001 if [ $ret != 0 ]; then echo_i "failed"; fi
   1002 status=$((status + ret))
   1003 
   1004 echo_i "restart ns3"
   1005 stop_server --use-rndc --port ${CONTROLPORT} ns3
   1006 start_server --noclean --restart --port ${PORT} ns3
   1007 
   1008 n=$((n + 1))
   1009 echo_i "enable responses from authoritative server ($n)"
   1010 ret=0
   1011 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
   1012 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1013 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
   1014 if [ $ret != 0 ]; then echo_i "failed"; fi
   1015 status=$((status + ret))
   1016 
   1017 n=$((n + 1))
   1018 echo_i "prime cache longttl.example TXT (max-stale-ttl default) ($n)"
   1019 ret=0
   1020 $DIG -p ${PORT} @10.53.0.3 longttl.example TXT >dig.out.test$n || ret=1
   1021 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1022 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1023 if [ $ret != 0 ]; then echo_i "failed"; fi
   1024 status=$((status + ret))
   1025 
   1026 n=$((n + 1))
   1027 echo_i "prime cache data.example TXT (max-stale-ttl default) ($n)"
   1028 ret=0
   1029 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   1030 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1031 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1032 grep "data\.example\..*2.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   1033 if [ $ret != 0 ]; then echo_i "failed"; fi
   1034 status=$((status + ret))
   1035 
   1036 n=$((n + 1))
   1037 echo_i "prime cache othertype.example CAA (max-stale-ttl default) ($n)"
   1038 ret=0
   1039 $DIG -p ${PORT} @10.53.0.3 othertype.example CAA >dig.out.test$n || ret=1
   1040 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1041 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1042 grep "othertype\.example\..*2.*IN.*CAA.*0.*issue" dig.out.test$n >/dev/null || ret=1
   1043 if [ $ret != 0 ]; then echo_i "failed"; fi
   1044 status=$((status + ret))
   1045 
   1046 n=$((n + 1))
   1047 echo_i "prime cache nodata.example TXT (max-stale-ttl default) ($n)"
   1048 ret=0
   1049 $DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$n || ret=1
   1050 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1051 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1052 grep "example\..*2.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
   1053 if [ $ret != 0 ]; then echo_i "failed"; fi
   1054 status=$((status + ret))
   1055 
   1056 n=$((n + 1))
   1057 echo_i "prime cache nxdomain.example TXT (max-stale-ttl default) ($n)"
   1058 ret=0
   1059 $DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT >dig.out.test$n || ret=1
   1060 grep "status: NXDOMAIN" dig.out.test$n >/dev/null || ret=1
   1061 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1062 grep "example\..*2.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
   1063 if [ $ret != 0 ]; then echo_i "failed"; fi
   1064 status=$((status + ret))
   1065 
   1066 n=$((n + 1))
   1067 echo_i "verify prime cache statistics (max-stale-ttl default) ($n)"
   1068 ret=0
   1069 rm -f ns3/named.stats
   1070 $RNDCCMD 10.53.0.3 stats >/dev/null 2>&1
   1071 [ -f ns3/named.stats ] || ret=1
   1072 cp ns3/named.stats ns3/named.stats.$n
   1073 # Check first 10 lines of Cache DB statistics.  After prime queries, we expect
   1074 # two active TXT RRsets, one active Others, one nxrrset TXT, and one NXDOMAIN.
   1075 grep -A 10 "++ Cache DB RRsets ++" ns3/named.stats.$n >ns3/named.stats.$n.cachedb || ret=1
   1076 grep "2 TXT" ns3/named.stats.$n.cachedb >/dev/null || ret=1
   1077 grep "1 Others" ns3/named.stats.$n.cachedb >/dev/null || ret=1
   1078 grep "1 !TXT" ns3/named.stats.$n.cachedb >/dev/null || ret=1
   1079 grep "1 NXDOMAIN" ns3/named.stats.$n.cachedb >/dev/null || ret=1
   1080 status=$((status + ret))
   1081 if [ $ret != 0 ]; then echo_i "failed"; fi
   1082 
   1083 n=$((n + 1))
   1084 echo_i "disable responses from authoritative server ($n)"
   1085 ret=0
   1086 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
   1087 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1088 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
   1089 if [ $ret != 0 ]; then echo_i "failed"; fi
   1090 status=$((status + ret))
   1091 
   1092 n=$((n + 1))
   1093 echo_i "check 'rndc serve-stale status' ($n)"
   1094 ret=0
   1095 $RNDCCMD 10.53.0.3 serve-stale status >rndc.out.test$n 2>&1 || ret=1
   1096 grep "_default: stale cache enabled; stale answers disabled (stale-answer-ttl=$stale_answer_ttl max-stale-ttl=$max_stale_ttl stale-refresh-time=30)" rndc.out.test$n >/dev/null || ret=1
   1097 if [ $ret != 0 ]; then echo_i "failed"; fi
   1098 status=$((status + ret))
   1099 
   1100 sleep 2
   1101 
   1102 echo_i "sending queries for tests $((n + 1))-$((n + 4))..."
   1103 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$((n + 1)) &
   1104 $DIG -p ${PORT} @10.53.0.3 othertype.example CAA >dig.out.test$((n + 2)) &
   1105 $DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$((n + 3)) &
   1106 $DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT >dig.out.test$((n + 4)) &
   1107 
   1108 wait
   1109 
   1110 # no stale answers are used and the authoritative queries timed out. So no EDE 3
   1111 # is not sent but EDE 22 is sent.
   1112 
   1113 n=$((n + 1))
   1114 echo_i "check fail of data.example TXT (max-stale-ttl default) ($n)"
   1115 ret=0
   1116 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1117 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1118 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1119 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1120 if [ $ret != 0 ]; then echo_i "failed"; fi
   1121 status=$((status + ret))
   1122 
   1123 n=$((n + 1))
   1124 echo_i "check fail of othertype.example CAA (max-stale-ttl default) ($n)"
   1125 ret=0
   1126 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1127 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1128 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1129 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1130 if [ $ret != 0 ]; then echo_i "failed"; fi
   1131 status=$((status + ret))
   1132 
   1133 n=$((n + 1))
   1134 echo_i "check fail of nodata.example TXT (max-stale-ttl default) ($n)"
   1135 ret=0
   1136 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1137 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1138 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1139 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1140 if [ $ret != 0 ]; then echo_i "failed"; fi
   1141 status=$((status + ret))
   1142 
   1143 n=$((n + 1))
   1144 echo_i "check fail of nxdomain.example TXT (max-stale-ttl default) ($n)"
   1145 ret=0
   1146 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1147 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1148 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1149 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1150 if [ $ret != 0 ]; then echo_i "failed"; fi
   1151 status=$((status + ret))
   1152 
   1153 n=$((n + 1))
   1154 echo_i "verify stale cache statistics (max-stale-ttl default) ($n)"
   1155 ret=0
   1156 rm -f ns3/named.stats
   1157 $RNDCCMD 10.53.0.3 stats >/dev/null 2>&1
   1158 [ -f ns3/named.stats ] || ret=1
   1159 cp ns3/named.stats ns3/named.stats.$n
   1160 # Check first 10 lines of Cache DB statistics. After last queries, we expect
   1161 # one active TXT RRset, one stale TXT, one stale nxrrset TXT, and one stale
   1162 # NXDOMAIN.
   1163 grep -A 10 "++ Cache DB RRsets ++" ns3/named.stats.$n >ns3/named.stats.$n.cachedb || ret=1
   1164 grep "1 TXT" ns3/named.stats.$n.cachedb >/dev/null || ret=1
   1165 grep "1 #TXT" ns3/named.stats.$n.cachedb >/dev/null || ret=1
   1166 grep "1 #Others" ns3/named.stats.$n.cachedb >/dev/null || ret=1
   1167 grep "1 #!TXT" ns3/named.stats.$n.cachedb >/dev/null || ret=1
   1168 
   1169 status=$((status + ret))
   1170 if [ $ret != 0 ]; then echo_i "failed"; fi
   1171 
   1172 n=$((n + 1))
   1173 echo_i "check 'rndc serve-stale on' ($n)"
   1174 ret=0
   1175 $RNDCCMD 10.53.0.3 serve-stale on >rndc.out.test$n 2>&1 || ret=1
   1176 if [ $ret != 0 ]; then echo_i "failed"; fi
   1177 status=$((status + ret))
   1178 
   1179 n=$((n + 1))
   1180 echo_i "check 'rndc serve-stale status' ($n)"
   1181 ret=0
   1182 $RNDCCMD 10.53.0.3 serve-stale status >rndc.out.test$n 2>&1 || ret=1
   1183 grep "_default: stale cache enabled; stale answers enabled (stale-answer-ttl=$stale_answer_ttl max-stale-ttl=$max_stale_ttl stale-refresh-time=30)" rndc.out.test$n >/dev/null || ret=1
   1184 if [ $ret != 0 ]; then echo_i "failed"; fi
   1185 status=$((status + ret))
   1186 
   1187 sleep 2
   1188 
   1189 # Check that if we don't have stale data for a domain name, we will
   1190 # not answer anything until the resolver query timeout.
   1191 n=$((n + 1))
   1192 echo_i "check notincache.example TXT times out (max-stale-ttl default) ($n)"
   1193 ret=0
   1194 $DIG -p ${PORT} +tries=1 +timeout=3 @10.53.0.3 notfound.example TXT >dig.out.test$n 2>&1 && ret=1
   1195 grep "timed out" dig.out.test$n >/dev/null || ret=1
   1196 grep ";; no servers could be reached" dig.out.test$n >/dev/null || ret=1
   1197 if [ $ret != 0 ]; then echo_i "failed"; fi
   1198 status=$((status + ret))
   1199 
   1200 echo_i "sending queries for tests $((n + 1))-$((n + 4))..."
   1201 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$((n + 1)) &
   1202 $DIG -p ${PORT} @10.53.0.3 othertype.example CAA >dig.out.test$((n + 2)) &
   1203 $DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$((n + 3)) &
   1204 $DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT >dig.out.test$((n + 4)) &
   1205 $DIG -p ${PORT} @10.53.0.3 notfound.example TXT >dig.out.test$((n + 5)) &
   1206 
   1207 wait
   1208 
   1209 n=$((n + 1))
   1210 echo_i "check data.example TXT (max-stale-ttl default) ($n)"
   1211 ret=0
   1212 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1213 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
   1214 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1215 grep "data\.example\..*30.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   1216 if [ $ret != 0 ]; then echo_i "failed"; fi
   1217 status=$((status + ret))
   1218 
   1219 n=$((n + 1))
   1220 echo_i "check othertype.example CAA (max-stale-ttl default) ($n)"
   1221 ret=0
   1222 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1223 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
   1224 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1225 grep "example\..*30.*IN.*CAA.*0.*issue" dig.out.test$n >/dev/null || ret=1
   1226 if [ $ret != 0 ]; then echo_i "failed"; fi
   1227 status=$((status + ret))
   1228 
   1229 n=$((n + 1))
   1230 echo_i "check nodata.example TXT (max-stale-ttl default) ($n)"
   1231 ret=0
   1232 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1233 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
   1234 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1235 grep "example\..*30.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
   1236 if [ $ret != 0 ]; then echo_i "failed"; fi
   1237 status=$((status + ret))
   1238 
   1239 n=$((n + 1))
   1240 echo_i "check nxdomain.example TXT (max-stale-ttl default) ($n)"
   1241 ret=0
   1242 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1243 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1244 if [ $ret != 0 ]; then echo_i "failed"; fi
   1245 status=$((status + ret))
   1246 
   1247 # The notfound.example check is different than nxdomain.example because
   1248 # we didn't send a prime query to add notfound.example to the cache.
   1249 # Independently, EDE 22 is sent as the authoritative server doesn't respond.
   1250 n=$((n + 1))
   1251 echo_i "check notfound.example TXT (max-stale-ttl default) ($n)"
   1252 ret=0
   1253 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1254 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1255 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1256 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1257 if [ $ret != 0 ]; then echo_i "failed"; fi
   1258 status=$((status + ret))
   1259 
   1260 #
   1261 # Now test server with serve-stale answers disabled.
   1262 #
   1263 echo_i "test server with serve-stale disabled"
   1264 
   1265 n=$((n + 1))
   1266 echo_i "enable responses from authoritative server ($n)"
   1267 ret=0
   1268 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
   1269 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1270 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
   1271 if [ $ret != 0 ]; then echo_i "failed"; fi
   1272 status=$((status + ret))
   1273 
   1274 n=$((n + 1))
   1275 echo_i "prime cache longttl.example TTL (serve-stale answers disabled) ($n)"
   1276 ret=0
   1277 $DIG -p ${PORT} @10.53.0.4 longttl.example TXT >dig.out.test$n || ret=1
   1278 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1279 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1280 if [ $ret != 0 ]; then echo_i "failed"; fi
   1281 status=$((status + ret))
   1282 
   1283 n=$((n + 1))
   1284 echo_i "prime cache data.example TTL (serve-stale answers disabled) ($n)"
   1285 ret=0
   1286 $DIG -p ${PORT} @10.53.0.4 data.example TXT >dig.out.test$n || ret=1
   1287 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1288 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1289 grep "data\.example\..*2.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   1290 if [ $ret != 0 ]; then echo_i "failed"; fi
   1291 status=$((status + ret))
   1292 
   1293 n=$((n + 1))
   1294 echo_i "prime cache othertype.example CAA (serve-stale answers disabled) ($n)"
   1295 ret=0
   1296 $DIG -p ${PORT} @10.53.0.4 othertype.example CAA >dig.out.test$n || ret=1
   1297 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1298 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1299 grep "othertype\.example\..*2.*IN.*CAA.*0.*issue" dig.out.test$n >/dev/null || ret=1
   1300 if [ $ret != 0 ]; then echo_i "failed"; fi
   1301 status=$((status + ret))
   1302 
   1303 n=$((n + 1))
   1304 echo_i "prime cache nodata.example TXT (serve-stale answers disabled) ($n)"
   1305 ret=0
   1306 $DIG -p ${PORT} @10.53.0.4 nodata.example TXT >dig.out.test$n || ret=1
   1307 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1308 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1309 grep "example\..*2.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
   1310 if [ $ret != 0 ]; then echo_i "failed"; fi
   1311 status=$((status + ret))
   1312 
   1313 n=$((n + 1))
   1314 echo_i "prime cache nxdomain.example TXT (serve-stale answers disabled) ($n)"
   1315 ret=0
   1316 $DIG -p ${PORT} @10.53.0.4 nxdomain.example TXT >dig.out.test$n || ret=1
   1317 grep "status: NXDOMAIN" dig.out.test$n >/dev/null || ret=1
   1318 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1319 grep "example\..*2.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
   1320 if [ $ret != 0 ]; then echo_i "failed"; fi
   1321 status=$((status + ret))
   1322 
   1323 n=$((n + 1))
   1324 echo_i "verify prime cache statistics (serve-stale answers disabled) ($n)"
   1325 ret=0
   1326 rm -f ns4/named.stats
   1327 $RNDCCMD 10.53.0.4 stats >/dev/null 2>&1
   1328 [ -f ns4/named.stats ] || ret=1
   1329 cp ns4/named.stats ns4/named.stats.$n
   1330 # Check first 10 lines of Cache DB statistics.  After prime queries, we expect
   1331 # two active TXT RRsets, one active Others, one nxrrset TXT, and one NXDOMAIN.
   1332 grep -A 10 "++ Cache DB RRsets ++" ns4/named.stats.$n >ns4/named.stats.$n.cachedb || ret=1
   1333 grep "2 TXT" ns4/named.stats.$n.cachedb >/dev/null || ret=1
   1334 grep "1 Others" ns4/named.stats.$n.cachedb >/dev/null || ret=1
   1335 grep "1 !TXT" ns4/named.stats.$n.cachedb >/dev/null || ret=1
   1336 grep "1 NXDOMAIN" ns4/named.stats.$n.cachedb >/dev/null || ret=1
   1337 status=$((status + ret))
   1338 if [ $ret != 0 ]; then echo_i "failed"; fi
   1339 
   1340 n=$((n + 1))
   1341 echo_i "disable responses from authoritative server ($n)"
   1342 ret=0
   1343 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
   1344 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1345 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
   1346 if [ $ret != 0 ]; then echo_i "failed"; fi
   1347 status=$((status + ret))
   1348 
   1349 n=$((n + 1))
   1350 echo_i "check 'rndc serve-stale status' ($n)"
   1351 ret=0
   1352 $RNDCCMD 10.53.0.4 serve-stale status >rndc.out.test$n 2>&1 || ret=1
   1353 grep "_default: stale cache enabled; stale answers disabled (stale-answer-ttl=$stale_answer_ttl max-stale-ttl=$max_stale_ttl stale-refresh-time=30)" rndc.out.test$n >/dev/null || ret=1
   1354 if [ $ret != 0 ]; then echo_i "failed"; fi
   1355 status=$((status + ret))
   1356 
   1357 sleep 2
   1358 
   1359 echo_i "sending queries for tests $((n + 1))-$((n + 4))..."
   1360 $DIG -p ${PORT} @10.53.0.4 data.example TXT >dig.out.test$((n + 1)) &
   1361 $DIG -p ${PORT} @10.53.0.4 othertype.example CAA >dig.out.test$((n + 2)) &
   1362 $DIG -p ${PORT} @10.53.0.4 nodata.example TXT >dig.out.test$((n + 3)) &
   1363 $DIG -p ${PORT} @10.53.0.4 nxdomain.example TXT >dig.out.test$((n + 4)) &
   1364 
   1365 wait
   1366 
   1367 # no stale answers are used and the authoritative queries timed out. So no EDE 3
   1368 # is not sent but EDE 22 is sent.
   1369 
   1370 n=$((n + 1))
   1371 echo_i "check fail of data.example TXT (serve-stale answers disabled) ($n)"
   1372 ret=0
   1373 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1374 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1375 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1376 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1377 if [ $ret != 0 ]; then echo_i "failed"; fi
   1378 status=$((status + ret))
   1379 
   1380 n=$((n + 1))
   1381 echo_i "check fail of othertype.example TXT (serve-stale answers disabled) ($n)"
   1382 ret=0
   1383 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1384 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1385 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1386 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1387 if [ $ret != 0 ]; then echo_i "failed"; fi
   1388 status=$((status + ret))
   1389 
   1390 n=$((n + 1))
   1391 echo_i "check fail of nodata.example TXT (serve-stale answers disabled) ($n)"
   1392 ret=0
   1393 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1394 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1395 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1396 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1397 if [ $ret != 0 ]; then echo_i "failed"; fi
   1398 status=$((status + ret))
   1399 
   1400 n=$((n + 1))
   1401 echo_i "check fail of nxdomain.example TXT (serve-stale answers disabled) ($n)"
   1402 ret=0
   1403 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1404 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1405 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1406 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1407 if [ $ret != 0 ]; then echo_i "failed"; fi
   1408 status=$((status + ret))
   1409 
   1410 n=$((n + 1))
   1411 echo_i "verify stale cache statistics (serve-stale answers disabled) ($n)"
   1412 ret=0
   1413 rm -f ns4/named.stats
   1414 $RNDCCMD 10.53.0.4 stats >/dev/null 2>&1
   1415 [ -f ns4/named.stats ] || ret=1
   1416 cp ns4/named.stats ns4/named.stats.$n
   1417 # Check first 10 lines of Cache DB statistics. After last queries, we expect
   1418 # one active TXT RRset, one stale TXT, one stale nxrrset TXT, and one stale
   1419 # NXDOMAIN.
   1420 grep -A 10 "++ Cache DB RRsets ++" ns4/named.stats.$n >ns4/named.stats.$n.cachedb || ret=1
   1421 grep "1 TXT" ns4/named.stats.$n.cachedb >/dev/null || ret=1
   1422 grep "1 #TXT" ns4/named.stats.$n.cachedb >/dev/null || ret=1
   1423 grep "1 #Others" ns4/named.stats.$n.cachedb >/dev/null || ret=1
   1424 grep "1 #!TXT" ns4/named.stats.$n.cachedb >/dev/null || ret=1
   1425 status=$((status + ret))
   1426 if [ $ret != 0 ]; then echo_i "failed"; fi
   1427 
   1428 # Dump the cache.
   1429 n=$((n + 1))
   1430 echo_i "dump the cache (serve-stale answers disabled) ($n)"
   1431 ret=0
   1432 rndc_dumpdb ns4 -cache || ret=1
   1433 if [ $ret != 0 ]; then echo_i "failed"; fi
   1434 status=$((status + ret))
   1435 
   1436 echo_i "stop ns4"
   1437 stop_server --use-rndc --port ${CONTROLPORT} ns4
   1438 
   1439 # Load the cache as if it was five minutes (RBTDB_VIRTUAL) older. Since
   1440 # max-stale-ttl defaults to a week, we need to adjust the date by one week and
   1441 # five minutes.
   1442 LASTWEEK=$(TZ=UTC perl -e 'my $now = time();
   1443         my $oneWeekAgo = $now - 604800;
   1444         my $fiveMinutesAgo = $oneWeekAgo - 300;
   1445         my ($s, $m, $h, $d, $mo, $y) = (localtime($fiveMinutesAgo))[0, 1, 2, 3, 4, 5];
   1446         printf("%04d%02d%02d%02d%02d%02d", $y+1900, $mo+1, $d, $h, $m, $s);')
   1447 
   1448 echo_i "mock the cache date to $LASTWEEK (serve-stale answers disabled) ($n)"
   1449 ret=0
   1450 sed -E "s/DATE [0-9]{14}/DATE $LASTWEEK/g" ns4/named_dump.db.test$n >ns4/named_dump.db.out || ret=1
   1451 cp ns4/named_dump.db.out ns4/named_dump.db
   1452 if [ $ret != 0 ]; then echo_i "failed"; fi
   1453 status=$((status + ret))
   1454 
   1455 echo_i "start ns4"
   1456 start_server --noclean --restart --port ${PORT} ns4
   1457 
   1458 n=$((n + 1))
   1459 echo_i "verify ancient cache statistics (serve-stale answers disabled) ($n)"
   1460 ret=0
   1461 rm -f ns4/named.stats
   1462 $RNDCCMD 10.53.0.4 stats #> /dev/null 2>&1
   1463 [ -f ns4/named.stats ] || ret=1
   1464 cp ns4/named.stats ns4/named.stats.$n
   1465 # Check first 10 lines of Cache DB statistics. After last queries, we expect
   1466 # everything to be removed or scheduled to be removed.
   1467 grep -A 10 "++ Cache DB RRsets ++" ns4/named.stats.$n >ns4/named.stats.$n.cachedb || ret=1
   1468 grep "#TXT" ns4/named.stats.$n.cachedb >/dev/null && ret=1
   1469 grep "#Others" ns4/named.stats.$n.cachedb >/dev/null && ret=1
   1470 grep "#!TXT" ns4/named.stats.$n.cachedb >/dev/null && ret=1
   1471 grep "#NXDOMAIN" ns4/named.stats.$n.cachedb >/dev/null && ret=1
   1472 status=$((status + ret))
   1473 if [ $ret != 0 ]; then echo_i "failed"; fi
   1474 
   1475 #
   1476 # Test the server with stale-cache disabled.
   1477 #
   1478 echo_i "test server with serve-stale cache disabled"
   1479 
   1480 n=$((n + 1))
   1481 echo_i "enable responses from authoritative server ($n)"
   1482 ret=0
   1483 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
   1484 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1485 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
   1486 if [ $ret != 0 ]; then echo_i "failed"; fi
   1487 status=$((status + ret))
   1488 
   1489 n=$((n + 1))
   1490 echo_i "prime cache longttl.example TXT (serve-stale cache disabled) ($n)"
   1491 ret=0
   1492 $DIG -p ${PORT} @10.53.0.5 longttl.example TXT >dig.out.test$n || ret=1
   1493 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1494 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1495 if [ $ret != 0 ]; then echo_i "failed"; fi
   1496 status=$((status + ret))
   1497 
   1498 n=$((n + 1))
   1499 echo_i "prime cache data.example TXT (serve-stale cache disabled) ($n)"
   1500 ret=0
   1501 $DIG -p ${PORT} @10.53.0.5 data.example TXT >dig.out.test$n || ret=1
   1502 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1503 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1504 grep "data\.example\..*2.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   1505 if [ $ret != 0 ]; then echo_i "failed"; fi
   1506 status=$((status + ret))
   1507 
   1508 n=$((n + 1))
   1509 echo_i "prime cache othertype.example CAA (serve-stale cache disabled) ($n)"
   1510 ret=0
   1511 $DIG -p ${PORT} @10.53.0.5 othertype.example CAA >dig.out.test$n || ret=1
   1512 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1513 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1514 grep "othertype\.example\..*2.*IN.*CAA.*0.*issue" dig.out.test$n >/dev/null || ret=1
   1515 if [ $ret != 0 ]; then echo_i "failed"; fi
   1516 status=$((status + ret))
   1517 
   1518 n=$((n + 1))
   1519 echo_i "prime cache nodata.example TXT (serve-stale cache disabled) ($n)"
   1520 ret=0
   1521 $DIG -p ${PORT} @10.53.0.5 nodata.example TXT >dig.out.test$n || ret=1
   1522 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1523 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1524 grep "example\..*2.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
   1525 if [ $ret != 0 ]; then echo_i "failed"; fi
   1526 status=$((status + ret))
   1527 
   1528 n=$((n + 1))
   1529 echo_i "prime cache nxdomain.example TXT (serve-stale cache disabled) ($n)"
   1530 ret=0
   1531 $DIG -p ${PORT} @10.53.0.5 nxdomain.example TXT >dig.out.test$n || ret=1
   1532 grep "status: NXDOMAIN" dig.out.test$n >/dev/null || ret=1
   1533 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1534 grep "example\..*2.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
   1535 if [ $ret != 0 ]; then echo_i "failed"; fi
   1536 status=$((status + ret))
   1537 
   1538 n=$((n + 1))
   1539 echo_i "verify prime cache statistics (serve-stale cache disabled) ($n)"
   1540 ret=0
   1541 rm -f ns5/named.stats
   1542 $RNDCCMD 10.53.0.5 stats >/dev/null 2>&1
   1543 [ -f ns5/named.stats ] || ret=1
   1544 cp ns5/named.stats ns5/named.stats.$n
   1545 # Check first 10 lines of Cache DB statistics.  After serve-stale queries,
   1546 # we expect two active TXT RRsets, one active Others, one nxrrset TXT, and
   1547 # one NXDOMAIN.
   1548 grep -A 10 "++ Cache DB RRsets ++" ns5/named.stats.$n >ns5/named.stats.$n.cachedb || ret=1
   1549 grep "2 TXT" ns5/named.stats.$n.cachedb >/dev/null || ret=1
   1550 grep "1 Others" ns5/named.stats.$n.cachedb >/dev/null || ret=1
   1551 grep "1 !TXT" ns5/named.stats.$n.cachedb >/dev/null || ret=1
   1552 status=$((status + ret))
   1553 if [ $ret != 0 ]; then echo_i "failed"; fi
   1554 
   1555 n=$((n + 1))
   1556 echo_i "disable responses from authoritative server ($n)"
   1557 ret=0
   1558 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
   1559 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1560 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
   1561 if [ $ret != 0 ]; then echo_i "failed"; fi
   1562 status=$((status + ret))
   1563 
   1564 n=$((n + 1))
   1565 echo_i "check 'rndc serve-stale status' ($n)"
   1566 ret=0
   1567 $RNDCCMD 10.53.0.5 serve-stale status >rndc.out.test$n 2>&1 || ret=1
   1568 grep "_default: stale cache disabled; stale answers unavailable" rndc.out.test$n >/dev/null || ret=1
   1569 if [ $ret != 0 ]; then echo_i "failed"; fi
   1570 status=$((status + ret))
   1571 
   1572 sleep 2
   1573 
   1574 echo_i "sending queries for tests $((n + 1))-$((n + 4))..."
   1575 $DIG -p ${PORT} @10.53.0.5 data.example TXT >dig.out.test$((n + 1)) &
   1576 $DIG -p ${PORT} @10.53.0.5 othertype.example CAA >dig.out.test$((n + 2)) &
   1577 $DIG -p ${PORT} @10.53.0.5 nodata.example TXT >dig.out.test$((n + 3)) &
   1578 $DIG -p ${PORT} @10.53.0.5 nxdomain.example TXT >dig.out.test$((n + 4)) &
   1579 
   1580 wait
   1581 
   1582 # no stale answers are used and the authoritative queries timed out. So no EDE 3
   1583 # is not sent but EDE 22 is sent.
   1584 
   1585 n=$((n + 1))
   1586 echo_i "check fail of data.example TXT (serve-stale cache disabled) ($n)"
   1587 ret=0
   1588 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1589 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1590 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1591 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1592 if [ $ret != 0 ]; then echo_i "failed"; fi
   1593 status=$((status + ret))
   1594 
   1595 n=$((n + 1))
   1596 echo_i "check fail of othertype.example CAA (serve-stale cache disabled) ($n)"
   1597 ret=0
   1598 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1599 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1600 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1601 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1602 if [ $ret != 0 ]; then echo_i "failed"; fi
   1603 status=$((status + ret))
   1604 
   1605 n=$((n + 1))
   1606 echo_i "check fail of nodata.example TXT (serve-stale cache disabled) ($n)"
   1607 ret=0
   1608 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1609 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1610 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1611 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1612 if [ $ret != 0 ]; then echo_i "failed"; fi
   1613 status=$((status + ret))
   1614 
   1615 n=$((n + 1))
   1616 echo_i "check fail of nxdomain.example TXT (serve-stale cache disabled) ($n)"
   1617 ret=0
   1618 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   1619 grep "EDE: 22 (No Reachable Authority)" dig.out.test$n >/dev/null || ret=1
   1620 grep "EDE: 3 (Stale Answer)" dig.out.test$n >/dev/null && ret=1
   1621 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1622 if [ $ret != 0 ]; then echo_i "failed"; fi
   1623 status=$((status + ret))
   1624 
   1625 n=$((n + 1))
   1626 echo_i "verify stale cache statistics (serve-stale cache disabled) ($n)"
   1627 ret=0
   1628 rm -f ns5/named.stats
   1629 $RNDCCMD 10.53.0.5 stats >/dev/null 2>&1
   1630 [ -f ns5/named.stats ] || ret=1
   1631 cp ns5/named.stats ns5/named.stats.$n
   1632 # Check first 10 lines of Cache DB statistics.  After serve-stale queries,
   1633 # we expect one active TXT (longttl) and the rest to be expired from cache,
   1634 # but since we keep everything for 5 minutes (RBTDB_VIRTUAL) in the cache
   1635 # after expiry, they still show up in the stats.
   1636 grep -A 10 "++ Cache DB RRsets ++" ns5/named.stats.$n >ns5/named.stats.$n.cachedb || ret=1
   1637 grep -F "1 Others" ns5/named.stats.$n.cachedb >/dev/null || ret=1
   1638 grep -F "2 TXT" ns5/named.stats.$n.cachedb >/dev/null || ret=1
   1639 grep -F "1 !TXT" ns5/named.stats.$n.cachedb >/dev/null || ret=1
   1640 status=$((status + ret))
   1641 if [ $ret != 0 ]; then echo_i "failed"; fi
   1642 
   1643 # Dump the cache.
   1644 n=$((n + 1))
   1645 echo_i "dump the cache (serve-stale cache disabled) ($n)"
   1646 ret=0
   1647 rndc_dumpdb ns5 || ret=1
   1648 if [ $ret != 0 ]; then echo_i "failed"; fi
   1649 status=$((status + ret))
   1650 # Check that expired records are not dumped.
   1651 ret=0
   1652 grep "; expired (awaiting cleanup)" ns5/named_dump.db.test$n && ret=1
   1653 if [ $ret != 0 ]; then echo_i "failed"; fi
   1654 status=$((status + ret))
   1655 
   1656 # Dump the cache including expired entries.
   1657 n=$((n + 1))
   1658 echo_i "dump the cache including expired entries (serve-stale cache disabled) ($n)"
   1659 ret=0
   1660 rndc_dumpdb ns5 -expired || ret=1
   1661 if [ $ret != 0 ]; then echo_i "failed"; fi
   1662 status=$((status + ret))
   1663 
   1664 # Check that expired records are dumped.
   1665 echo_i "check rndc dump expired data.example ($n)"
   1666 ret=0
   1667 awk '/; expired/ { x=$0; getline; print x, $0}' ns5/named_dump.db.test$n \
   1668   | grep "; expired (awaiting cleanup) data\.example\..*A text record with a 2 second ttl" >/dev/null 2>&1 || ret=1
   1669 awk '/; expired/ { x=$0; getline; print x, $0}' ns5/named_dump.db.test$n \
   1670   | grep "; expired (awaiting cleanup) nodata\.example\." >/dev/null 2>&1 || ret=1
   1671 awk '/; expired/ { x=$0; getline; print x, $0}' ns5/named_dump.db.test$n \
   1672   | grep "; expired (awaiting cleanup) nxdomain\.example\." >/dev/null 2>&1 || ret=1
   1673 awk '/; expired/ { x=$0; getline; print x, $0}' ns5/named_dump.db.test$n \
   1674   | grep "; expired (awaiting cleanup) othertype\.example\." >/dev/null 2>&1 || ret=1
   1675 # Also make sure the not expired data does not have an expired comment.
   1676 awk '/; authanswer/ { x=$0; getline; print x, $0}' ns5/named_dump.db.test$n \
   1677   | grep "; authanswer longttl\.example.*A text record with a 600 second ttl" >/dev/null 2>&1 || ret=1
   1678 if [ $ret != 0 ]; then echo_i "failed"; fi
   1679 status=$((status + ret))
   1680 
   1681 echo_i "stop ns5"
   1682 stop_server --use-rndc --port ${CONTROLPORT} ns5
   1683 
   1684 # Load the cache as if it was five minutes (RBTDB_VIRTUAL) older.
   1685 cp ns5/named_dump.db.test$n ns5/named_dump.db
   1686 FIVEMINUTESAGO=$(TZ=UTC perl -e 'my $now = time();
   1687         my $fiveMinutesAgo = 300;
   1688         my ($s, $m, $h, $d, $mo, $y) = (localtime($fiveMinutesAgo))[0, 1, 2, 3, 4, 5];
   1689         printf("%04d%02d%02d%02d%02d%02d", $y+1900, $mo+1, $d, $h, $m, $s);')
   1690 
   1691 n=$((n + 1))
   1692 echo_i "mock the cache date to $FIVEMINUTESAGO (serve-stale cache disabled) ($n)"
   1693 ret=0
   1694 sed -E "s/DATE [0-9]{14}/DATE $FIVEMINUTESAGO/g" ns5/named_dump.db >ns5/named_dump.db.out || ret=1
   1695 cp ns5/named_dump.db.out ns5/named_dump.db
   1696 if [ $ret != 0 ]; then echo_i "failed"; fi
   1697 status=$((status + ret))
   1698 
   1699 echo_i "start ns5"
   1700 start_server --noclean --restart --port ${PORT} ns5
   1701 
   1702 n=$((n + 1))
   1703 echo_i "verify ancient cache statistics (serve-stale cache disabled) ($n)"
   1704 ret=0
   1705 rm -f ns5/named.stats
   1706 $RNDCCMD 10.53.0.5 stats #> /dev/null 2>&1
   1707 [ -f ns5/named.stats ] || ret=1
   1708 cp ns5/named.stats ns5/named.stats.$n
   1709 # Check first 10 lines of Cache DB statistics. After last queries, we expect
   1710 # everything to be removed or scheduled to be removed.
   1711 grep -A 10 "++ Cache DB RRsets ++" ns5/named.stats.$n >ns5/named.stats.$n.cachedb || ret=1
   1712 grep -F "#TXT" ns5/named.stats.$n.cachedb >/dev/null && ret=1
   1713 grep -F "#Others" ns5/named.stats.$n.cachedb >/dev/null && ret=1
   1714 grep -F "#!TXT" ns5/named.stats.$n.cachedb >/dev/null && ret=1
   1715 status=$((status + ret))
   1716 if [ $ret != 0 ]; then echo_i "failed"; fi
   1717 
   1718 #############################################
   1719 # Test for stale-answer-client-timeout off. #
   1720 #############################################
   1721 echo_i "test stale-answer-client-timeout (off)"
   1722 
   1723 n=$((n + 1))
   1724 echo_i "updating ns3/named.conf ($n)"
   1725 ret=0
   1726 copy_setports ns3/named3.conf.in ns3/named.conf
   1727 if [ $ret != 0 ]; then echo_i "failed"; fi
   1728 status=$((status + ret))
   1729 
   1730 n=$((n + 1))
   1731 echo_i "running 'rndc reload' ($n)"
   1732 ret=0
   1733 rndc_reload ns3 10.53.0.3
   1734 if [ $ret != 0 ]; then echo_i "failed"; fi
   1735 status=$((status + ret))
   1736 
   1737 # Send a query, auth server is disabled, we will enable it after a while in
   1738 # order to receive an answer before resolver-query-timeout expires. Since
   1739 # stale-answer-client-timeout is disabled we must receive an answer from
   1740 # authoritative server.
   1741 echo_i "sending query for test $((n + 2))"
   1742 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$((n + 2)) &
   1743 sleep 3
   1744 
   1745 n=$((n + 1))
   1746 echo_i "enable responses from authoritative server ($n)"
   1747 ret=0
   1748 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
   1749 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1750 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
   1751 if [ $ret != 0 ]; then echo_i "failed"; fi
   1752 status=$((status + ret))
   1753 
   1754 # Wait until dig is done.
   1755 wait
   1756 
   1757 n=$((n + 1))
   1758 echo_i "check data.example TXT comes from authoritative server (stale-answer-client-timeout off) ($n)"
   1759 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1760 grep "EDE" dig.out.test$n >/dev/null && ret=1
   1761 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1762 grep "data\.example\..*[12].*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   1763 if [ $ret != 0 ]; then echo_i "failed"; fi
   1764 status=$((status + ret))
   1765 
   1766 check_server_responds() {
   1767   $DIG -p ${PORT} @10.53.0.3 version.bind txt ch >dig.out.test$n || return 1
   1768   grep "status: NOERROR" dig.out.test$n >/dev/null || return 1
   1769 }
   1770 
   1771 ##############################################################
   1772 # Test for stale-answer-client-timeout off and CNAME record. #
   1773 ##############################################################
   1774 echo_i "test stale-answer-client-timeout (0) and CNAME record"
   1775 
   1776 n=$((n + 1))
   1777 echo_i "prime cache shortttl.cname.example (stale-answer-client-timeout off) ($n)"
   1778 ret=0
   1779 $DIG -p ${PORT} @10.53.0.3 shortttl.cname.example A >dig.out.test$n || ret=1
   1780 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1781 grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1
   1782 grep "shortttl\.cname\.example\..*1.*IN.*CNAME.*longttl\.target\.example\." dig.out.test$n >/dev/null || ret=1
   1783 grep "longttl\.target\.example\..*600.*IN.*A.*10\.53\.0\.2" dig.out.test$n >/dev/null || ret=1
   1784 if [ $ret != 0 ]; then echo_i "failed"; fi
   1785 status=$((status + ret))
   1786 
   1787 # Allow RRset to become stale.
   1788 sleep 1
   1789 
   1790 n=$((n + 1))
   1791 echo_i "disable responses from authoritative server ($n)"
   1792 ret=0
   1793 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
   1794 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1795 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
   1796 if [ $ret != 0 ]; then echo_i "failed"; fi
   1797 status=$((status + ret))
   1798 
   1799 n=$((n + 1))
   1800 ret=0
   1801 echo_i "check stale shortttl.cname.example comes from cache (stale-answer-client-timeout off) ($n)"
   1802 nextpart ns3/named.run >/dev/null
   1803 $DIG -p ${PORT} @10.53.0.3 shortttl.cname.example A >dig.out.test$n || ret=1
   1804 wait_for_log 5 "shortttl.cname.example A resolver failure, stale answer used" ns3/named.run || ret=1
   1805 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1806 grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1
   1807 grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1
   1808 grep "shortttl\.cname\.example\..*3.*IN.*CNAME.*longttl\.target\.example\." dig.out.test$n >/dev/null || ret=1
   1809 # We can't reliably test the TTL of the longttl.target.example A record.
   1810 grep "longttl\.target\.example\..*IN.*A.*10\.53\.0\.2" dig.out.test$n >/dev/null || ret=1
   1811 if [ $ret != 0 ]; then echo_i "failed"; fi
   1812 status=$((status + ret))
   1813 
   1814 n=$((n + 1))
   1815 echo_i "enable responses from authoritative server ($n)"
   1816 ret=0
   1817 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
   1818 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1819 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
   1820 if [ $ret != 0 ]; then echo_i "failed"; fi
   1821 status=$((status + ret))
   1822 
   1823 n=$((n + 1))
   1824 echo_i "check server is alive or restart ($n)"
   1825 ret=0
   1826 $RNDCCMD 10.53.0.3 status >rndc.out.test$n 2>&1 || ret=1
   1827 if [ $ret != 0 ]; then
   1828   echo_i "failed"
   1829   echo_i "restart ns3"
   1830   start_server --noclean --restart --port ${PORT} serve-stale ns3
   1831 fi
   1832 status=$((status + ret))
   1833 
   1834 n=$((n + 1))
   1835 echo_i "check server is alive or restart ($n)"
   1836 ret=0
   1837 $RNDCCMD 10.53.0.3 status >rndc.out.test$n 2>&1 || ret=1
   1838 if [ $ret != 0 ]; then
   1839   echo_i "failed"
   1840   echo_i "restart ns3"
   1841   start_server --noclean --restart --port ${PORT} serve-stale ns3
   1842 fi
   1843 status=$((status + ret))
   1844 
   1845 #############################################
   1846 # Test for stale-answer-client-timeout 0.   #
   1847 #############################################
   1848 echo_i "test stale-answer-client-timeout (0)"
   1849 
   1850 n=$((n + 1))
   1851 echo_i "updating ns3/named.conf ($n)"
   1852 ret=0
   1853 copy_setports ns3/named4.conf.in ns3/named.conf
   1854 if [ $ret != 0 ]; then echo_i "failed"; fi
   1855 status=$((status + ret))
   1856 
   1857 echo_i "restart ns3"
   1858 stop_server --use-rndc --port ${CONTROLPORT} ns3
   1859 start_server --noclean --restart --port ${PORT} ns3
   1860 
   1861 n=$((n + 1))
   1862 echo_i "prime cache data.example TXT (stale-answer-client-timeout 0)"
   1863 ret=0
   1864 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   1865 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1866 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1867 if [ $ret != 0 ]; then echo_i "failed"; fi
   1868 status=$((status + ret))
   1869 
   1870 n=$((n + 1))
   1871 echo_i "prime cache nodata.example TXT (stale-answer-client-timeout 0)"
   1872 ret=0
   1873 $DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$n || ret=1
   1874 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1875 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1876 if [ $ret != 0 ]; then echo_i "failed"; fi
   1877 status=$((status + ret))
   1878 
   1879 n=$((n + 1))
   1880 echo_i "disable responses from authoritative server ($n)"
   1881 ret=0
   1882 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
   1883 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1884 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
   1885 if [ $ret != 0 ]; then echo_i "failed"; fi
   1886 status=$((status + ret))
   1887 
   1888 # Allow RRset to become stale.
   1889 sleep 2
   1890 
   1891 n=$((n + 1))
   1892 ret=0
   1893 echo_i "check stale nodata.example TXT comes from cache (stale-answer-client-timeout 0) ($n)"
   1894 nextpart ns3/named.run >/dev/null
   1895 $DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$n || ret=1
   1896 wait_for_log 5 "nodata.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
   1897 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1898 grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1
   1899 grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1
   1900 grep "example\..*3.*IN.*SOA" dig.out.test$n >/dev/null || ret=1
   1901 if [ $ret != 0 ]; then echo_i "failed"; fi
   1902 status=$((status + ret))
   1903 
   1904 n=$((n + 1))
   1905 ret=0
   1906 echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0) ($n)"
   1907 nextpart ns3/named.run >/dev/null
   1908 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   1909 wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
   1910 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1911 grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1
   1912 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1913 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   1914 if [ $ret != 0 ]; then echo_i "failed"; fi
   1915 status=$((status + ret))
   1916 
   1917 n=$((n + 1))
   1918 echo_i "enable responses from authoritative server ($n)"
   1919 ret=0
   1920 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
   1921 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1922 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
   1923 if [ $ret != 0 ]; then echo_i "failed"; fi
   1924 status=$((status + ret))
   1925 
   1926 wait_for_rrset_refresh() {
   1927   $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || return 1
   1928   grep "status: NOERROR" dig.out.test$n >/dev/null || return 1
   1929   grep "EDE" dig.out.test$n >/dev/null && return 1
   1930   grep "ANSWER: 1," dig.out.test$n >/dev/null || return 1
   1931   grep "data\.example\..*[12].*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || return 1
   1932 }
   1933 
   1934 # This test ensures that after we get stale data due to
   1935 # stale-answer-client-timeout 0, enabling the authoritative server will allow
   1936 # the RRset to be updated.
   1937 n=$((n + 1))
   1938 ret=0
   1939 echo_i "check stale data.example TXT was refreshed (stale-answer-client-timeout 0) ($n)"
   1940 retry_quiet 10 wait_for_rrset_refresh || ret=1
   1941 if [ $ret != 0 ]; then echo_i "failed"; fi
   1942 status=$((status + ret))
   1943 
   1944 wait_for_nodata_refresh() {
   1945   $DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$n || return 1
   1946   grep "status: NOERROR" dig.out.test$n >/dev/null || return 1
   1947   grep "ANSWER: 0," dig.out.test$n >/dev/null || return 1
   1948   grep "example\..*[12].*IN.*SOA" dig.out.test$n >/dev/null || return 1
   1949   return 0
   1950 }
   1951 
   1952 n=$((n + 1))
   1953 ret=0
   1954 echo_i "check stale nodata.example TXT was refreshed (stale-answer-client-timeout 0) ($n)"
   1955 retry_quiet 10 wait_for_nodata_refresh || ret=1
   1956 if [ $ret != 0 ]; then echo_i "failed"; fi
   1957 status=$((status + ret))
   1958 
   1959 ####################################################################
   1960 # Test for stale-answer-client-timeout 0 and recursive-clients 10. #
   1961 # CVE-2023-2911, GL #4089                                          #
   1962 # ##################################################################
   1963 echo_i "test stale-answer-client-timeout (0) and recursive-clients 10"
   1964 
   1965 n=$((n + 1))
   1966 echo_i "prime cache data.slow TXT (stale-answer-client-timeout 0) ($n)"
   1967 ret=0
   1968 $DIG -p ${PORT} @10.53.0.3 data.slow TXT >dig.out.test$n || ret=1
   1969 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   1970 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1971 if [ $ret != 0 ]; then echo_i "failed"; fi
   1972 status=$((status + ret))
   1973 
   1974 # Run the following check twice. Sometimes a priming query interrupts the first
   1975 # attempt to exceed the quota.
   1976 attempt=0
   1977 while [ $ret -eq 0 ] && [ $attempt -lt 2 ]; do
   1978   n=$((n + 1))
   1979   echo_i "slow down response from authoritative server ($n)"
   1980   ret=0
   1981   $DIG -p ${PORT} @10.53.0.2 slowdown TXT >dig.out.test$n || ret=1
   1982   grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   1983   grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
   1984   if [ $ret != 0 ]; then echo_i "failed"; fi
   1985   status=$((status + ret))
   1986 
   1987   # Let the data.slow TTL expire
   1988   sleep 2
   1989 
   1990   n=$((n + 1))
   1991   echo_i "check that named survives reaching recursive-clients quota (stale-answer-client-timeout 0) ($n)"
   1992   ret=0
   1993   num=0
   1994   # Attempt to exceed the configured value of 'recursive-clients 10;' by running
   1995   # 20 parallel queries for the stale domain which has slow auth.
   1996   while [ $num -lt 20 ]; do
   1997     $DIG +tries=1 +timeout=10 -p ${PORT} @10.53.0.3 data.slow TXT >/dev/null 2>&1 &
   1998     num=$((num + 1))
   1999   done
   2000   # Let the dig processes finish.
   2001   wait
   2002   retry_quiet 5 check_server_responds || ret=1
   2003   if [ $ret != 0 ]; then echo_i "failed"; fi
   2004   status=$((status + ret))
   2005 
   2006   attempt=$((attempt + 1))
   2007 done
   2008 
   2009 # Restart ns3 to avoid the exceeded recursive-clients limit from previous check
   2010 # to interfere with subsequent checks.
   2011 echo_i "restart ns3"
   2012 stop_server --use-rndc --port ${CONTROLPORT} ns3
   2013 start_server --noclean --restart --port ${PORT} ns3
   2014 
   2015 ############################################################
   2016 # Test for stale-answer-client-timeout 0 and CNAME record. #
   2017 ############################################################
   2018 echo_i "test stale-answer-client-timeout (0) and CNAME record"
   2019 
   2020 n=$((n + 1))
   2021 echo_i "prime cache cname1.stale.test A (stale-answer-client-timeout 0) ($n)"
   2022 ret=0
   2023 $DIG -p ${PORT} @10.53.0.3 cname1.stale.test A >dig.out.test$n || ret=1
   2024 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2025 grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1
   2026 grep "cname1\.stale\.test\..*1.*IN.*CNAME.*a1\.stale\.test\." dig.out.test$n >/dev/null || ret=1
   2027 grep "a1\.stale\.test\..*1.*IN.*A.*192\.0\.2\.1" dig.out.test$n >/dev/null || ret=1
   2028 if [ $ret != 0 ]; then echo_i "failed"; fi
   2029 status=$((status + ret))
   2030 
   2031 # Allow RRset to become stale.
   2032 sleep 1
   2033 
   2034 n=$((n + 1))
   2035 ret=0
   2036 echo_i "check stale cname1.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)"
   2037 nextpart ns3/named.run >/dev/null
   2038 $DIG -p ${PORT} @10.53.0.3 cname1.stale.test A >dig.out.test$n || ret=1
   2039 wait_for_log 5 "cname1.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
   2040 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2041 grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1
   2042 grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1
   2043 grep "cname1\.stale\.test\..*3.*IN.*CNAME.*a1\.stale\.test\." dig.out.test$n >/dev/null || ret=1
   2044 grep "a1\.stale\.test\..*3.*IN.*A.*192\.0\.2\.1" dig.out.test$n >/dev/null || ret=1
   2045 if [ $ret != 0 ]; then echo_i "failed"; fi
   2046 status=$((status + ret))
   2047 
   2048 n=$((n + 1))
   2049 echo_i "check server is alive or restart ($n)"
   2050 ret=0
   2051 $RNDCCMD 10.53.0.3 status >rndc.out.test$n 2>&1 || ret=1
   2052 if [ $ret != 0 ]; then
   2053   echo_i "failed"
   2054   echo_i "restart ns3"
   2055   start_server --noclean --restart --port ${PORT} ns3
   2056 fi
   2057 status=$((status + ret))
   2058 
   2059 n=$((n + 1))
   2060 echo_i "prime cache cname2.stale.test A (stale-answer-client-timeout 0) ($n)"
   2061 ret=0
   2062 $DIG -p ${PORT} @10.53.0.3 cname2.stale.test A >dig.out.test$n || ret=1
   2063 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2064 grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1
   2065 grep "cname2\.stale\.test\..*1.*IN.*CNAME.*a2\.stale\.test\." dig.out.test$n >/dev/null || ret=1
   2066 grep "a2\.stale\.test\..*300.*IN.*A.*192\.0\.2\.2" dig.out.test$n >/dev/null || ret=1
   2067 if [ $ret != 0 ]; then echo_i "failed"; fi
   2068 status=$((status + ret))
   2069 
   2070 # Allow CNAME record in the RRSET to become stale.
   2071 sleep 1
   2072 
   2073 n=$((n + 1))
   2074 ret=0
   2075 echo_i "check stale cname2.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)"
   2076 nextpart ns3/named.run >/dev/null
   2077 $DIG -p ${PORT} @10.53.0.3 cname2.stale.test A >dig.out.test$n || ret=1
   2078 wait_for_log 5 "cname2.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
   2079 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2080 grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1
   2081 grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1
   2082 grep "cname2\.stale\.test\..*3.*IN.*CNAME.*a2\.stale\.test\." dig.out.test$n >/dev/null || ret=1
   2083 # We can't reliably test the TTL of the a2.stale.test A record.
   2084 grep "a2\.stale\.test\..*IN.*A.*192\.0\.2\.2" dig.out.test$n >/dev/null || ret=1
   2085 if [ $ret != 0 ]; then echo_i "failed"; fi
   2086 status=$((status + ret))
   2087 
   2088 n=$((n + 1))
   2089 echo_i "check server is alive or restart ($n)"
   2090 ret=0
   2091 $RNDCCMD 10.53.0.3 status >rndc.out.test$n 2>&1 || ret=1
   2092 if [ $ret != 0 ]; then
   2093   echo_i "failed"
   2094   echo_i "restart ns3"
   2095   start_server --noclean --restart --port ${PORT} ns3
   2096 fi
   2097 status=$((status + ret))
   2098 
   2099 ####################################################################
   2100 # Test for stale-answer-client-timeout 0 and stale-refresh-time 4. #
   2101 ####################################################################
   2102 echo_i "test stale-answer-client-timeout (0) and stale-refresh-time (4)"
   2103 
   2104 n=$((n + 1))
   2105 echo_i "updating ns3/named.conf ($n)"
   2106 ret=0
   2107 copy_setports ns3/named5.conf.in ns3/named.conf
   2108 if [ $ret != 0 ]; then echo_i "failed"; fi
   2109 status=$((status + ret))
   2110 
   2111 n=$((n + 1))
   2112 echo_i "running 'rndc reload' ($n)"
   2113 ret=0
   2114 rndc_reload ns3 10.53.0.3
   2115 if [ $ret != 0 ]; then echo_i "failed"; fi
   2116 status=$((status + ret))
   2117 
   2118 n=$((n + 1))
   2119 echo_i "flush cache, enable responses from authoritative server ($n)"
   2120 ret=0
   2121 $RNDCCMD 10.53.0.3 flushtree example >rndc.out.test$n.1 2>&1 || ret=1
   2122 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
   2123 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2124 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
   2125 if [ $ret != 0 ]; then echo_i "failed"; fi
   2126 status=$((status + ret))
   2127 
   2128 n=$((n + 1))
   2129 echo_i "prime cache data.example TXT (stale-answer-client-timeout 0, stale-refresh-time 4) ($n)"
   2130 ret=0
   2131 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   2132 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2133 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2134 grep "data\.example\..*2.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   2135 if [ $ret != 0 ]; then echo_i "failed"; fi
   2136 status=$((status + ret))
   2137 
   2138 # Allow RRset to become stale.
   2139 sleep 2
   2140 
   2141 n=$((n + 1))
   2142 echo_i "disable responses from authoritative server ($n)"
   2143 ret=0
   2144 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
   2145 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2146 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
   2147 if [ $ret != 0 ]; then echo_i "failed"; fi
   2148 status=$((status + ret))
   2149 
   2150 n=$((n + 1))
   2151 ret=0
   2152 echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)"
   2153 nextpart ns3/named.run >/dev/null
   2154 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   2155 wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
   2156 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2157 grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1
   2158 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2159 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   2160 if [ $ret != 0 ]; then echo_i "failed"; fi
   2161 status=$((status + ret))
   2162 
   2163 n=$((n + 1))
   2164 echo_i "enable responses from authoritative server ($n)"
   2165 ret=0
   2166 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
   2167 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2168 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
   2169 if [ $ret != 0 ]; then echo_i "failed"; fi
   2170 status=$((status + ret))
   2171 
   2172 # This test ensures that after we get stale data due to
   2173 # stale-answer-client-timeout 0, enabling the authoritative server will allow
   2174 # the RRset to be updated.
   2175 n=$((n + 1))
   2176 ret=0
   2177 echo_i "check stale data.example TXT was refreshed (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)"
   2178 retry_quiet 10 wait_for_rrset_refresh || ret=1
   2179 if [ $ret != 0 ]; then echo_i "failed"; fi
   2180 status=$((status + ret))
   2181 
   2182 # Allow RRset to become stale.
   2183 sleep 2
   2184 
   2185 n=$((n + 1))
   2186 echo_i "disable responses from authoritative server ($n)"
   2187 ret=0
   2188 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
   2189 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2190 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
   2191 if [ $ret != 0 ]; then echo_i "failed"; fi
   2192 status=$((status + ret))
   2193 
   2194 n=$((n + 1))
   2195 ret=0
   2196 echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)"
   2197 nextpart ns3/named.run >/dev/null
   2198 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   2199 wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
   2200 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2201 grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1
   2202 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2203 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   2204 if [ $ret != 0 ]; then echo_i "failed"; fi
   2205 status=$((status + ret))
   2206 
   2207 # Allow stale-refresh-time to be activated.
   2208 n=$((n + 1))
   2209 ret=0
   2210 echo_i "wait until resolver query times out, activating stale-refresh-time"
   2211 wait_for_log 15 "data.example/TXT stale refresh failed: timed out" ns3/named.run || ret=1
   2212 if [ $ret != 0 ]; then echo_i "failed"; fi
   2213 status=$((status + ret))
   2214 
   2215 n=$((n + 1))
   2216 ret=0
   2217 echo_i "check stale data.example TXT comes from cache within stale-refresh-time (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)"
   2218 nextpart ns3/named.run >/dev/null
   2219 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   2220 wait_for_log 5 "data.example TXT query within stale refresh time" ns3/named.run || ret=1
   2221 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2222 grep "EDE: 3 (Stale Answer): (query within stale refresh time window)" dig.out.test$n >/dev/null || ret=1
   2223 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2224 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   2225 if [ $ret != 0 ]; then echo_i "failed"; fi
   2226 status=$((status + ret))
   2227 
   2228 n=$((n + 1))
   2229 echo_i "enable responses from authoritative server ($n)"
   2230 ret=0
   2231 $DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1
   2232 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2233 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1
   2234 if [ $ret != 0 ]; then echo_i "failed"; fi
   2235 status=$((status + ret))
   2236 
   2237 # We give BIND some time to ensure that after we enable authoritative server,
   2238 # this RRset is still not refreshed because it was hit during
   2239 # stale-refresh-time window.
   2240 sleep 1
   2241 
   2242 n=$((n + 1))
   2243 ret=0
   2244 echo_i "check stale data.example TXT was not refreshed (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)"
   2245 nextpart ns3/named.run >/dev/null
   2246 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   2247 wait_for_log 5 "data.example TXT query within stale refresh time" ns3/named.run || ret=1
   2248 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2249 grep "EDE: 3 (Stale Answer): (query within stale refresh time window)" dig.out.test$n >/dev/null || ret=1
   2250 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2251 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   2252 if [ $ret != 0 ]; then echo_i "failed"; fi
   2253 status=$((status + ret))
   2254 
   2255 # After the refresh-time-window, the RRset will be refreshed.
   2256 sleep 4
   2257 
   2258 n=$((n + 1))
   2259 ret=0
   2260 echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)"
   2261 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   2262 wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1
   2263 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2264 grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1
   2265 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2266 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   2267 if [ $ret != 0 ]; then echo_i "failed"; fi
   2268 status=$((status + ret))
   2269 
   2270 n=$((n + 1))
   2271 ret=0
   2272 echo_i "check stale data.example TXT was refreshed (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)"
   2273 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   2274 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2275 grep "EDE" dig.out.test$n >/dev/null && ret=1
   2276 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2277 grep "data\.example\..*[12].*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   2278 if [ $ret != 0 ]; then echo_i "failed"; fi
   2279 status=$((status + ret))
   2280 
   2281 ####################################################################
   2282 # Test serve-stale's interaction with fetch limits (cache only) #
   2283 #################################################################
   2284 echo_i "test serve-stale's interaction with fetch-limits (cache only)"
   2285 
   2286 # We update the named configuration to enable fetch-limits. The fetch-limits
   2287 # are set to 1, which is ridiciously low, but that is because for this test we
   2288 # want to reach the fetch-limits.
   2289 n=$((n + 1))
   2290 echo_i "updating ns3/named.conf ($n)"
   2291 ret=0
   2292 copy_setports ns3/named6.conf.in ns3/named.conf
   2293 if [ $ret != 0 ]; then echo_i "failed"; fi
   2294 status=$((status + ret))
   2295 
   2296 n=$((n + 1))
   2297 echo_i "running 'rndc reload' ($n)"
   2298 ret=0
   2299 rndc_reload ns3 10.53.0.3
   2300 if [ $ret != 0 ]; then echo_i "failed"; fi
   2301 status=$((status + ret))
   2302 
   2303 # Disable responses from authoritative server. If we can't resolve the example
   2304 # zone, fetch limits will be reached.
   2305 n=$((n + 1))
   2306 echo_i "disable responses from authoritative server ($n)"
   2307 ret=0
   2308 $DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1
   2309 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2310 grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1
   2311 if [ $ret != 0 ]; then echo_i "failed"; fi
   2312 status=$((status + ret))
   2313 
   2314 # Allow RRset to become stale.
   2315 sleep 2
   2316 
   2317 # Turn on serve-stale.
   2318 n=$((n + 1))
   2319 echo_i "running 'rndc serve-stale on' ($n)"
   2320 ret=0
   2321 $RNDCCMD 10.53.0.3 serve-stale on || ret=1
   2322 if [ $ret != 0 ]; then echo_i "failed"; fi
   2323 status=$((status + ret))
   2324 
   2325 n=$((n + 1))
   2326 echo_i "check 'rndc serve-stale status' ($n)"
   2327 ret=0
   2328 $RNDCCMD 10.53.0.3 serve-stale status >rndc.out.test$n 2>&1 || ret=1
   2329 grep '_default: stale cache enabled; stale answers enabled (stale-answer-ttl=3 max-stale-ttl=3600 stale-refresh-time=4)' rndc.out.test$n >/dev/null || ret=1
   2330 if [ $ret != 0 ]; then echo_i "failed"; fi
   2331 status=$((status + ret))
   2332 
   2333 # Hit the fetch-limits. We burst the name server with a small batch of queries.
   2334 # Only 2 queries are required to hit the fetch-limits. The first query will
   2335 # start to resolve, the second one hit the fetch-limits.
   2336 burst() {
   2337   num=${1}
   2338   rm -f burst.input.$$
   2339   while [ $num -gt 0 ]; do
   2340     num=$((num - 1))
   2341     echo "fetch${num}.example A" >>burst.input.$$
   2342   done
   2343   $PERL ../ditch.pl -p ${PORT} -s 10.53.0.3 -b ${EXTRAPORT8} burst.input.$$
   2344   rm -f burst.input.$$
   2345 }
   2346 
   2347 wait_for_fetchlimits() {
   2348   burst 2
   2349   # We expect a query for nx.example to fail because fetch-limits for
   2350   # the domain 'example.' (and everything below) has been reached.
   2351   $DIG -p ${PORT} +tries=1 +timeout=1 @10.53.0.3 nx.example >dig.out.test$n || return 1
   2352   grep "status: SERVFAIL" dig.out.test$n >/dev/null || return 1
   2353 }
   2354 
   2355 n=$((n + 1))
   2356 echo_i "hit fetch limits ($n)"
   2357 ret=0
   2358 retry_quiet 10 wait_for_fetchlimits || ret=1
   2359 if [ $ret != 0 ]; then echo_i "failed"; fi
   2360 status=$((status + ret))
   2361 
   2362 # Expect stale data now (because fetch-limits for the domain 'example.' (and
   2363 # everything below) has been reached. But we have a stale RRset for
   2364 # 'data.example/TXT' that can be used.
   2365 n=$((n + 1))
   2366 ret=0
   2367 echo_i "check stale data.example TXT comes from cache (fetch-limits) ($n)"
   2368 nextpart ns3/named.run >/dev/null
   2369 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   2370 wait_for_log 5 "data.example TXT resolver failure, stale answer used" ns3/named.run || ret=1
   2371 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2372 grep "EDE: 3 (Stale Answer): (resolver failure" dig.out.test$n >/dev/null || ret=1
   2373 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2374 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   2375 if [ $ret != 0 ]; then echo_i "failed"; fi
   2376 status=$((status + ret))
   2377 
   2378 # The previous query should not have started the stale-refresh-time window.
   2379 n=$((n + 1))
   2380 ret=0
   2381 echo_i "check stale data.example TXT comes from cache again (fetch-limits) ($n)"
   2382 nextpart ns3/named.run >/dev/null
   2383 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1
   2384 wait_for_log 5 "data.example TXT resolver failure, stale answer used" ns3/named.run || ret=1
   2385 grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1
   2386 grep "EDE: 3 (Stale Answer): (resolver failure" dig.out.test$n >/dev/null || ret=1
   2387 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1
   2388 grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1
   2389 if [ $ret != 0 ]; then echo_i "failed"; fi
   2390 status=$((status + ret))
   2391 
   2392 ########################################################################
   2393 # Test serve-stale's interaction with fetch limits (dual-mode) #
   2394 ########################################################################
   2395 echo_i "test serve-stale's interaction with fetch limits (dual-mode)"
   2396 
   2397 # Update named configuration so that ns3 becomes a recursive resolver which is
   2398 # also a secondary server for the root zone.
   2399 n=$((n + 1))
   2400 echo_i "updating ns3/named.conf ($n)"
   2401 ret=0
   2402 copy_setports ns3/named7.conf.in ns3/named.conf
   2403 if [ $ret != 0 ]; then echo_i "failed"; fi
   2404 status=$((status + ret))
   2405 
   2406 n=$((n + 1))
   2407 echo_i "running 'rndc reload' ($n)"
   2408 ret=0
   2409 rndc_reload ns3 10.53.0.3
   2410 if [ $ret != 0 ]; then echo_i "failed"; fi
   2411 status=$((status + ret))
   2412 
   2413 n=$((n + 1))
   2414 echo_i "check 'rndc serve-stale status' ($n)"
   2415 ret=0
   2416 $RNDCCMD 10.53.0.3 serve-stale status >rndc.out.test$n 2>&1 || ret=1
   2417 grep '_default: stale cache enabled; stale answers enabled (stale-answer-ttl=3 max-stale-ttl=3600 stale-refresh-time=4)' rndc.out.test$n >/dev/null || ret=1
   2418 if [ $ret != 0 ]; then echo_i "failed"; fi
   2419 status=$((status + ret))
   2420 
   2421 # Flush the cache to ensure the example/NS RRset cached during previous tests
   2422 # does not override the authoritative delegation found in the root zone.
   2423 n=$((n + 1))
   2424 echo_i "flush cache ($n)"
   2425 ret=0
   2426 $RNDCCMD 10.53.0.3 flush >rndc.out.test$n 2>&1 || ret=1
   2427 if [ $ret != 0 ]; then echo_i "failed"; fi
   2428 status=$((status + ret))
   2429 
   2430 # Test that after flush, serve-stale configuration is not reset.
   2431 n=$((n + 1))
   2432 echo_i "check serve-stale configuration is not reset after flush ($n)"
   2433 ret=0
   2434 $RNDCCMD 10.53.0.3 serve-stale status >rndc.out.test$n 2>&1 || ret=1
   2435 grep '_default: stale cache enabled; stale answers enabled (stale-answer-ttl=3 max-stale-ttl=3600 stale-refresh-time=4)' rndc.out.test$n >/dev/null || ret=1
   2436 if [ $ret != 0 ]; then echo_i "failed"; fi
   2437 status=$((status + ret))
   2438 
   2439 # Query name server with low fetch limits. The authoritative server (ans2) is
   2440 # not responding. Sending queries for multiple names in the 'example' zone
   2441 # in parallel causes the fetch limit for that zone (set to 1) to be
   2442 # reached. This should not trigger a crash.
   2443 echo_i "sending queries for tests $((n + 1))-$((n + 4))..."
   2444 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$((n + 1)) &
   2445 $DIG -p ${PORT} @10.53.0.3 othertype.example CAA >dig.out.test$((n + 2)) &
   2446 $DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$((n + 3)) &
   2447 $DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT >dig.out.test$((n + 4)) &
   2448 
   2449 wait
   2450 
   2451 # Expect SERVFAIL for the entries not in cache.
   2452 n=$((n + 1))
   2453 echo_i "check stale data.example TXT (fetch-limits dual-mode) ($n)"
   2454 ret=0
   2455 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   2456 if [ $ret != 0 ]; then echo_i "failed"; fi
   2457 status=$((status + ret))
   2458 
   2459 n=$((n + 1))
   2460 echo_i "check stale othertype.example CAA (fetch-limits dual-mode) ($n)"
   2461 ret=0
   2462 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   2463 if [ $ret != 0 ]; then echo_i "failed"; fi
   2464 status=$((status + ret))
   2465 
   2466 n=$((n + 1))
   2467 echo_i "check stale nodata.example TXT (fetch-limits dual-mode) ($n)"
   2468 ret=0
   2469 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   2470 if [ $ret != 0 ]; then echo_i "failed"; fi
   2471 status=$((status + ret))
   2472 
   2473 n=$((n + 1))
   2474 echo_i "check stale nxdomain.example TXT (fetch-limits dual-mode) ($n)"
   2475 ret=0
   2476 grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1
   2477 if [ $ret != 0 ]; then echo_i "failed"; fi
   2478 status=$((status + ret))
   2479 
   2480 n=$((n + 1))
   2481 echo_i "check DNS64 processing of a stale negative answer ($n)"
   2482 ret=0
   2483 # configure ns3 with dns64
   2484 copy_setports ns3/named8.conf.in ns3/named.conf
   2485 rndc_reload ns3 10.53.0.3
   2486 # flush cache, enable ans2 responses, make sure serve-stale is on
   2487 $RNDCCMD 10.53.0.3 flush >rndc.out.test$n.1 2>&1 || ret=1
   2488 $DIG -p ${PORT} @10.53.0.2 txt enable >/dev/null || ret=1
   2489 $RNDCCMD 10.53.0.3 serve-stale on >rndc.out.test$n.2 2>&1 || ret=1
   2490 # prime the cache with an AAAA NXRRSET response
   2491 $DIG -p ${PORT} @10.53.0.3 a-only.example AAAA >dig.out.1.test$n || ret=1
   2492 grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
   2493 grep "2001:aaaa" dig.out.1.test$n >/dev/null || ret=1
   2494 # disable responses from the auth server
   2495 $DIG -p ${PORT} @10.53.0.2 txt disable >/dev/null || ret=1
   2496 # wait two seconds for the previous answer to become stale
   2497 sleep 2
   2498 # resend the query and wait in the background; we should get a stale answer
   2499 $DIG -p ${PORT} @10.53.0.3 a-only.example AAAA >dig.out.2.test$n &
   2500 # re-enable queries after a pause, so the server gets a real answer too
   2501 sleep 2
   2502 $DIG -p ${PORT} @10.53.0.2 txt enable >/dev/null || ret=1
   2503 wait
   2504 grep "status: NOERROR" dig.out.2.test$n >/dev/null || ret=1
   2505 grep "2001:aaaa" dig.out.2.test$n >/dev/null || ret=1
   2506 if [ $ret != 0 ]; then echo_i "failed"; fi
   2507 status=$((status + ret))
   2508 
   2509 n=$((n + 1))
   2510 echo_i "check serve-stale (stale-answer-client-timeout 0) with a delegation ($n)"
   2511 ret=0
   2512 # configure ns3 with stale-answer-client-timeout 0 and a delegated zone
   2513 copy_setports ns3/named9.conf.in ns3/named.conf
   2514 rndc_reload ns3 10.53.0.3
   2515 # flush cache, enable ans2 responses, make sure serve-stale is on
   2516 $RNDCCMD 10.53.0.3 flush >rndc.out.test$n.1 2>&1 || ret=1
   2517 $DIG -p ${PORT} @10.53.0.2 txt enable >/dev/null || ret=1
   2518 $RNDCCMD 10.53.0.3 serve-stale on >rndc.out.test$n.2 2>&1 || ret=1
   2519 # prime the cache with the A response
   2520 $DIG -p ${PORT} @10.53.0.3 www.delegated.serve.stale >dig.out.1.test$n || ret=1
   2521 grep -F "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1
   2522 grep -F "10.53.0.99" dig.out.1.test$n >/dev/null || ret=1
   2523 # disable responses from the auth server
   2524 $DIG -p ${PORT} @10.53.0.2 txt disable >/dev/null || ret=1
   2525 # wait two seconds for the previous answer to become stale
   2526 sleep 2
   2527 # resend the query; we should immediately get a stale answer
   2528 $DIG -p ${PORT} @10.53.0.3 www.delegated.serve.stale >dig.out.2.test$n || ret=1
   2529 grep -F "status: NOERROR" dig.out.2.test$n >/dev/null || ret=1
   2530 grep -F "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.2.test$n >/dev/null || ret=1
   2531 grep -F "10.53.0.99" dig.out.2.test$n >/dev/null || ret=1
   2532 # re-enable responses
   2533 $DIG -p ${PORT} @10.53.0.2 txt enable >/dev/null || ret=1
   2534 if [ $ret != 0 ]; then echo_i "failed"; fi
   2535 status=$((status + ret))
   2536 
   2537 echo_i "exit status: $status"
   2538 [ $status -eq 0 ] || exit 1
   2539