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 14set -e 15 16. ../conf.sh 17 18DIGCMD="$DIG @10.53.0.3 -p ${PORT} +tcp +tries=1 +time=1" 19 20rndccmd() ( 21 "$RNDC" -c ../_common/rndc.conf -p "${CONTROLPORT}" -s "$@" 22) 23 24burst() { 25 server=${1} 26 num=${4:-20} 27 rm -f burst.input.$$ 28 while [ $num -gt 0 ]; do 29 num=$((num - 1)) 30 if [ "${5}" = "dup" ]; then 31 # burst with duplicate queries 32 echo "${2}${3}.lamesub.example A" >>burst.input.$$ 33 else 34 # burst with unique queries 35 echo "${num}${2}${3}.lamesub.example A" >>burst.input.$$ 36 fi 37 done 38 $PERL ../ditch.pl -p ${PORT} -s ${server} -b ${EXTRAPORT8} burst.input.$$ 39 rm -f burst.input.$$ 40} 41 42stat() { 43 clients=$(rndccmd ${1} status | grep "recursive clients" \ 44 | sed 's;.*: \([^/][^/]*\)/.*;\1;') 45 echo_i "clients: $clients" 46 [ "$clients" = "" ] && return 1 47 [ "$clients" -ge $2 ] || return 1 48 [ "$clients" -le $3 ] || return 1 49 return 0 50} 51 52_wait_for_message() ( 53 nextpartpeek "$1" >wait_for_message.$n 54 grep -F "$2" wait_for_message.$n >/dev/null 55) 56 57wait_for_message() ( 58 retry_quiet 20 _wait_for_message "$@" 59) 60 61n=0 62status=0 63 64n=$((n + 1)) 65echo_i "checking recursing clients are dropped at the per-server limit ($n)" 66ret=0 67# make the server lame and restart 68rndccmd 10.53.0.3 flush 69touch ans4/norespond 70for try in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do 71 burst 10.53.0.3 a $try 72 # fetches-per-server is at 400, but at 20qps against a lame server, 73 # we'll reach 200 at the tenth second, and the quota should have been 74 # tuned to less than that by then. 75 [ $try -le 5 ] && low=$((try * 10)) 76 stat 10.53.0.3 20 200 || ret=1 77 [ $ret -eq 1 ] && break 78 sleep 1 79done 80if [ $ret != 0 ]; then echo_i "failed"; fi 81status=$((status + ret)) 82 83n=$((n + 1)) 84echo_i "dumping ADB data ($n)" 85ret=0 86info=$(rndccmd 10.53.0.3 fetchlimit | grep 10.53.0.4 | sed 's/.*quota .*(\([0-9]*\).*atr \([.0-9]*\).*/\2 \1/') 87echo_i $info 88set -- $info 89quota=$2 90[ ${quota:-200} -lt 200 ] || ret=1 91if [ $ret != 0 ]; then echo_i "failed"; fi 92status=$((status + ret)) 93 94n=$((n + 1)) 95echo_i "checking servfail statistics ($n)" 96ret=0 97rm -f ns3/named.stats 98rndccmd 10.53.0.3 stats 99for try in 1 2 3 4 5; do 100 [ -f ns3/named.stats ] && break 101 sleep 1 102done 103sspill=$(grep 'spilled due to server' ns3/named.stats | sed 's/\([0-9][0-9]*\) spilled.*/\1/') 104[ -z "$sspill" ] && sspill=0 105fails=$(grep 'queries resulted in SERVFAIL' ns3/named.stats | sed 's/\([0-9][0-9]*\) queries.*/\1/') 106[ -z "$fails" ] && fails=0 107[ "$fails" -ge "$sspill" ] || ret=1 108if [ $ret != 0 ]; then echo_i "failed"; fi 109status=$((status + ret)) 110 111n=$((n + 1)) 112echo_i "checking lame server recovery ($n)" 113ret=0 114test -f ans4/norespond && rm -f ans4/norespond 115for try in 1 2 3 4 5; do 116 burst 10.53.0.3 b $try 117 stat 10.53.0.3 0 200 || ret=1 118 [ $ret -eq 1 ] && break 119 sleep 1 120done 121if [ $ret != 0 ]; then echo_i "failed"; fi 122status=$((status + ret)) 123 124n=$((n + 1)) 125echo_i "dumping ADB data ($n)" 126ret=0 127info=$(rndccmd 10.53.0.3 fetchlimit | grep 10.53.0.4 | sed 's/.*quota .*(\([0-9]*\).*atr \([.0-9]*\).*/\2 \1/') 128echo_i $info 129set -- $info 130[ ${2:-${quota}} -lt $quota ] || ret=1 131quota=$2 132if [ $ret != 0 ]; then echo_i "failed"; fi 133status=$((status + ret)) 134 135n=$((n + 1)) 136echo_i "checking lame server recovery (continued) ($n)" 137ret=0 138for try in 1 2 3 4 5 6 7 8 9 10; do 139 burst 10.53.0.3 c $try 140 stat 10.53.0.3 0 20 || ret=1 141 [ $ret -eq 1 ] && break 142 sleep 1 143done 144if [ $ret != 0 ]; then echo_i "failed"; fi 145status=$((status + ret)) 146 147n=$((n + 1)) 148echo_i "dumping ADB data ($n)" 149ret=0 150info=$(rndccmd 10.53.0.3 fetchlimit | grep 10.53.0.4 | sed 's/.*quota .*(\([0-9]*\).*atr \([.0-9]*\).*/\2 \1/') 151echo_i $info 152set -- $info 153[ ${2:-${quota}} -gt $quota ] || ret=1 154quota=$2 155if [ $ret != 0 ]; then echo_i "failed"; fi 156status=$((status + ret)) 157 158copy_setports ns3/named2.conf.in ns3/named.conf 159rndc_reconfig ns3 10.53.0.3 160 161n=$((n + 1)) 162echo_i "checking lame server clients are dropped at the per-domain limit ($n)" 163ret=0 164fail=0 165success=0 166touch ans4/norespond 167for try in 1 2 3 4 5; do 168 burst 10.53.0.3 b $try 300 169 $DIGCMD a ${try}.example >dig.out.ns3.$n.$try 170 grep "status: NOERROR" dig.out.ns3.$n.$try >/dev/null 2>&1 \ 171 && success=$((success + 1)) 172 grep "status: SERVFAIL" dig.out.ns3.$n.$try >/dev/null 2>&1 \ 173 && fail=$(($fail + 1)) 174 stat 10.53.0.3 40 40 || ret=1 175 allowed=$(rndccmd 10.53.0.3 fetchlimit | awk '/lamesub/ { print $6 }') 176 [ "${allowed:-0}" -eq 40 ] || ret=1 177 [ $ret -eq 1 ] && break 178 sleep 1 179done 180echo_i "$success successful valid queries, $fail SERVFAIL" 181if [ $ret != 0 ]; then echo_i "failed"; fi 182status=$((status + ret)) 183 184n=$((n + 1)) 185echo_i "checking drop statistics ($n)" 186ret=0 187rm -f ns3/named.stats 188rndccmd 10.53.0.3 stats 189for try in 1 2 3 4 5; do 190 [ -f ns3/named.stats ] && break 191 sleep 1 192done 193zspill=$(grep 'spilled due to zone' ns3/named.stats | sed 's/\([0-9][0-9]*\) spilled.*/\1/') 194[ -z "$zspill" ] && zspill=0 195drops=$(grep 'queries dropped' ns3/named.stats | sed 's/\([0-9][0-9]*\) queries.*/\1/') 196[ -z "$drops" ] && drops=0 197[ "$drops" -ge "$zspill" ] || ret=1 198if [ $ret != 0 ]; then echo_i "failed"; fi 199status=$((status + ret)) 200 201copy_setports ns3/named3.conf.in ns3/named.conf 202rndc_reconfig ns3 10.53.0.3 203 204n=$((n + 1)) 205echo_i "checking lame server clients are dropped below the hard limit ($n)" 206ret=0 207fail=0 208exceeded=0 209success=0 210touch ans4/norespond 211for try in 1 2 3 4 5; do 212 burst 10.53.0.3 b $try 400 213 $DIGCMD +time=2 a ${try}.example >dig.out.ns3.$n.$try 214 stat 10.53.0.3 1 400 || exceeded=$((exceeded + 1)) 215 grep "status: NOERROR" dig.out.ns3.$n.$try >/dev/null 2>&1 \ 216 && success=$((success + 1)) 217 grep "status: SERVFAIL" dig.out.ns3.$n.$try >/dev/null 2>&1 \ 218 && fail=$(($fail + 1)) 219 sleep 1 220done 221echo_i "$success successful valid queries (expected 5)" 222[ "$success" -eq 5 ] || { 223 echo_i "failed" 224 ret=1 225} 226echo_i "$fail SERVFAIL responses (expected 0)" 227[ "$fail" -eq 0 ] || { 228 echo_i "failed" 229 ret=1 230} 231echo_i "clients count exceeded 400 on $exceeded trials (expected 0)" 232[ "$exceeded" -eq 0 ] || { 233 echo_i "failed" 234 ret=1 235} 236if [ $ret != 0 ]; then echo_i "failed"; fi 237status=$((status + ret)) 238 239n=$((n + 1)) 240echo_i "checking drop statistics ($n)" 241ret=0 242rm -f ns3/named.stats 243touch ns3/named.stats 244rndccmd 10.53.0.3 stats 245wait_for_log 5 "queries dropped due to recursive client limit" ns3/named.stats || ret=1 246drops=$(grep 'queries dropped due to recursive client limit' ns3/named.stats | sed 's/\([0-9][0-9]*\) queries.*/\1/') 247[ "${drops:-0}" -ne 0 ] || ret=1 248if [ $ret != 0 ]; then echo_i "failed"; fi 249status=$((status + ret)) 250 251nextpart ns5/named.run >/dev/null 252 253n=$((n + 1)) 254echo_i "checking clients are dropped at the clients-per-query limit ($n)" 255ret=0 256test -f ans4/norespond && rm -f ans4/norespond 257for try in 1 2 3 4 5; do 258 burst 10.53.0.5 latency $try 20 "dup" 259 sleep 1 260done 261wait_for_message ns5/named.run "clients-per-query increased to 10" || ret=1 262if [ $ret != 0 ]; then echo_i "failed"; fi 263status=$((status + ret)) 264 265n=$((n + 1)) 266echo_i "checking drop statistics ($n)" 267ret=0 268rm -f ns5/named.stats 269rndccmd 10.53.0.5 stats 270for try in 1 2 3 4 5; do 271 [ -f ns5/named.stats ] && break 272 sleep 1 273done 274zspill=$(grep 'spilled due to clients per query' ns5/named.stats | sed 's/ *\([0-9][0-9]*\) spilled.*/\1/') 275[ -z "$zspill" ] && zspill=0 276# ns5 configuration: 277# clients-per-query 5 278# max-clients-per-query 10 279# expected spills: 280# 15 (out of 20) spilled for the first burst, and 10 (out of 20) spilled for 281# the next 4 bursts (because of auto-tuning): 15 + (4 * 10) == 55 282expected=55 283[ "$zspill" -eq "$expected" ] || ret=1 284echo_i "$zspill clients spilled (expected $expected)" 285if [ $ret != 0 ]; then echo_i "failed"; fi 286status=$((status + ret)) 287 288echo_i "stop ns5" 289stop_server --use-rndc --port ${CONTROLPORT} ns5 290copy_setports ns5/named2.conf.in ns5/named.conf 291echo_i "start ns5" 292start_server --noclean --restart --port ${PORT} ns5 293 294nextpart ns5/named.run >/dev/null 295 296n=$((n + 1)) 297echo_i "checking clients are dropped at the clients-per-query limit with stale-answer-client-timeout ($n)" 298ret=0 299test -f ans4/norespond && rm -f ans4/norespond 300for try in 1 2 3 4 5; do 301 burst 10.53.0.5 latency $try 20 "dup" 302 sleep 1 303done 304wait_for_message ns5/named.run "clients-per-query increased to 10" || ret=1 305if [ $ret != 0 ]; then echo_i "failed"; fi 306status=$((status + ret)) 307 308n=$((n + 1)) 309echo_i "checking drop statistics ($n)" 310ret=0 311rm -f ns5/named.stats 312rndccmd 10.53.0.5 stats 313for try in 1 2 3 4 5; do 314 [ -f ns5/named.stats ] && break 315 sleep 1 316done 317zspill=$(grep 'spilled due to clients per query' ns5/named.stats | sed 's/ *\([0-9][0-9]*\) spilled.*/\1/') 318[ -z "$zspill" ] && zspill=0 319# ns5 configuration: 320# clients-per-query 5 321# max-clients-per-query 10 322# expected spills: 323# 15 (out of 20) spilled for the first burst, and 10 (out of 20) spilled for 324# the next 4 bursts (because of auto-tuning): 15 + (4 * 10) == 55 325expected=55 326[ "$zspill" -eq "$expected" ] || ret=1 327echo_i "$zspill clients spilled (expected $expected)" 328if [ $ret != 0 ]; then echo_i "failed"; fi 329status=$((status + ret)) 330 331echo_i "exit status: $status" 332[ $status -eq 0 ] || exit 1 333