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