[9.20] chg: test: Use isctest.asyncserver in the "fetchlimit" test

Replace the custom DNS server used in the "fetchlimit" system test
with new code based on the isctest.asyncserver module.

Backport of MR !10614

Merge branch 'backport-stepan/fetchlimit-asyncserver-9.20' into 'bind-9.20'

See merge request isc-projects/bind9!10755
This commit is contained in:
Štěpán Balážik 2025-07-22 10:16:17 +00:00
commit 920874ea58
3 changed files with 65 additions and 96 deletions

View file

@ -1,90 +0,0 @@
#!/usr/bin/perl -w
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
#
# SPDX-License-Identifier: MPL-2.0
#
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
#
# See the COPYRIGHT file distributed with this work for additional
# information regarding copyright ownership.
#
# Don't respond if the "norespond" file exists; otherwise respond to
# any A or AAAA query.
#
use IO::File;
use IO::Socket;
use Net::DNS;
use Net::DNS::Packet;
my $localport = int($ENV{'PORT'});
if (!$localport) { $localport = 5300; }
my $sock = IO::Socket::INET->new(LocalAddr => "10.53.0.4",
LocalPort => $localport, Proto => "udp") or die "$!";
my $pidf = new IO::File "ans.pid", "w" or die "cannot open pid file: $!";
print $pidf "$$\n" or die "cannot write pid file: $!";
$pidf->close or die "cannot close pid file: $!";
sub rmpid { unlink "ans.pid"; exit 1; };
$SIG{INT} = \&rmpid;
$SIG{TERM} = \&rmpid;
for (;;) {
$sock->recv($buf, 512);
print "**** request from " , $sock->peerhost, " port ", $sock->peerport, "\n";
my $packet;
if ($Net::DNS::VERSION > 0.68) {
$packet = new Net::DNS::Packet(\$buf, 0);
$@ and die $@;
} else {
my $err;
($packet, $err) = new Net::DNS::Packet(\$buf, 0);
$err and die $err;
}
print "REQUEST:\n";
$packet->print;
$packet->header->qr(1);
my @questions = $packet->question;
my $qname = $questions[0]->qname;
my $qtype = $questions[0]->qtype;
my $donotrespond = 0;
if (-e 'norespond') {
$donotrespond = 1;
} else {
$packet->header->aa(1);
if ($qtype eq "A") {
$packet->push("answer",
new Net::DNS::RR($qname .
" 300 A 192.0.2.1"));
} elsif ($qtype eq "AAAA") {
$packet->push("answer",
new Net::DNS::RR($qname .
" 300 AAAA 2001:db8:beef::1"));
}
}
if ($donotrespond == 0) {
if (index($qname, "latency") == 0) {
# 50ms latency
select(undef, undef, undef, 0.05);
}
$sock->send($packet->data);
print "RESPONSE:\n";
$packet->print;
print "\n";
}
}

View file

@ -0,0 +1,48 @@
"""
Copyright (C) Internet Systems Consortium, Inc. ("ISC")
SPDX-License-Identifier: MPL-2.0
This Source Code Form is subject to the terms of the Mozilla Public
License, v. 2.0. If a copy of the MPL was not distributed with this
file, you can obtain one at https://mozilla.org/MPL/2.0/.
See the COPYRIGHT file distributed with this work for additional
information regarding copyright ownership.
"""
from typing import AsyncGenerator
import dns
from isctest.asyncserver import (
ControllableAsyncDnsServer,
DnsResponseSend,
QueryContext,
ResponseHandler,
ToggleResponsesCommand,
)
class MaybeDelayedAddressAnswerHandler(ResponseHandler):
async def get_responses(
self, qctx: QueryContext
) -> AsyncGenerator[DnsResponseSend, None]:
if qctx.qtype in (dns.rdatatype.A, dns.rdatatype.AAAA):
addr = "192.0.2.1" if qctx.qtype == dns.rdatatype.A else "2001:db8:beef::1"
rrset = dns.rrset.from_text(qctx.qname, 300, qctx.qclass, qctx.qtype, addr)
qctx.response.answer.append(rrset)
qctx.response.set_rcode(dns.rcode.NOERROR)
delay = 0.05 if qctx.qname.labels[0].startswith(b"latency") else 0.00
yield DnsResponseSend(qctx.response, delay=delay, authoritative=True)
def main() -> None:
server = ControllableAsyncDnsServer([ToggleResponsesCommand])
server.install_response_handler(MaybeDelayedAddressAnswerHandler())
server.run()
if __name__ == "__main__":
main()

View file

@ -21,6 +21,17 @@ rndccmd() (
"$RNDC" -c ../_common/rndc.conf -p "${CONTROLPORT}" -s "$@"
)
dig_with_opts() (
"$DIG" -p "$PORT" "$@"
)
sendcmd() (
SERVER="${1}"
COMMAND="${2}"
COMMAND_ARGS="${3}"
dig_with_opts "@${SERVER}" "${COMMAND_ARGS}.${COMMAND}._control." TXT +time=5 +tries=1 +tcp >/dev/null 2>&1
)
burst() {
server=${1}
num=${4:-20}
@ -66,7 +77,7 @@ echo_i "checking recursing clients are dropped at the per-server limit ($n)"
ret=0
# make the server lame and restart
rndccmd 10.53.0.3 flush
touch ans4/norespond
sendcmd 10.53.0.4 send-responses "disable"
for try in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do
burst 10.53.0.3 a $try
# fetches-per-server is at 400, but at 20qps against a lame server,
@ -111,7 +122,7 @@ status=$((status + ret))
n=$((n + 1))
echo_i "checking lame server recovery ($n)"
ret=0
test -f ans4/norespond && rm -f ans4/norespond
sendcmd 10.53.0.4 send-responses "enable"
for try in 1 2 3 4 5; do
burst 10.53.0.3 b $try
stat 10.53.0.3 0 200 || ret=1
@ -163,7 +174,7 @@ echo_i "checking lame server clients are dropped at the per-domain limit ($n)"
ret=0
fail=0
success=0
touch ans4/norespond
sendcmd 10.53.0.4 send-responses "disable"
for try in 1 2 3 4 5; do
burst 10.53.0.3 d $try 300
$DIGCMD a ${try}.example >dig.out.ns3.$n.$try
@ -207,7 +218,7 @@ ret=0
fail=0
exceeded=0
success=0
touch ans4/norespond
sendcmd 10.53.0.4 send-responses "disable"
for try in 1 2 3 4 5; do
burst 10.53.0.3 b $try 400
$DIGCMD +time=2 a ${try}.example >dig.out.ns3.$n.$try
@ -253,7 +264,7 @@ nextpart ns5/named.run >/dev/null
n=$((n + 1))
echo_i "checking clients are dropped at the clients-per-query limit ($n)"
ret=0
test -f ans4/norespond && rm -f ans4/norespond
sendcmd 10.53.0.4 send-responses "enable"
for try in 1 2 3 4 5; do
burst 10.53.0.5 latency $try 20 "dup"
sleep 1
@ -296,7 +307,7 @@ nextpart ns5/named.run >/dev/null
n=$((n + 1))
echo_i "checking clients are dropped at the clients-per-query limit with stale-answer-client-timeout ($n)"
ret=0
test -f ans4/norespond && rm -f ans4/norespond
sendcmd 10.53.0.4 send-responses "enable"
for try in 1 2 3 4 5; do
burst 10.53.0.5 latency $try 20 "dup"
sleep 1