xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/rrl/tests.sh (revision fb5eed702691094bd687fbf1ded189c87457cd35)
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
12SYSTEMTESTTOP=..
13. $SYSTEMTESTTOP/conf.sh
14
15RNDCCMD="$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p ${CONTROLPORT} -s"
16
17#set -x
18
19ns1=10.53.0.1			    # root, defining the others
20ns2=10.53.0.2			    # test server
21ns3=10.53.0.3			    # secondary test server
22ns4=10.53.0.4			    # log-only test server
23ns7=10.53.0.7			    # whitelisted client
24
25USAGE="$0: [-x]"
26while getopts "x" c; do
27    case $c in
28	x) set -x;;
29	*) echo "$USAGE" 1>&2; exit 1;;
30    esac
31done
32shift `expr $OPTIND - 1 || true`
33if test "$#" -ne 0; then
34    echo "$USAGE" 1>&2
35    exit 1
36fi
37# really quit on control-C
38trap 'exit 1' 1 2 15
39
40
41ret=0
42setret () {
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.
51sec_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
64HOME=/dev/null; export HOME
65
66#   $1=number of tests  $2=target domain  $3=dig options
67QNUM=1
68burst () {
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
101range () {
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
107ck_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
150ckstats () {
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#########
165sec_start
166
167# Tests of referrals to "." must be done before the hints are loaded
168#   or with "additional-from-cache no"
169burst 5 a1.tld3 +norec
170# basic rate limiting
171burst 3 a1.tld2
172# delay allows an additional response.
173sleep 1
174burst 10 a1.tld2
175# Request 30 different qnames to try a wildcard.
176burst 30 'x$CNT.a2.tld2'
177# These should be counted and limited but are not.  See RT33138.
178burst 10 'y.x$CNT.a2.tld2'
179
180#					IP      TC      drop  NXDOMAIN SERVFAIL NOERROR
181# referrals to "."
182ck_result   a1.tld3	x		0	1	2	0	0	2
183# check 13 results including 1 second delay that allows an additional response
184ck_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.
188ck_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.
191ck_result 'y.x*.a2.tld2' 192.0.2.2	10	0	0	0	0	10
192
193#########
194sec_start
195
196burst 10 'x.a3.tld3'
197burst 10 'y$CNT.a3.tld3'
198burst 10 'z$CNT.a4.tld2'
199
200# 10 identical recursive responses are limited
201ck_result 'x.a3.tld3'	192.0.3.3	2	3	5	0	0	5
202
203# 10 different recursive responses are not limited
204ck_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.
209ck_result 'z*.a4.tld2'	x		0	3	5	5	0	0
210
211$RNDCCMD $ns2 stats
212ckstats first dropped 36
213ckstats first truncated 21
214
215
216#########
217sec_start
218
219burst 10 a5.tld2 +tcp
220burst 10 a6.tld2 -b $ns7
221burst 10 a7.tld4
222burst 2 a8.tld2 -t AAAA
223burst 2 a8.tld2 -t TXT
224burst 2 a8.tld2 -t SPF
225
226#					IP      TC      drop  NXDOMAIN SERVFAIL NOERROR
227# TCP responses are not rate limited
228ck_result a5.tld2	192.0.2.5	10	0	0	0	0	10
229
230# whitelisted client is not rate limited
231ck_result a6.tld2	192.0.2.6	10	0	0	0	0	10
232
233# Errors such as SERVFAIL are rate limited.
234ck_result a7.tld4	x		0	0	8	0	2	0
235
236# NODATA responses are counted as the same regardless of qtype.
237ck_result a8.tld2	x		0	2	2	0	0	4
238
239$RNDCCMD $ns2 stats
240ckstats second dropped 46
241ckstats second truncated 23
242
243
244#########
245sec_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.
250QNUM=101
251burst 60 'all$CNT.a9.tld2'
252
253ck_result 'a*.a9.tld2'	192.0.2.8	50	0	10	0	0	50
254
255$RNDCCMD $ns2 stats
256ckstats final dropped 56
257ckstats final truncated 23
258
259#########
260sec_start
261
262DIGOPTS="+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
275grep "would limit" ns4/named.run >/dev/null 2>&1 ||
276setret "\"would limit\" not found in log file."
277
278$NAMED -D rrl-ns5 -gc broken.conf > broken.out 2>&1 &
279sleep 2
280grep "min-table-size 1" broken.out > /dev/null || setret "min-table-size 0 was not changed to 1"
281
282if [ -f named.pid ]; then
283    $KILL `cat named.pid`
284    setret "named should not have started, but did"
285fi
286
287echo_i "exit status: $ret"
288[ $ret -eq 0 ] || exit 1
289