xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/fetchlimit/tests.sh (revision 9689912e6b171cbda866ec33f15ae94a04e2c02d)
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