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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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)) || true 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 || ret=1 276 grep "status: SERVFAIL" dig.out.test$n.$num >/dev/null || ret=1 277 if [ $ret != 0 ]; then num=$threshold; fi 278 279 sleep 1 280 num=$((num + 1)) 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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)) || true 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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)) || true 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 || ret=1 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 off. # 1683############################################# 1684echo_i "test stale-answer-client-timeout (off)" 1685 1686n=$((n + 1)) 1687echo_i "updating ns3/named.conf ($n)" 1688ret=0 1689copy_setports ns3/named3.conf.in ns3/named.conf 1690if [ $ret != 0 ]; then echo_i "failed"; fi 1691status=$((status + ret)) 1692 1693n=$((n + 1)) 1694echo_i "running 'rndc reload' ($n)" 1695ret=0 1696rndc_reload ns3 10.53.0.3 1697if [ $ret != 0 ]; then echo_i "failed"; fi 1698status=$((status + ret)) 1699 1700# Send a query, auth server is disabled, we will enable it after a while in 1701# order to receive an answer before resolver-query-timeout expires. Since 1702# stale-answer-client-timeout is disabled we must receive an answer from 1703# authoritative server. 1704echo_i "sending query for test $((n + 2))" 1705$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$((n + 2)) & 1706sleep 3 1707 1708n=$((n + 1)) 1709echo_i "enable responses from authoritative server ($n)" 1710ret=0 1711$DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1 1712grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 1713grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1 1714if [ $ret != 0 ]; then echo_i "failed"; fi 1715status=$((status + ret)) 1716 1717# Wait until dig is done. 1718wait 1719 1720n=$((n + 1)) 1721echo_i "check data.example TXT comes from authoritative server (stale-answer-client-timeout off) ($n)" 1722grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 1723grep "EDE" dig.out.test$n >/dev/null && ret=1 1724grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 1725grep "data\.example\..*[12].*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1 1726if [ $ret != 0 ]; then echo_i "failed"; fi 1727status=$((status + ret)) 1728 1729check_server_responds() { 1730 $DIG -p ${PORT} @10.53.0.3 version.bind txt ch >dig.out.test$n || return 1 1731 grep "status: NOERROR" dig.out.test$n >/dev/null || return 1 1732} 1733 1734############################################################## 1735# Test for stale-answer-client-timeout off and CNAME record. # 1736############################################################## 1737echo_i "test stale-answer-client-timeout (0) and CNAME record" 1738 1739n=$((n + 1)) 1740echo_i "prime cache shortttl.cname.example (stale-answer-client-timeout off) ($n)" 1741ret=0 1742$DIG -p ${PORT} @10.53.0.3 shortttl.cname.example A >dig.out.test$n || ret=1 1743grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 1744grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1 1745grep "shortttl\.cname\.example\..*1.*IN.*CNAME.*longttl\.target\.example\." dig.out.test$n >/dev/null || ret=1 1746grep "longttl\.target\.example\..*600.*IN.*A.*10\.53\.0\.2" dig.out.test$n >/dev/null || ret=1 1747if [ $ret != 0 ]; then echo_i "failed"; fi 1748status=$((status + ret)) 1749 1750# Allow RRset to become stale. 1751sleep 1 1752 1753n=$((n + 1)) 1754echo_i "disable responses from authoritative server ($n)" 1755ret=0 1756$DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1 1757grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 1758grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1 1759if [ $ret != 0 ]; then echo_i "failed"; fi 1760status=$((status + ret)) 1761 1762n=$((n + 1)) 1763ret=0 1764echo_i "check stale shortttl.cname.example comes from cache (stale-answer-client-timeout off) ($n)" 1765nextpart ns3/named.run >/dev/null 1766$DIG -p ${PORT} @10.53.0.3 shortttl.cname.example A >dig.out.test$n || ret=1 1767wait_for_log 5 "shortttl.cname.example A resolver failure, stale answer used" ns3/named.run || ret=1 1768grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 1769grep "EDE: 3 (Stale Answer): (resolver failure)" dig.out.test$n >/dev/null || ret=1 1770grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1 1771grep "shortttl\.cname\.example\..*3.*IN.*CNAME.*longttl\.target\.example\." dig.out.test$n >/dev/null || ret=1 1772# We can't reliably test the TTL of the longttl.target.example A record. 1773grep "longttl\.target\.example\..*IN.*A.*10\.53\.0\.2" dig.out.test$n >/dev/null || ret=1 1774if [ $ret != 0 ]; then echo_i "failed"; fi 1775status=$((status + ret)) 1776 1777n=$((n + 1)) 1778echo_i "enable responses from authoritative server ($n)" 1779ret=0 1780$DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1 1781grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 1782grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1 1783if [ $ret != 0 ]; then echo_i "failed"; fi 1784status=$((status + ret)) 1785 1786n=$((n + 1)) 1787echo_i "check server is alive or restart ($n)" 1788ret=0 1789$RNDCCMD 10.53.0.3 status >rndc.out.test$n 2>&1 || ret=1 1790if [ $ret != 0 ]; then 1791 echo_i "failed" 1792 echo_i "restart ns3" 1793 start_server --noclean --restart --port ${PORT} serve-stale ns3 1794fi 1795status=$((status + ret)) 1796 1797n=$((n + 1)) 1798echo_i "check server is alive or restart ($n)" 1799ret=0 1800$RNDCCMD 10.53.0.3 status >rndc.out.test$n 2>&1 || ret=1 1801if [ $ret != 0 ]; then 1802 echo_i "failed" 1803 echo_i "restart ns3" 1804 start_server --noclean --restart --port ${PORT} serve-stale ns3 1805fi 1806status=$((status + ret)) 1807 1808############################################# 1809# Test for stale-answer-client-timeout 0. # 1810############################################# 1811echo_i "test stale-answer-client-timeout (0)" 1812 1813n=$((n + 1)) 1814echo_i "updating ns3/named.conf ($n)" 1815ret=0 1816copy_setports ns3/named4.conf.in ns3/named.conf 1817if [ $ret != 0 ]; then echo_i "failed"; fi 1818status=$((status + ret)) 1819 1820echo_i "restart ns3" 1821stop_server --use-rndc --port ${CONTROLPORT} ns3 1822start_server --noclean --restart --port ${PORT} ns3 1823 1824n=$((n + 1)) 1825echo_i "prime cache data.example TXT (stale-answer-client-timeout 0)" 1826ret=0 1827$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1 1828grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 1829grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 1830if [ $ret != 0 ]; then echo_i "failed"; fi 1831status=$((status + ret)) 1832 1833n=$((n + 1)) 1834echo_i "prime cache nodata.example TXT (stale-answer-client-timeout 0)" 1835ret=0 1836$DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$n || ret=1 1837grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 1838grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1 1839if [ $ret != 0 ]; then echo_i "failed"; fi 1840status=$((status + ret)) 1841 1842n=$((n + 1)) 1843echo_i "disable responses from authoritative server ($n)" 1844ret=0 1845$DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1 1846grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 1847grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1 1848if [ $ret != 0 ]; then echo_i "failed"; fi 1849status=$((status + ret)) 1850 1851# Allow RRset to become stale. 1852sleep 2 1853 1854n=$((n + 1)) 1855ret=0 1856echo_i "check stale nodata.example TXT comes from cache (stale-answer-client-timeout 0) ($n)" 1857nextpart ns3/named.run >/dev/null 1858$DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$n || ret=1 1859wait_for_log 5 "nodata.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1 1860grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 1861grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1 1862grep "ANSWER: 0," dig.out.test$n >/dev/null || ret=1 1863grep "example\..*3.*IN.*SOA" dig.out.test$n >/dev/null || ret=1 1864if [ $ret != 0 ]; then echo_i "failed"; fi 1865status=$((status + ret)) 1866 1867n=$((n + 1)) 1868ret=0 1869echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0) ($n)" 1870nextpart ns3/named.run >/dev/null 1871$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1 1872wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1 1873grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 1874grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1 1875grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 1876grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1 1877if [ $ret != 0 ]; then echo_i "failed"; fi 1878status=$((status + ret)) 1879 1880n=$((n + 1)) 1881echo_i "enable responses from authoritative server ($n)" 1882ret=0 1883$DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1 1884grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 1885grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1 1886if [ $ret != 0 ]; then echo_i "failed"; fi 1887status=$((status + ret)) 1888 1889wait_for_rrset_refresh() { 1890 $DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || return 1 1891 grep "status: NOERROR" dig.out.test$n >/dev/null || return 1 1892 grep "EDE" dig.out.test$n >/dev/null && return 1 1893 grep "ANSWER: 1," dig.out.test$n >/dev/null || return 1 1894 grep "data\.example\..*[12].*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || return 1 1895} 1896 1897# This test ensures that after we get stale data due to 1898# stale-answer-client-timeout 0, enabling the authoritative server will allow 1899# the RRset to be updated. 1900n=$((n + 1)) 1901ret=0 1902echo_i "check stale data.example TXT was refreshed (stale-answer-client-timeout 0) ($n)" 1903retry_quiet 10 wait_for_rrset_refresh || ret=1 1904if [ $ret != 0 ]; then echo_i "failed"; fi 1905status=$((status + ret)) 1906 1907wait_for_nodata_refresh() { 1908 $DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$n || return 1 1909 grep "status: NOERROR" dig.out.test$n >/dev/null || return 1 1910 grep "ANSWER: 0," dig.out.test$n >/dev/null || return 1 1911 grep "example\..*[12].*IN.*SOA" dig.out.test$n >/dev/null || return 1 1912 return 0 1913} 1914 1915n=$((n + 1)) 1916ret=0 1917echo_i "check stale nodata.example TXT was refreshed (stale-answer-client-timeout 0) ($n)" 1918retry_quiet 10 wait_for_nodata_refresh || ret=1 1919if [ $ret != 0 ]; then echo_i "failed"; fi 1920status=$((status + ret)) 1921 1922#################################################################### 1923# Test for stale-answer-client-timeout 0 and recursive-clients 10. # 1924# CVE-2023-2911, GL #4089 # 1925# ################################################################## 1926echo_i "test stale-answer-client-timeout (0) and recursive-clients 10" 1927 1928n=$((n + 1)) 1929echo_i "prime cache data.slow TXT (stale-answer-client-timeout 0) ($n)" 1930ret=0 1931$DIG -p ${PORT} @10.53.0.3 data.slow TXT >dig.out.test$n || ret=1 1932grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 1933grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 1934if [ $ret != 0 ]; then echo_i "failed"; fi 1935status=$((status + ret)) 1936 1937# Run the following check twice. Sometimes a priming query interrupts the first 1938# attempt to exceed the quota. 1939attempt=0 1940while [ $ret -eq 0 ] && [ $attempt -lt 2 ]; do 1941 n=$((n + 1)) 1942 echo_i "slow down response from authoritative server ($n)" 1943 ret=0 1944 $DIG -p ${PORT} @10.53.0.2 slowdown TXT >dig.out.test$n || ret=1 1945 grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 1946 grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1 1947 if [ $ret != 0 ]; then echo_i "failed"; fi 1948 status=$((status + ret)) 1949 1950 # Let the data.slow TTL expire 1951 sleep 2 1952 1953 n=$((n + 1)) 1954 echo_i "check that named survives reaching recursive-clients quota (stale-answer-client-timeout 0) ($n)" 1955 ret=0 1956 num=0 1957 # Attempt to exceed the configured value of 'recursive-clients 10;' by running 1958 # 20 parallel queries for the stale domain which has slow auth. 1959 while [ $num -lt 20 ]; do 1960 $DIG +tries=1 +timeout=10 -p ${PORT} @10.53.0.3 data.slow TXT >/dev/null 2>&1 & 1961 num=$((num + 1)) 1962 done 1963 # Let the dig processes finish. 1964 wait 1965 retry_quiet 5 check_server_responds || ret=1 1966 if [ $ret != 0 ]; then echo_i "failed"; fi 1967 status=$((status + ret)) 1968 1969 attempt=$((attempt + 1)) 1970done 1971 1972# Restart ns3 to avoid the exceeded recursive-clients limit from previous check 1973# to interfere with subsequent checks. 1974echo_i "restart ns3" 1975stop_server --use-rndc --port ${CONTROLPORT} ns3 1976start_server --noclean --restart --port ${PORT} ns3 1977 1978############################################################ 1979# Test for stale-answer-client-timeout 0 and CNAME record. # 1980############################################################ 1981echo_i "test stale-answer-client-timeout (0) and CNAME record" 1982 1983n=$((n + 1)) 1984echo_i "prime cache cname1.stale.test A (stale-answer-client-timeout 0) ($n)" 1985ret=0 1986$DIG -p ${PORT} @10.53.0.3 cname1.stale.test A >dig.out.test$n || ret=1 1987grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 1988grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1 1989grep "cname1\.stale\.test\..*1.*IN.*CNAME.*a1\.stale\.test\." dig.out.test$n >/dev/null || ret=1 1990grep "a1\.stale\.test\..*1.*IN.*A.*192\.0\.2\.1" dig.out.test$n >/dev/null || ret=1 1991if [ $ret != 0 ]; then echo_i "failed"; fi 1992status=$((status + ret)) 1993 1994# Allow RRset to become stale. 1995sleep 1 1996 1997n=$((n + 1)) 1998ret=0 1999echo_i "check stale cname1.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)" 2000nextpart ns3/named.run >/dev/null 2001$DIG -p ${PORT} @10.53.0.3 cname1.stale.test A >dig.out.test$n || ret=1 2002wait_for_log 5 "cname1.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1 2003grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2004grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1 2005grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1 2006grep "cname1\.stale\.test\..*3.*IN.*CNAME.*a1\.stale\.test\." dig.out.test$n >/dev/null || ret=1 2007grep "a1\.stale\.test\..*3.*IN.*A.*192\.0\.2\.1" dig.out.test$n >/dev/null || ret=1 2008if [ $ret != 0 ]; then echo_i "failed"; fi 2009status=$((status + ret)) 2010 2011n=$((n + 1)) 2012echo_i "check server is alive or restart ($n)" 2013ret=0 2014$RNDCCMD 10.53.0.3 status >rndc.out.test$n 2>&1 || ret=1 2015if [ $ret != 0 ]; then 2016 echo_i "failed" 2017 echo_i "restart ns3" 2018 start_server --noclean --restart --port ${PORT} ns3 2019fi 2020status=$((status + ret)) 2021 2022n=$((n + 1)) 2023echo_i "prime cache cname2.stale.test A (stale-answer-client-timeout 0) ($n)" 2024ret=0 2025$DIG -p ${PORT} @10.53.0.3 cname2.stale.test A >dig.out.test$n || ret=1 2026grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2027grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1 2028grep "cname2\.stale\.test\..*1.*IN.*CNAME.*a2\.stale\.test\." dig.out.test$n >/dev/null || ret=1 2029grep "a2\.stale\.test\..*300.*IN.*A.*192\.0\.2\.2" dig.out.test$n >/dev/null || ret=1 2030if [ $ret != 0 ]; then echo_i "failed"; fi 2031status=$((status + ret)) 2032 2033# Allow CNAME record in the RRSET to become stale. 2034sleep 1 2035 2036n=$((n + 1)) 2037ret=0 2038echo_i "check stale cname2.stale.test A comes from cache (stale-answer-client-timeout 0) ($n)" 2039nextpart ns3/named.run >/dev/null 2040$DIG -p ${PORT} @10.53.0.3 cname2.stale.test A >dig.out.test$n || ret=1 2041wait_for_log 5 "cname2.stale.test A stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1 2042grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2043grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1 2044grep "ANSWER: 2," dig.out.test$n >/dev/null || ret=1 2045grep "cname2\.stale\.test\..*3.*IN.*CNAME.*a2\.stale\.test\." dig.out.test$n >/dev/null || ret=1 2046# We can't reliably test the TTL of the a2.stale.test A record. 2047grep "a2\.stale\.test\..*IN.*A.*192\.0\.2\.2" dig.out.test$n >/dev/null || ret=1 2048if [ $ret != 0 ]; then echo_i "failed"; fi 2049status=$((status + ret)) 2050 2051n=$((n + 1)) 2052echo_i "check server is alive or restart ($n)" 2053ret=0 2054$RNDCCMD 10.53.0.3 status >rndc.out.test$n 2>&1 || ret=1 2055if [ $ret != 0 ]; then 2056 echo_i "failed" 2057 echo_i "restart ns3" 2058 start_server --noclean --restart --port ${PORT} ns3 2059fi 2060status=$((status + ret)) 2061 2062#################################################################### 2063# Test for stale-answer-client-timeout 0 and stale-refresh-time 4. # 2064#################################################################### 2065echo_i "test stale-answer-client-timeout (0) and stale-refresh-time (4)" 2066 2067n=$((n + 1)) 2068echo_i "updating ns3/named.conf ($n)" 2069ret=0 2070copy_setports ns3/named5.conf.in ns3/named.conf 2071if [ $ret != 0 ]; then echo_i "failed"; fi 2072status=$((status + ret)) 2073 2074n=$((n + 1)) 2075echo_i "running 'rndc reload' ($n)" 2076ret=0 2077rndc_reload ns3 10.53.0.3 2078if [ $ret != 0 ]; then echo_i "failed"; fi 2079status=$((status + ret)) 2080 2081n=$((n + 1)) 2082echo_i "flush cache, enable responses from authoritative server ($n)" 2083ret=0 2084$RNDCCMD 10.53.0.3 flushtree example >rndc.out.test$n.1 2>&1 || ret=1 2085$DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1 2086grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2087grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1 2088if [ $ret != 0 ]; then echo_i "failed"; fi 2089status=$((status + ret)) 2090 2091n=$((n + 1)) 2092echo_i "prime cache data.example TXT (stale-answer-client-timeout 0, stale-refresh-time 4) ($n)" 2093ret=0 2094$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1 2095grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2096grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2097grep "data\.example\..*2.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1 2098if [ $ret != 0 ]; then echo_i "failed"; fi 2099status=$((status + ret)) 2100 2101# Allow RRset to become stale. 2102sleep 2 2103 2104n=$((n + 1)) 2105echo_i "disable responses from authoritative server ($n)" 2106ret=0 2107$DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1 2108grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2109grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1 2110if [ $ret != 0 ]; then echo_i "failed"; fi 2111status=$((status + ret)) 2112 2113n=$((n + 1)) 2114ret=0 2115echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)" 2116nextpart ns3/named.run >/dev/null 2117$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1 2118wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1 2119grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2120grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1 2121grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2122grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1 2123if [ $ret != 0 ]; then echo_i "failed"; fi 2124status=$((status + ret)) 2125 2126n=$((n + 1)) 2127echo_i "enable responses from authoritative server ($n)" 2128ret=0 2129$DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1 2130grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2131grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1 2132if [ $ret != 0 ]; then echo_i "failed"; fi 2133status=$((status + ret)) 2134 2135# This test ensures that after we get stale data due to 2136# stale-answer-client-timeout 0, enabling the authoritative server will allow 2137# the RRset to be updated. 2138n=$((n + 1)) 2139ret=0 2140echo_i "check stale data.example TXT was refreshed (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)" 2141retry_quiet 10 wait_for_rrset_refresh || ret=1 2142if [ $ret != 0 ]; then echo_i "failed"; fi 2143status=$((status + ret)) 2144 2145# Allow RRset to become stale. 2146sleep 2 2147 2148n=$((n + 1)) 2149echo_i "disable responses from authoritative server ($n)" 2150ret=0 2151$DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1 2152grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2153grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1 2154if [ $ret != 0 ]; then echo_i "failed"; fi 2155status=$((status + ret)) 2156 2157n=$((n + 1)) 2158ret=0 2159echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)" 2160nextpart ns3/named.run >/dev/null 2161$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1 2162wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1 2163grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2164grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1 2165grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2166grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1 2167if [ $ret != 0 ]; then echo_i "failed"; fi 2168status=$((status + ret)) 2169 2170# Allow stale-refresh-time to be activated. 2171n=$((n + 1)) 2172ret=0 2173echo_i "wait until resolver query times out, activating stale-refresh-time" 2174wait_for_log 15 "data.example/TXT stale refresh failed: timed out" ns3/named.run || ret=1 2175if [ $ret != 0 ]; then echo_i "failed"; fi 2176status=$((status + ret)) 2177 2178n=$((n + 1)) 2179ret=0 2180echo_i "check stale data.example TXT comes from cache within stale-refresh-time (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)" 2181nextpart ns3/named.run >/dev/null 2182$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1 2183wait_for_log 5 "data.example TXT query within stale refresh time" ns3/named.run || ret=1 2184grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2185grep "EDE: 3 (Stale Answer): (query within stale refresh time window)" dig.out.test$n >/dev/null || ret=1 2186grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2187grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1 2188if [ $ret != 0 ]; then echo_i "failed"; fi 2189status=$((status + ret)) 2190 2191n=$((n + 1)) 2192echo_i "enable responses from authoritative server ($n)" 2193ret=0 2194$DIG -p ${PORT} @10.53.0.2 txt enable >dig.out.test$n || ret=1 2195grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2196grep "TXT.\"1\"" dig.out.test$n >/dev/null || ret=1 2197if [ $ret != 0 ]; then echo_i "failed"; fi 2198status=$((status + ret)) 2199 2200# We give BIND some time to ensure that after we enable authoritative server, 2201# this RRset is still not refreshed because it was hit during 2202# stale-refresh-time window. 2203sleep 1 2204 2205n=$((n + 1)) 2206ret=0 2207echo_i "check stale data.example TXT was not refreshed (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)" 2208nextpart ns3/named.run >/dev/null 2209$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1 2210wait_for_log 5 "data.example TXT query within stale refresh time" ns3/named.run || ret=1 2211grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2212grep "EDE: 3 (Stale Answer): (query within stale refresh time window)" dig.out.test$n >/dev/null || ret=1 2213grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2214grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1 2215if [ $ret != 0 ]; then echo_i "failed"; fi 2216status=$((status + ret)) 2217 2218# After the refresh-time-window, the RRset will be refreshed. 2219sleep 4 2220 2221n=$((n + 1)) 2222ret=0 2223echo_i "check stale data.example TXT comes from cache (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)" 2224$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1 2225wait_for_log 5 "data.example TXT stale answer used, an attempt to refresh the RRset" ns3/named.run || ret=1 2226grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2227grep "EDE: 3 (Stale Answer): (stale data prioritized over lookup)" dig.out.test$n >/dev/null || ret=1 2228grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2229grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1 2230if [ $ret != 0 ]; then echo_i "failed"; fi 2231status=$((status + ret)) 2232 2233n=$((n + 1)) 2234ret=0 2235echo_i "check stale data.example TXT was refreshed (stale-answer-client-timeout 0 stale-refresh-time 4) ($n)" 2236$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1 2237grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2238grep "EDE" dig.out.test$n >/dev/null && ret=1 2239grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2240grep "data\.example\..*[12].*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1 2241if [ $ret != 0 ]; then echo_i "failed"; fi 2242status=$((status + ret)) 2243 2244#################################################################### 2245# Test serve-stale's interaction with fetch limits (cache only) # 2246################################################################# 2247echo_i "test serve-stale's interaction with fetch-limits (cache only)" 2248 2249# We update the named configuration to enable fetch-limits. The fetch-limits 2250# are set to 1, which is ridiciously low, but that is because for this test we 2251# want to reach the fetch-limits. 2252n=$((n + 1)) 2253echo_i "updating ns3/named.conf ($n)" 2254ret=0 2255copy_setports ns3/named6.conf.in ns3/named.conf 2256if [ $ret != 0 ]; then echo_i "failed"; fi 2257status=$((status + ret)) 2258 2259n=$((n + 1)) 2260echo_i "running 'rndc reload' ($n)" 2261ret=0 2262rndc_reload ns3 10.53.0.3 2263if [ $ret != 0 ]; then echo_i "failed"; fi 2264status=$((status + ret)) 2265 2266# Disable responses from authoritative server. If we can't resolve the example 2267# zone, fetch limits will be reached. 2268n=$((n + 1)) 2269echo_i "disable responses from authoritative server ($n)" 2270ret=0 2271$DIG -p ${PORT} @10.53.0.2 txt disable >dig.out.test$n || ret=1 2272grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2273grep "TXT.\"0\"" dig.out.test$n >/dev/null || ret=1 2274if [ $ret != 0 ]; then echo_i "failed"; fi 2275status=$((status + ret)) 2276 2277# Allow RRset to become stale. 2278sleep 2 2279 2280# Turn on serve-stale. 2281n=$((n + 1)) 2282echo_i "running 'rndc serve-stale on' ($n)" 2283ret=0 2284$RNDCCMD 10.53.0.3 serve-stale on || ret=1 2285if [ $ret != 0 ]; then echo_i "failed"; fi 2286status=$((status + ret)) 2287 2288n=$((n + 1)) 2289echo_i "check 'rndc serve-stale status' ($n)" 2290ret=0 2291$RNDCCMD 10.53.0.3 serve-stale status >rndc.out.test$n 2>&1 || ret=1 2292grep '_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 2293if [ $ret != 0 ]; then echo_i "failed"; fi 2294status=$((status + ret)) 2295 2296# Hit the fetch-limits. We burst the name server with a small batch of queries. 2297# Only 2 queries are required to hit the fetch-limits. The first query will 2298# start to resolve, the second one hit the fetch-limits. 2299burst() { 2300 num=${1} 2301 rm -f burst.input.$$ 2302 while [ $num -gt 0 ]; do 2303 num=$((num - 1)) 2304 echo "fetch${num}.example A" >>burst.input.$$ 2305 done 2306 $PERL ../ditch.pl -p ${PORT} -s 10.53.0.3 -b ${EXTRAPORT8} burst.input.$$ 2307 rm -f burst.input.$$ 2308} 2309 2310wait_for_fetchlimits() { 2311 burst 2 2312 # We expect a query for nx.example to fail because fetch-limits for 2313 # the domain 'example.' (and everything below) has been reached. 2314 $DIG -p ${PORT} +tries=1 +timeout=1 @10.53.0.3 nx.example >dig.out.test$n || return 1 2315 grep "status: SERVFAIL" dig.out.test$n >/dev/null || return 1 2316} 2317 2318n=$((n + 1)) 2319echo_i "hit fetch limits ($n)" 2320ret=0 2321retry_quiet 10 wait_for_fetchlimits || ret=1 2322if [ $ret != 0 ]; then echo_i "failed"; fi 2323status=$((status + ret)) 2324 2325# Expect stale data now (because fetch-limits for the domain 'example.' (and 2326# everything below) has been reached. But we have a stale RRset for 2327# 'data.example/TXT' that can be used. 2328n=$((n + 1)) 2329ret=0 2330echo_i "check stale data.example TXT comes from cache (fetch-limits) ($n)" 2331nextpart ns3/named.run >/dev/null 2332$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1 2333wait_for_log 5 "data.example TXT resolver failure, stale answer used" ns3/named.run || ret=1 2334grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2335grep "EDE: 3 (Stale Answer): (resolver failure" dig.out.test$n >/dev/null || ret=1 2336grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2337grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1 2338if [ $ret != 0 ]; then echo_i "failed"; fi 2339status=$((status + ret)) 2340 2341# The previous query should not have started the stale-refresh-time window. 2342n=$((n + 1)) 2343ret=0 2344echo_i "check stale data.example TXT comes from cache again (fetch-limits) ($n)" 2345nextpart ns3/named.run >/dev/null 2346$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$n || ret=1 2347wait_for_log 5 "data.example TXT resolver failure, stale answer used" ns3/named.run || ret=1 2348grep "status: NOERROR" dig.out.test$n >/dev/null || ret=1 2349grep "EDE: 3 (Stale Answer): (resolver failure" dig.out.test$n >/dev/null || ret=1 2350grep "ANSWER: 1," dig.out.test$n >/dev/null || ret=1 2351grep "data\.example\..*3.*IN.*TXT.*A text record with a 2 second ttl" dig.out.test$n >/dev/null || ret=1 2352if [ $ret != 0 ]; then echo_i "failed"; fi 2353status=$((status + ret)) 2354 2355######################################################################## 2356# Test serve-stale's interaction with fetch limits (dual-mode) # 2357######################################################################## 2358echo_i "test serve-stale's interaction with fetch limits (dual-mode)" 2359 2360# Update named configuration so that ns3 becomes a recursive resolver which is 2361# also a secondary server for the root zone. 2362n=$((n + 1)) 2363echo_i "updating ns3/named.conf ($n)" 2364ret=0 2365copy_setports ns3/named7.conf.in ns3/named.conf 2366if [ $ret != 0 ]; then echo_i "failed"; fi 2367status=$((status + ret)) 2368 2369n=$((n + 1)) 2370echo_i "running 'rndc reload' ($n)" 2371ret=0 2372rndc_reload ns3 10.53.0.3 2373if [ $ret != 0 ]; then echo_i "failed"; fi 2374status=$((status + ret)) 2375 2376n=$((n + 1)) 2377echo_i "check 'rndc serve-stale status' ($n)" 2378ret=0 2379$RNDCCMD 10.53.0.3 serve-stale status >rndc.out.test$n 2>&1 || ret=1 2380grep '_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 2381if [ $ret != 0 ]; then echo_i "failed"; fi 2382status=$((status + ret)) 2383 2384# Flush the cache to ensure the example/NS RRset cached during previous tests 2385# does not override the authoritative delegation found in the root zone. 2386n=$((n + 1)) 2387echo_i "flush cache ($n)" 2388ret=0 2389$RNDCCMD 10.53.0.3 flush >rndc.out.test$n 2>&1 || ret=1 2390if [ $ret != 0 ]; then echo_i "failed"; fi 2391status=$((status + ret)) 2392 2393# Test that after flush, serve-stale configuration is not reset. 2394n=$((n + 1)) 2395echo_i "check serve-stale configuration is not reset after flush ($n)" 2396ret=0 2397$RNDCCMD 10.53.0.3 serve-stale status >rndc.out.test$n 2>&1 || ret=1 2398grep '_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 2399if [ $ret != 0 ]; then echo_i "failed"; fi 2400status=$((status + ret)) 2401 2402# Query name server with low fetch limits. The authoritative server (ans2) is 2403# not responding. Sending queries for multiple names in the 'example' zone 2404# in parallel causes the fetch limit for that zone (set to 1) to be 2405# reached. This should not trigger a crash. 2406echo_i "sending queries for tests $((n + 1))-$((n + 4))..." 2407$DIG -p ${PORT} @10.53.0.3 data.example TXT >dig.out.test$((n + 1)) & 2408$DIG -p ${PORT} @10.53.0.3 othertype.example CAA >dig.out.test$((n + 2)) & 2409$DIG -p ${PORT} @10.53.0.3 nodata.example TXT >dig.out.test$((n + 3)) & 2410$DIG -p ${PORT} @10.53.0.3 nxdomain.example TXT >dig.out.test$((n + 4)) & 2411 2412wait 2413 2414# Expect SERVFAIL for the entries not in cache. 2415n=$((n + 1)) 2416echo_i "check stale data.example TXT (fetch-limits dual-mode) ($n)" 2417ret=0 2418grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1 2419if [ $ret != 0 ]; then echo_i "failed"; fi 2420status=$((status + ret)) 2421 2422n=$((n + 1)) 2423echo_i "check stale othertype.example CAA (fetch-limits dual-mode) ($n)" 2424ret=0 2425grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1 2426if [ $ret != 0 ]; then echo_i "failed"; fi 2427status=$((status + ret)) 2428 2429n=$((n + 1)) 2430echo_i "check stale nodata.example TXT (fetch-limits dual-mode) ($n)" 2431ret=0 2432grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1 2433if [ $ret != 0 ]; then echo_i "failed"; fi 2434status=$((status + ret)) 2435 2436n=$((n + 1)) 2437echo_i "check stale nxdomain.example TXT (fetch-limits dual-mode) ($n)" 2438ret=0 2439grep "status: SERVFAIL" dig.out.test$n >/dev/null || ret=1 2440if [ $ret != 0 ]; then echo_i "failed"; fi 2441status=$((status + ret)) 2442 2443n=$((n + 1)) 2444echo_i "check DNS64 processing of a stale negative answer ($n)" 2445ret=0 2446# configure ns3 with dns64 2447copy_setports ns3/named8.conf.in ns3/named.conf 2448rndc_reload ns3 10.53.0.3 2449# flush cache, enable ans2 responses, make sure serve-stale is on 2450$RNDCCMD 10.53.0.3 flush >rndc.out.test$n.1 2>&1 || ret=1 2451$DIG -p ${PORT} @10.53.0.2 txt enable >/dev/null || ret=1 2452$RNDCCMD 10.53.0.3 serve-stale on >rndc.out.test$n.2 2>&1 || ret=1 2453# prime the cache with an AAAA NXRRSET response 2454$DIG -p ${PORT} @10.53.0.3 a-only.example AAAA >dig.out.1.test$n || ret=1 2455grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1 2456grep "2001:aaaa" dig.out.1.test$n >/dev/null || ret=1 2457# disable responses from the auth server 2458$DIG -p ${PORT} @10.53.0.2 txt disable >/dev/null || ret=1 2459# wait two seconds for the previous answer to become stale 2460sleep 2 2461# resend the query and wait in the background; we should get a stale answer 2462$DIG -p ${PORT} @10.53.0.3 a-only.example AAAA >dig.out.2.test$n & 2463# re-enable queries after a pause, so the server gets a real answer too 2464sleep 2 2465$DIG -p ${PORT} @10.53.0.2 txt enable >/dev/null || ret=1 2466wait 2467grep "status: NOERROR" dig.out.2.test$n >/dev/null || ret=1 2468grep "2001:aaaa" dig.out.2.test$n >/dev/null || ret=1 2469if [ $ret != 0 ]; then echo_i "failed"; fi 2470status=$((status + ret)) 2471 2472echo_i "exit status: $status" 2473[ $status -eq 0 ] || exit 1 2474