tests.sh revision 1.1.1.3 1 # Copyright (C) Internet Systems Consortium, Inc. ("ISC")
2 #
3 # This Source Code Form is subject to the terms of the Mozilla Public
4 # License, v. 2.0. If a copy of the MPL was not distributed with this
5 # file, you can obtain one at https://mozilla.org/MPL/2.0/.
6 #
7 # See the COPYRIGHT file distributed with this work for additional
8 # information regarding copyright ownership.
9
10 # test response rate limiting
11
12 SYSTEMTESTTOP=..
13 . $SYSTEMTESTTOP/conf.sh
14
15 RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
16
17 #set -x
18
19 ns1=10.53.0.1 # root, defining the others
20 ns2=10.53.0.2 # test server
21 ns3=10.53.0.3 # secondary test server
22 ns4=10.53.0.4 # log-only test server
23 ns7=10.53.0.7 # whitelisted client
24
25 USAGE="$0: [-x]"
26 while getopts "x" c; do
27 case $c in
28 x) set -x;;
29 *) echo "$USAGE" 1>&2; exit 1;;
30 esac
31 done
32 shift `expr $OPTIND - 1 || true`
33 if test "$#" -ne 0; then
34 echo "$USAGE" 1>&2
35 exit 1
36 fi
37 # really quit on control-C
38 trap 'exit 1' 1 2 15
39
40
41 ret=0
42 setret () {
43 ret=1
44 echo_i "$*"
45 }
46
47
48 # Wait until soon after the start of a second to make results consistent.
49 # The start of a second credits a rate limit.
50 # This would be far easier in C or by assuming a modern version of perl.
51 sec_start () {
52 START=`date`
53 while true; do
54 NOW=`date`
55 if test "$START" != "$NOW"; then
56 return
57 fi
58 $PERL -e 'select(undef, undef, undef, 0.05)' || true
59 done
60 }
61
62
63 # turn off ${HOME}/.digrc
64 HOME=/dev/null; export HOME
65
66 # $1=number of tests $2=target domain $3=dig options
67 QNUM=1
68 burst () {
69 BURST_LIMIT=$1; shift
70 BURST_DOM_BASE="$1"; shift
71
72 XCNT=$CNT
73 CNT='XXX'
74 eval FILENAME="mdig.out-$BURST_DOM_BASE"
75 CNT=$XCNT
76
77 DOMS=""
78 CNTS=`$PERL -e 'for ( $i = 0; $i < '$BURST_LIMIT'; $i++) { printf "%03d\n", '$QNUM' + $i; }'`
79 for CNT in $CNTS
80 do
81 eval BURST_DOM="$BURST_DOM_BASE"
82 DOMS="$DOMS $BURST_DOM"
83 done
84 ARGS="+burst +nocookie +continue +time=1 +tries=1 -p ${PORT} $* @$ns2 $DOMS"
85 $MDIG $ARGS 2>&1 | \
86 tr -d '\r' | \
87 tee -a full-$FILENAME | \
88 sed -n -e '/^;; AUTHORITY/,/^$/d' \
89 -e '/^;; ADDITIONAL/,/^$/d' \
90 -e 's/^[^;].* \([^ ]\{1,\}\)$/\1/p' \
91 -e 's/;; flags.* tc .*/TC/p' \
92 -e 's/;; .* status: NXDOMAIN.*/NXDOMAIN/p' \
93 -e 's/;; .* status: NOERROR.*/NOERROR/p' \
94 -e 's/;; .* status: SERVFAIL.*/SERVFAIL/p' \
95 -e 's/response failed with timed out.*/drop/p' \
96 -e 's/;; communications error to.*/drop/p' >> $FILENAME &
97 QNUM=`expr $QNUM + $BURST_LIMIT`
98 }
99
100 # compare integers $1 and $2; ensure the difference is no more than $3
101 range () {
102 $PERL -e 'if (abs(int($ARGV[0]) - int($ARGV[1])) > int($ARGV[2])) { exit(1) }' $1 $2 $3
103 }
104
105 # $1=domain $2=IP address $3=# of IP addresses $4=TC $5=drop
106 # $6=NXDOMAIN $7=SERVFAIL or other errors
107 ck_result() {
108 # wait to the background mdig calls to complete.
109 wait
110 BAD=no
111 ADDRS=`egrep "^$2$" mdig.out-$1 2>/dev/null | wc -l`
112 # count simple truncated and truncated NXDOMAIN as TC
113 TC=`egrep "^TC|NXDOMAINTC$" mdig.out-$1 2>/dev/null | wc -l`
114 DROP=`egrep "^drop$" mdig.out-$1 2>/dev/null | wc -l`
115 # count NXDOMAIN and truncated NXDOMAIN as NXDOMAIN
116 NXDOMAIN=`egrep "^NXDOMAIN|NXDOMAINTC$" mdig.out-$1 2>/dev/null | wc -l`
117 SERVFAIL=`egrep "^SERVFAIL$" mdig.out-$1 2>/dev/null | wc -l`
118 NOERROR=`egrep "^NOERROR$" mdig.out-$1 2>/dev/null | wc -l`
119
120 range $ADDRS "$3" 1 ||
121 setret "$ADDRS instead of $3 '$2' responses for $1" &&
122 BAD=yes
123
124 range $TC "$4" 1 ||
125 setret "$TC instead of $4 truncation responses for $1" &&
126 BAD=yes
127
128 range $DROP "$5" 1 ||
129 setret "$DROP instead of $5 dropped responses for $1" &&
130 BAD=yes
131
132 range $NXDOMAIN "$6" 1 ||
133 setret "$NXDOMAIN instead of $6 NXDOMAIN responses for $1" &&
134 BAD=yes
135
136 range $SERVFAIL "$7" 1 ||
137 setret "$SERVFAIL instead of $7 error responses for $1" &&
138 BAD=yes
139
140 range $NOERROR "$8" 1 ||
141 setret "$NOERROR instead of $8 NOERROR responses for $1" &&
142 BAD=yes
143
144 if test -z "$BAD"; then
145 rm -f mdig.out-$1
146 fi
147 }
148
149
150 ckstats () {
151 LABEL="$1"; shift
152 TYPE="$1"; shift
153 EXPECTED="$1"; shift
154 C=`tr -d '\r' < ns2/named.stats |
155 sed -n -e "s/[ ]*\([0-9]*\).responses $TYPE for rate limits.*/\1/p" |
156 tail -1`
157 C=`expr 0$C + 0`
158
159 range "$C" $EXPECTED 1 ||
160 setret "wrong $LABEL $TYPE statistics of $C instead of $EXPECTED"
161 }
162
163
164 #########
165 sec_start
166
167 # Tests of referrals to "." must be done before the hints are loaded
168 # or with "additional-from-cache no"
169 burst 5 a1.tld3 +norec
170 # basic rate limiting
171 burst 3 a1.tld2
172 # delay allows an additional response.
173 sleep 1
174 burst 10 a1.tld2
175 # Request 30 different qnames to try a wildcard.
176 burst 30 'x$CNT.a2.tld2'
177 # These should be counted and limited but are not. See RT33138.
178 burst 10 'y.x$CNT.a2.tld2'
179
180 # IP TC drop NXDOMAIN SERVFAIL NOERROR
181 # referrals to "."
182 ck_result a1.tld3 x 0 1 2 0 0 2
183 # check 13 results including 1 second delay that allows an additional response
184 ck_result a1.tld2 192.0.2.1 3 4 6 0 0 8
185
186 # Check the wild card answers.
187 # The parent name of the 30 requests is counted.
188 ck_result 'x*.a2.tld2' 192.0.2.2 2 10 18 0 0 12
189
190 # These should be limited but are not. See RT33138.
191 ck_result 'y.x*.a2.tld2' 192.0.2.2 10 0 0 0 0 10
192
193 #########
194 sec_start
195
196 burst 10 'x.a3.tld3'
197 burst 10 'y$CNT.a3.tld3'
198 burst 10 'z$CNT.a4.tld2'
199
200 # 10 identical recursive responses are limited
201 ck_result 'x.a3.tld3' 192.0.3.3 2 3 5 0 0 5
202
203 # 10 different recursive responses are not limited
204 ck_result 'y*.a3.tld3' 192.0.3.3 10 0 0 0 0 10
205
206 # 10 different NXDOMAIN responses are limited based on the parent name.
207 # We count 13 responses because we count truncated NXDOMAIN responses
208 # as both truncated and NXDOMAIN.
209 ck_result 'z*.a4.tld2' x 0 3 5 5 0 0
210
211 $RNDCCMD $ns2 stats
212 ckstats first dropped 36
213 ckstats first truncated 21
214
215
216 #########
217 sec_start
218
219 burst 10 a5.tld2 +tcp
220 burst 10 a6.tld2 -b $ns7
221 burst 10 a7.tld4
222 burst 2 a8.tld2 -t AAAA
223 burst 2 a8.tld2 -t TXT
224 burst 2 a8.tld2 -t SPF
225
226 # IP TC drop NXDOMAIN SERVFAIL NOERROR
227 # TCP responses are not rate limited
228 ck_result a5.tld2 192.0.2.5 10 0 0 0 0 10
229
230 # whitelisted client is not rate limited
231 ck_result a6.tld2 192.0.2.6 10 0 0 0 0 10
232
233 # Errors such as SERVFAIL are rate limited.
234 ck_result a7.tld4 x 0 0 8 0 2 0
235
236 # NODATA responses are counted as the same regardless of qtype.
237 ck_result a8.tld2 x 0 2 2 0 0 4
238
239 $RNDCCMD $ns2 stats
240 ckstats second dropped 46
241 ckstats second truncated 23
242
243
244 #########
245 sec_start
246
247 # IP TC drop NXDOMAIN SERVFAIL NOERROR
248 # all-per-second
249 # The qnames are all unique but the client IP address is constant.
250 QNUM=101
251 burst 60 'all$CNT.a9.tld2'
252
253 ck_result 'a*.a9.tld2' 192.0.2.8 50 0 10 0 0 50
254
255 $RNDCCMD $ns2 stats
256 ckstats final dropped 56
257 ckstats final truncated 23
258
259 #########
260 sec_start
261
262 DIGOPTS="+nocookie +nosearch +time=1 +tries=1 +ignore -p ${PORT}"
263 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
264 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
265 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
266 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
267 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
268 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
269 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
270 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
271 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
272 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
273 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
274
275 grep "would limit" ns4/named.run >/dev/null 2>&1 ||
276 setret "\"would limit\" not found in log file."
277
278 $NAMED -D rrl-ns5 -gc broken.conf > broken.out 2>&1 &
279 sleep 2
280 grep "min-table-size 1" broken.out > /dev/null || setret "min-table-size 0 was not changed to 1"
281
282 if [ -f named.pid ]; then
283 $KILL `cat named.pid`
284 setret "named should not have started, but did"
285 fi
286
287 echo_i "exit status: $ret"
288 [ $ret -eq 0 ] || exit 1
289