1# Copyright (C) 2012, 2013 Internet Systems Consortium, Inc. ("ISC") 2# 3# Permission to use, copy, modify, and/or distribute this software for any 4# purpose with or without fee is hereby granted, provided that the above 5# copyright notice and this permission notice appear in all copies. 6# 7# THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH 8# REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY 9# AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT, 10# INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM 11# LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE 12# OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 13# PERFORMANCE OF THIS SOFTWARE. 14 15 16# test response rate limiting 17 18SYSTEMTESTTOP=.. 19. $SYSTEMTESTTOP/conf.sh 20 21#set -x 22 23ns1=10.53.0.1 # root, defining the others 24ns2=10.53.0.2 # test server 25ns3=10.53.0.3 # secondary test server 26ns7=10.53.0.7 # whitelisted client 27 28USAGE="$0: [-x]" 29while getopts "x" c; do 30 case $c in 31 x) set -x;; 32 *) echo "$USAGE" 1>&2; exit 1;; 33 esac 34done 35shift `expr $OPTIND - 1 || true` 36if test "$#" -ne 0; then 37 echo "$USAGE" 1>&2 38 exit 1 39fi 40# really quit on control-C 41trap 'exit 1' 1 2 15 42 43 44ret=0 45setret () { 46 ret=1 47 echo "$*" 48} 49 50 51# Wait until soon after the start of a second to make results consistent. 52# The start of a second credits a rate limit. 53# This would be far easier in C or by assuming a modern version of perl. 54sec_start () { 55 START=`date` 56 while true; do 57 NOW=`date` 58 if test "$START" != "$NOW"; then 59 return 60 fi 61 $PERL -e 'select(undef, undef, undef, 0.05)' || true 62 done 63} 64 65 66# turn off ${HOME}/.digrc 67HOME=/dev/null; export HOME 68 69# $1=result name $2=domain name $3=dig options 70digcmd () { 71 OFILE=$1; shift 72 DIG_DOM=$1; shift 73 ARGS="+nosearch +time=1 +tries=1 +ignore -p 5300 $* $DIG_DOM @$ns2" 74 #echo I:dig $ARGS 1>&2 75 START=`date +%y%m%d%H%M.%S` 76 RESULT=`$DIG $ARGS 2>&1 | tee $OFILE=TEMP \ 77 | sed -n -e '/^;; AUTHORITY/,/^$/d' \ 78 -e '/^;; ADDITIONAL/,/^$/d' \ 79 -e 's/^[^;].* \([^ ]\{1,\}\)$/\1/p' \ 80 -e 's/;; flags.* tc .*/TC/p' \ 81 -e 's/;; .* status: NXDOMAIN.*/NXDOMAIN/p' \ 82 -e 's/;; .* status: SERVFAIL.*/SERVFAIL/p' \ 83 -e 's/;; connection timed out.*/drop/p' \ 84 -e 's/;; communications error to.*/drop/p' \ 85 | tr -d '\n'` 86 mv "$OFILE=TEMP" "$OFILE=$RESULT" 87 touch -t $START "$OFILE=$RESULT" 88} 89 90 91# $1=number of tests $2=target domain $3=dig options 92QNUM=1 93burst () { 94 BURST_LIMIT=$1; shift 95 BURST_DOM_BASE="$1"; shift 96 while test "$BURST_LIMIT" -ge 1; do 97 CNT=`expr "00$QNUM" : '.*\(...\)'` 98 eval BURST_DOM="$BURST_DOM_BASE" 99 FILE="dig.out-$BURST_DOM-$CNT" 100 digcmd $FILE $BURST_DOM $* & 101 QNUM=`expr $QNUM + 1` 102 BURST_LIMIT=`expr "$BURST_LIMIT" - 1` 103 done 104} 105 106 107# $1=domain $2=IP address $3=# of IP addresses $4=TC $5=drop 108# $6=NXDOMAIN $7=SERVFAIL or other errors 109ck_result() { 110 BAD= 111 wait 112 ADDRS=`ls dig.out-$1-*=$2 2>/dev/null | wc -l` 113 # count simple truncated and truncated NXDOMAIN as TC 114 TC=`ls dig.out-$1-*=TC dig.out-$1-*=NXDOMAINTC 2>/dev/null | wc -l` 115 DROP=`ls dig.out-$1-*=drop 2>/dev/null | wc -l` 116 # count NXDOMAIN and truncated NXDOMAIN as NXDOMAIN 117 NXDOMAIN=`ls dig.out-$1-*=NXDOMAIN dig.out-$1-*=NXDOMAINTC 2>/dev/null \ 118 | wc -l` 119 SERVFAIL=`ls dig.out-$1-*=SERVFAIL 2>/dev/null | wc -l` 120 if test $ADDRS -ne "$3"; then 121 setret "I:"$ADDRS" instead of $3 '$2' responses for $1" 122 BAD=yes 123 fi 124 if test $TC -ne "$4"; then 125 setret "I:"$TC" instead of $4 truncation responses for $1" 126 BAD=yes 127 fi 128 if test $DROP -ne "$5"; then 129 setret "I:"$DROP" instead of $5 dropped responses for $1" 130 BAD=yes 131 fi 132 if test $NXDOMAIN -ne "$6"; then 133 setret "I:"$NXDOMAIN" instead of $6 NXDOMAIN responses for $1" 134 BAD=yes 135 fi 136 if test $SERVFAIL -ne "$7"; then 137 setret "I:"$SERVFAIL" instead of $7 error responses for $1" 138 BAD=yes 139 fi 140 if test -z "$BAD"; then 141 rm -f dig.out-$1-* 142 fi 143} 144 145 146ckstats () { 147 LABEL="$1"; shift 148 TYPE="$1"; shift 149 EXPECTED="$1"; shift 150 C=`sed -n -e "s/[ ]*\([0-9]*\).responses $TYPE for rate limits.*/\1/p" \ 151 ns2/named.stats | tail -1` 152 C=`expr 0$C + 0` 153 if test "$C" -ne $EXPECTED; then 154 setret "I:wrong $LABEL $TYPE statistics of $C instead of $EXPECTED" 155 fi 156} 157 158 159######### 160sec_start 161 162# Tests of referrals to "." must be done before the hints are loaded 163# or with "additional-from-cache no" 164burst 5 a1.tld3 +norec 165# basic rate limiting 166burst 3 a1.tld2 167# 1 second delay allows an additional response. 168sleep 1 169burst 10 a1.tld2 170# Request 30 different qnames to try a wildcard. 171burst 30 'x$CNT.a2.tld2' 172# These should be counted and limited but are not. See RT33138. 173burst 10 'y.x$CNT.a2.tld2' 174 175# IP TC drop NXDOMAIN SERVFAIL 176# referrals to "." 177ck_result a1.tld3 '' 2 1 2 0 0 178# check 13 results including 1 second delay that allows an additional response 179ck_result a1.tld2 192.0.2.1 3 4 6 0 0 180 181# Check the wild card answers. 182# The parent name of the 30 requests is counted. 183ck_result 'x*.a2.tld2' 192.0.2.2 2 10 18 0 0 184 185# These should be limited but are not. See RT33138. 186ck_result 'y.x*.a2.tld2' 192.0.2.2 10 0 0 0 0 187 188######### 189sec_start 190 191burst 10 'x.a3.tld3' 192burst 10 'y$CNT.a3.tld3' 193burst 10 'z$CNT.a4.tld2' 194 195# 10 identical recursive responses are limited 196ck_result 'x.a3.tld3' 192.0.3.3 2 3 5 0 0 197 198# 10 different recursive responses are not limited 199ck_result 'y*.a3.tld3' 192.0.3.3 10 0 0 0 0 200 201# 10 different NXDOMAIN responses are limited based on the parent name. 202# We count 13 responses because we count truncated NXDOMAIN responses 203# as both truncated and NXDOMAIN. 204ck_result 'z*.a4.tld2' x 0 3 5 5 0 205 206$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s $ns2 stats 207ckstats first dropped 36 208ckstats first truncated 21 209 210 211######### 212sec_start 213 214burst 10 a5.tld2 +tcp 215burst 10 a6.tld2 -b $ns7 216burst 10 a7.tld4 217burst 2 a8.tld2 AAAA 218burst 2 a8.tld2 TXT 219burst 2 a8.tld2 SPF 220 221# IP TC drop NXDOMAIN SERVFAIL 222# TCP responses are not rate limited 223ck_result a5.tld2 192.0.2.5 10 0 0 0 0 224 225# whitelisted client is not rate limited 226ck_result a6.tld2 192.0.2.6 10 0 0 0 0 227 228# Errors such as SERVFAIL are rate limited. 229ck_result a7.tld4 x 0 0 8 0 2 230 231# NODATA responses are counted as the same regardless of qtype. 232ck_result a8.tld2 '' 2 2 2 0 0 233 234$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s $ns2 stats 235ckstats second dropped 46 236ckstats second truncated 23 237 238 239######### 240sec_start 241 242# IP TC drop NXDOMAIN SERVFAIL 243# all-per-second 244# The qnames are all unique but the client IP address is constant. 245QNUM=101 246burst 60 'all$CNT.a9.tld2' 247 248ck_result 'a*.a9.tld2' 192.0.2.8 50 0 10 0 0 249 250$RNDC -c $SYSTEMTESTTOP/common/rndc.conf -p 9953 -s $ns2 stats 251ckstats final dropped 56 252ckstats final truncated 23 253 254 255echo "I:exit status: $ret" 256# exit $ret 257[ $ret -ne 0 ] && echo "I:test failure overridden" 258exit 0 259