1#!/bin/sh
2
3# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
4#
5# SPDX-License-Identifier: MPL-2.0
6#
7# This Source Code Form is subject to the terms of the Mozilla Public
8# License, v. 2.0.  If a copy of the MPL was not distributed with this
9# file, you can obtain one at https://mozilla.org/MPL/2.0/.
10#
11# See the COPYRIGHT file distributed with this work for additional
12# information regarding copyright ownership.
13
14set -e
15
16# shellcheck source=conf.sh
17. ../conf.sh
18
19status=0
20n=0
21
22rm -f dig.out.*
23
24dig_with_opts() {
25  "$DIG" +tcp +noadd +nosea +nostat +nocmd -p "$PORT" "$@"
26}
27
28rndc_with_opts() {
29  "$RNDC" -c ../_common/rndc.conf -p "$CONTROLPORT" -s "$@"
30}
31
32echo_i "checking DNSSEC SERVFAIL is cached ($n)"
33ret=0
34dig_with_opts +dnssec foo.example. a @10.53.0.5 >dig.out.ns5.test$n || ret=1
35rndc_dumpdb ns5 -all
36awk '/Zone/{out=0} { if (out) print } /SERVFAIL/{out=1}' ns5/named_dump.db.test$n >sfcache.$n
37grep "^; foo.example/A" sfcache.$n >/dev/null || ret=1
38n=$((n + 1))
39if [ $ret != 0 ]; then echo_i "failed"; fi
40status=$((status + ret))
41
42echo_i "checking SERVFAIL is returned from cache ($n)"
43ret=0
44dig_with_opts +dnssec foo.example. a @10.53.0.5 >dig.out.ns5.test$n || ret=1
45grep "SERVFAIL" dig.out.ns5.test$n >/dev/null || ret=1
46n=$((n + 1))
47if [ $ret != 0 ]; then echo_i "failed"; fi
48status=$((status + ret))
49
50echo_i "checking that +cd bypasses cache check ($n)"
51ret=0
52dig_with_opts +dnssec +cd foo.example. a @10.53.0.5 >dig.out.ns5.test$n || ret=1
53grep "SERVFAIL" dig.out.ns5.test$n >/dev/null && ret=1
54n=$((n + 1))
55if [ $ret != 0 ]; then echo_i "failed"; fi
56status=$((status + ret))
57
58echo_i "switching to non-dnssec SERVFAIL tests"
59ret=0
60rndc_with_opts 10.53.0.5 flush 2>&1 | sed 's/^/I:ns5 /'
61rndc_dumpdb ns5 -all
62mv ns5/named_dump.db.test$n ns5/named_dump.db.test$n.1
63awk '/SERVFAIL/ { next; out=1 } /Zone/ { out=0 } { if (out) print }' ns5/named_dump.db.test$n.1 >sfcache.$n.1
64[ -s "sfcache.$n.1" ] && ret=1
65echo_i "checking SERVFAIL is cached ($n)"
66dig_with_opts bar.example2. a @10.53.0.5 >dig.out.ns5.test$n || ret=1
67rndc_dumpdb ns5 -all
68mv ns5/named_dump.db.test$n ns5/named_dump.db.test$n.2
69awk '/Zone/{out=0} { if (out) print } /SERVFAIL/{out=1}' ns5/named_dump.db.test$n.2 >sfcache.$n.2
70grep "^; bar.example2/A" sfcache.$n.2 >/dev/null || ret=1
71n=$((n + 1))
72if [ $ret != 0 ]; then echo_i "failed"; fi
73status=$((status + ret))
74
75echo_i "checking SERVFAIL is returned from cache ($n)"
76ret=0
77nextpart ns5/named.run >/dev/null
78dig_with_opts bar.example2. a @10.53.0.5 >dig.out.ns5.test$n || ret=1
79grep "SERVFAIL" dig.out.ns5.test$n >/dev/null || ret=1
80nextpart ns5/named.run >ns5/named.run.part$n
81grep 'servfail cache hit bar.example2/A (CD=0)' ns5/named.run.part$n >/dev/null || ret=1
82n=$((n + 1))
83if [ $ret != 0 ]; then echo_i "failed"; fi
84status=$((status + ret))
85
86echo_i "checking cache is bypassed with +cd query ($n)"
87ret=0
88dig_with_opts +cd bar.example2. a @10.53.0.5 >dig.out.ns5.test$n || ret=1
89grep "SERVFAIL" dig.out.ns5.test$n >/dev/null || ret=1
90nextpart ns5/named.run >ns5/named.run.part$n
91grep 'servfail cache hit' ns5/named.run.part$n >/dev/null && ret=1
92n=$((n + 1))
93if [ $ret != 0 ]; then echo_i "failed"; fi
94status=$((status + ret))
95
96echo_i "checking cache is used for subsequent +cd query ($n)"
97ret=0
98dig_with_opts +dnssec bar.example2. a @10.53.0.5 >dig.out.ns5.test$n || ret=1
99grep "SERVFAIL" dig.out.ns5.test$n >/dev/null || ret=1
100nextpart ns5/named.run >ns5/named.run.part$n
101grep 'servfail cache hit bar.example2/A (CD=1)' ns5/named.run.part$n >/dev/null || ret=1
102n=$((n + 1))
103if [ $ret != 0 ]; then echo_i "failed"; fi
104status=$((status + ret))
105
106echo_i "exit status: $status"
107[ $status -eq 0 ] || exit 1
108