tests.sh revision 1.1.1.2.2.2 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 http://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="+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 BAD=no
109 ADDRS=`egrep "^$2$" mdig.out-$1 2>/dev/null | wc -l`
110 # count simple truncated and truncated NXDOMAIN as TC
111 TC=`egrep "^TC|NXDOMAINTC$" mdig.out-$1 2>/dev/null | wc -l`
112 DROP=`egrep "^drop$" mdig.out-$1 2>/dev/null | wc -l`
113 # count NXDOMAIN and truncated NXDOMAIN as NXDOMAIN
114 NXDOMAIN=`egrep "^NXDOMAIN|NXDOMAINTC$" mdig.out-$1 2>/dev/null | wc -l`
115 SERVFAIL=`egrep "^SERVFAIL$" mdig.out-$1 2>/dev/null | wc -l`
116 NOERROR=`egrep "^NOERROR$" mdig.out-$1 2>/dev/null | wc -l`
117
118 range $ADDRS "$3" 1 ||
119 setret "$ADDRS instead of $3 '$2' responses for $1" &&
120 BAD=yes
121
122 range $TC "$4" 1 ||
123 setret "$TC instead of $4 truncation responses for $1" &&
124 BAD=yes
125
126 range $DROP "$5" 1 ||
127 setret "$DROP instead of $5 dropped responses for $1" &&
128 BAD=yes
129
130 range $NXDOMAIN "$6" 1 ||
131 setret "$NXDOMAIN instead of $6 NXDOMAIN responses for $1" &&
132 BAD=yes
133
134 range $SERVFAIL "$7" 1 ||
135 setret "$SERVFAIL instead of $7 error responses for $1" &&
136 BAD=yes
137
138 range $NOERROR "$8" 1 ||
139 setret "$NOERROR instead of $8 NOERROR responses for $1" &&
140 BAD=yes
141
142 if test -z "$BAD"; then
143 rm -f mdig.out-$1
144 fi
145 }
146
147
148 ckstats () {
149 LABEL="$1"; shift
150 TYPE="$1"; shift
151 EXPECTED="$1"; shift
152 C=`tr -d '\r' < ns2/named.stats |
153 sed -n -e "s/[ ]*\([0-9]*\).responses $TYPE for rate limits.*/\1/p" |
154 tail -1`
155 C=`expr 0$C + 0`
156
157 range "$C" $EXPECTED 1 ||
158 setret "wrong $LABEL $TYPE statistics of $C instead of $EXPECTED"
159 }
160
161
162 #########
163 sec_start
164
165 # Tests of referrals to "." must be done before the hints are loaded
166 # or with "additional-from-cache no"
167 burst 5 a1.tld3 +norec
168 # basic rate limiting
169 burst 3 a1.tld2
170 # delay allows an additional response.
171 sleep 1
172 burst 10 a1.tld2
173 # Request 30 different qnames to try a wildcard.
174 burst 30 'x$CNT.a2.tld2'
175 # These should be counted and limited but are not. See RT33138.
176 burst 10 'y.x$CNT.a2.tld2'
177
178 # IP TC drop NXDOMAIN SERVFAIL NOERROR
179 # referrals to "."
180 ck_result a1.tld3 x 0 1 2 0 0 2
181 # check 13 results including 1 second delay that allows an additional response
182 ck_result a1.tld2 192.0.2.1 3 4 6 0 0 8
183
184 # Check the wild card answers.
185 # The parent name of the 30 requests is counted.
186 ck_result 'x*.a2.tld2' 192.0.2.2 2 10 18 0 0 12
187
188 # These should be limited but are not. See RT33138.
189 ck_result 'y.x*.a2.tld2' 192.0.2.2 10 0 0 0 0 10
190
191 #########
192 sec_start
193
194 burst 10 'x.a3.tld3'
195 burst 10 'y$CNT.a3.tld3'
196 burst 10 'z$CNT.a4.tld2'
197
198 # 10 identical recursive responses are limited
199 ck_result 'x.a3.tld3' 192.0.3.3 2 3 5 0 0 5
200
201 # 10 different recursive responses are not limited
202 ck_result 'y*.a3.tld3' 192.0.3.3 10 0 0 0 0 10
203
204 # 10 different NXDOMAIN responses are limited based on the parent name.
205 # We count 13 responses because we count truncated NXDOMAIN responses
206 # as both truncated and NXDOMAIN.
207 ck_result 'z*.a4.tld2' x 0 3 5 5 0 0
208
209 $RNDCCMD $ns2 stats
210 ckstats first dropped 36
211 ckstats first truncated 21
212
213
214 #########
215 sec_start
216
217 burst 10 a5.tld2 +tcp
218 burst 10 a6.tld2 -b $ns7
219 burst 10 a7.tld4
220 burst 2 a8.tld2 -t AAAA
221 burst 2 a8.tld2 -t TXT
222 burst 2 a8.tld2 -t SPF
223
224 # IP TC drop NXDOMAIN SERVFAIL NOERROR
225 # TCP responses are not rate limited
226 ck_result a5.tld2 192.0.2.5 10 0 0 0 0 10
227
228 # whitelisted client is not rate limited
229 ck_result a6.tld2 192.0.2.6 10 0 0 0 0 10
230
231 # Errors such as SERVFAIL are rate limited.
232 ck_result a7.tld4 x 0 0 8 0 2 0
233
234 # NODATA responses are counted as the same regardless of qtype.
235 ck_result a8.tld2 x 0 2 2 0 0 4
236
237 $RNDCCMD $ns2 stats
238 ckstats second dropped 46
239 ckstats second truncated 23
240
241
242 #########
243 sec_start
244
245 # IP TC drop NXDOMAIN SERVFAIL NOERROR
246 # all-per-second
247 # The qnames are all unique but the client IP address is constant.
248 QNUM=101
249 burst 60 'all$CNT.a9.tld2'
250
251 ck_result 'a*.a9.tld2' 192.0.2.8 50 0 10 0 0 50
252
253 $RNDCCMD $ns2 stats
254 ckstats final dropped 56
255 ckstats final truncated 23
256
257 #########
258 sec_start
259
260 DIGOPTS="+nocookie +nosearch +time=1 +tries=1 +ignore -p ${PORT}"
261 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
262 $DIG $DIGOPTS @$ns4 A a7.tld4 > /dev/null 2>&1
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
273 grep "would limit" ns4/named.run >/dev/null 2>&1 ||
274 setret "\"would limit\" not found in log file."
275
276 $NAMED -D rrl-ns5 -gc broken.conf > broken.out 2>&1 &
277 sleep 2
278 grep "min-table-size 1" broken.out > /dev/null || setret "min-table-size 0 was not changed to 1"
279
280 if [ -f named.pid ]; then
281 $KILL `cat named.pid`
282 setret "named should not have started, but did"
283 fi
284
285 echo_i "exit status: $ret"
286 [ $ret -eq 0 ] || exit 1
287