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