Home | History | Annotate | Line # | Download | only in rrl
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