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