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