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