From: Colin Vidal Date: Wed, 25 Feb 2026 18:01:22 +0000 (+0100) Subject: Add test coverage for nameserver processing limits X-Git-Tag: v9.21.19~2^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5274e764c427155b65afd874f98d4a0237126ad1;p=thirdparty%2Fbind9.git Add test coverage for nameserver processing limits Introduce a new system test (nsprocessinglimit) to verify that the resolver strictly respects outgoing network fetch quotas when presented with heavily delegated, unresponsive zones. This test acts as a regression check for the recent Fisher-Yates nameserver selection refactor. It sets up an authoritative server delegating a zone to 23 distinct nameservers (all pointing to unresponsive loopback IPs). Using dnstap, the test forces a resolution failure and verifies that: 1. The resolver successfully traverses the zone delegation path. 2. The resolver caps the outgoing network queries to the delegated nameservers exactly at the processing limit (20 fetches), ensuring array boundaries and dynamic fetch quotas are strictly enforced without crashing or hanging. --- diff --git a/bin/tests/system/nsprocessinglimit/ns1/named.conf.j2 b/bin/tests/system/nsprocessinglimit/ns1/named.conf.j2 new file mode 100644 index 00000000000..5ad42a185a9 --- /dev/null +++ b/bin/tests/system/nsprocessinglimit/ns1/named.conf.j2 @@ -0,0 +1,39 @@ +/* + * 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. + */ + +options { + query-source address 10.53.0.1; + notify-source 10.53.0.1; + transfer-source 10.53.0.1; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.1; }; + recursion no; + dnssec-validation no; +}; + +view "default" { + zone "." { + type primary; + file "root.db"; + }; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.1 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff --git a/bin/tests/system/nsprocessinglimit/ns1/root.db b/bin/tests/system/nsprocessinglimit/ns1/root.db new file mode 100644 index 00000000000..41c97bf4451 --- /dev/null +++ b/bin/tests/system/nsprocessinglimit/ns1/root.db @@ -0,0 +1,24 @@ +; 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. + +$TTL 300 +. IN SOA marka.isc.org. a.root.servers.nil. ( + 2010 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +. NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.1 + +tld. NS ns.tld. +ns.tld. A 10.53.0.2 diff --git a/bin/tests/system/nsprocessinglimit/ns2/named.conf.j2 b/bin/tests/system/nsprocessinglimit/ns2/named.conf.j2 new file mode 100644 index 00000000000..8851c3728d8 --- /dev/null +++ b/bin/tests/system/nsprocessinglimit/ns2/named.conf.j2 @@ -0,0 +1,37 @@ +/* + * 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. + */ + +options { + query-source address 10.53.0.2; + notify-source 10.53.0.2; + transfer-source 10.53.0.2; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.2; }; + recursion no; + dnssec-validation no; +}; + +zone "tld." { + type primary; + file "tld.db"; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff --git a/bin/tests/system/nsprocessinglimit/ns2/tld.db b/bin/tests/system/nsprocessinglimit/ns2/tld.db new file mode 100644 index 00000000000..003fa089d23 --- /dev/null +++ b/bin/tests/system/nsprocessinglimit/ns2/tld.db @@ -0,0 +1,25 @@ +; 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. + +$TTL 300 +tld. IN SOA marka.isc.org. ns.tld. ( + 2010 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +tld. NS ns.tld. +ns.tld. A 10.53.0.2 + +example.tld. NS ns.example.tld. +ns.example.tld. A 10.53.0.3 + diff --git a/bin/tests/system/nsprocessinglimit/ns3/example.tld.db b/bin/tests/system/nsprocessinglimit/ns3/example.tld.db new file mode 100644 index 00000000000..48f62196930 --- /dev/null +++ b/bin/tests/system/nsprocessinglimit/ns3/example.tld.db @@ -0,0 +1,68 @@ +; 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. +$TTL 300 +example.tld. IN SOA marka.isc.org. ns.dnshoster.tld. ( + 2010 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +example.tld. NS ns.example.tld. +ns.example.tld. A 10.53.0.3 +sub.example.tld. NS ns01.sub.example.tld. +sub.example.tld. NS ns02.sub.example.tld. +sub.example.tld. NS ns03.sub.example.tld. +sub.example.tld. NS ns04.sub.example.tld. +sub.example.tld. NS ns05.sub.example.tld. +sub.example.tld. NS ns06.sub.example.tld. +sub.example.tld. NS ns07.sub.example.tld. +sub.example.tld. NS ns08.sub.example.tld. +sub.example.tld. NS ns09.sub.example.tld. +sub.example.tld. NS ns10.sub.example.tld. +sub.example.tld. NS ns11.sub.example.tld. +sub.example.tld. NS ns12.sub.example.tld. +sub.example.tld. NS ns12.sub.example.tld. +sub.example.tld. NS ns12.sub.example.tld. +sub.example.tld. NS ns13.sub.example.tld. +sub.example.tld. NS ns14.sub.example.tld. +sub.example.tld. NS ns15.sub.example.tld. +sub.example.tld. NS ns16.sub.example.tld. +sub.example.tld. NS ns17.sub.example.tld. +sub.example.tld. NS ns18.sub.example.tld. +sub.example.tld. NS ns19.sub.example.tld. +sub.example.tld. NS ns20.sub.example.tld. +sub.example.tld. NS ns21.sub.example.tld. +sub.example.tld. NS ns22.sub.example.tld. +sub.example.tld. NS ns23.sub.example.tld. +ns01.sub.example.tld. A 127.0.0.1 +ns02.sub.example.tld. A 127.0.0.2 +ns03.sub.example.tld. A 127.0.0.3 +ns04.sub.example.tld. A 127.0.0.4 +ns05.sub.example.tld. A 127.0.0.5 +ns06.sub.example.tld. A 127.0.0.6 +ns07.sub.example.tld. A 127.0.0.7 +ns08.sub.example.tld. A 127.0.0.8 +ns09.sub.example.tld. A 127.0.0.9 +ns10.sub.example.tld. A 127.0.0.10 +ns11.sub.example.tld. A 127.0.0.11 +ns12.sub.example.tld. A 127.0.0.12 +ns13.sub.example.tld. A 127.0.0.13 +ns14.sub.example.tld. A 127.0.0.14 +ns15.sub.example.tld. A 127.0.0.15 +ns16.sub.example.tld. A 127.0.0.16 +ns17.sub.example.tld. A 127.0.0.17 +ns18.sub.example.tld. A 127.0.0.18 +ns19.sub.example.tld. A 127.0.0.19 +ns20.sub.example.tld. A 127.0.0.20 +ns21.sub.example.tld. A 127.0.0.21 +ns22.sub.example.tld. A 127.0.0.22 +ns23.sub.example.tld. A 127.0.0.23 diff --git a/bin/tests/system/nsprocessinglimit/ns3/named.conf.j2 b/bin/tests/system/nsprocessinglimit/ns3/named.conf.j2 new file mode 100644 index 00000000000..15b68ee434a --- /dev/null +++ b/bin/tests/system/nsprocessinglimit/ns3/named.conf.j2 @@ -0,0 +1,37 @@ +/* + * 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. + */ + +options { + query-source address 10.53.0.3; + notify-source 10.53.0.3; + transfer-source 10.53.0.3; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.3; }; + recursion no; + dnssec-validation no; +}; + +zone "example.tld." { + type primary; + file "example.tld.db"; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff --git a/bin/tests/system/nsprocessinglimit/ns4/named.args b/bin/tests/system/nsprocessinglimit/ns4/named.args new file mode 100644 index 00000000000..71c23a43ce0 --- /dev/null +++ b/bin/tests/system/nsprocessinglimit/ns4/named.args @@ -0,0 +1 @@ +-D nsprocessinglimit-ns4 -m record -c named.conf -d 99 -g -T maxcachesize=2097152 -4 diff --git a/bin/tests/system/nsprocessinglimit/ns4/named.conf.j2 b/bin/tests/system/nsprocessinglimit/ns4/named.conf.j2 new file mode 100644 index 00000000000..8f1aea151be --- /dev/null +++ b/bin/tests/system/nsprocessinglimit/ns4/named.conf.j2 @@ -0,0 +1,39 @@ +/* + * 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. + */ + +options { + query-source address 10.53.0.4; + notify-source 10.53.0.4; + transfer-source 10.53.0.4; + port @PORT@; + pid-file "named.pid"; + listen-on { 10.53.0.4; }; + recursion yes; + dnssec-validation no; + dnstap { resolver query; }; + dnstap-output file "dnstap.out"; +}; + +zone "." { + type hint; + file "root.hint"; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; diff --git a/bin/tests/system/nsprocessinglimit/ns4/root.hint b/bin/tests/system/nsprocessinglimit/ns4/root.hint new file mode 100644 index 00000000000..d7d0e1fabac --- /dev/null +++ b/bin/tests/system/nsprocessinglimit/ns4/root.hint @@ -0,0 +1,14 @@ +; 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. + +$TTL 999999 +. IN NS a.root-servers.nil. +a.root-servers.nil. IN A 10.53.0.1 diff --git a/bin/tests/system/nsprocessinglimit/tests_nsprocessinglimit.py b/bin/tests/system/nsprocessinglimit/tests_nsprocessinglimit.py new file mode 100644 index 00000000000..3577c894606 --- /dev/null +++ b/bin/tests/system/nsprocessinglimit/tests_nsprocessinglimit.py @@ -0,0 +1,74 @@ +# 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. + +import os + +import isctest +import isctest.mark + +pytestmark = [isctest.mark.with_dnstap] + + +def line_to_ips_and_queries(line): + # dnstap-read output line example + # 05-Feb-2026 11:00:57.853 RQ 10.53.0.4:38507 -> 10.53.0.3:22047 TCP 56b sub.example.tld/IN/NS + _, _, _, _, _, dst, _, _, query = line.split(" ", 9) + ip, _ = dst.split(":", 1) + return (ip, query) + + +def extract_dnstap(ns, expectedlen): + ns.rndc("dnstap -roll 1") + path = os.path.join(ns.identifier, "dnstap.out.0") + dnstapread = isctest.run.cmd( + [isctest.vars.ALL["DNSTAPREAD"], path], + ) + + lines = dnstapread.out.splitlines() + assert expectedlen == len(lines) + return map(line_to_ips_and_queries, lines) + + +def expect_query(expected_query, expected_query_count, ips_and_queries): + count = 0 + for _, query in ips_and_queries: + if query == expected_query: + count += 1 + assert count == expected_query_count + + +def expect_next_ip_and_query(expected_ips_and_queries, ips_and_queries): + for expected_ip, expected_query in expected_ips_and_queries: + ip, query = next(ips_and_queries) + assert ip == expected_ip + assert query == expected_query + + +def test_selfpointedglue_nslimit(ns4): + msg = isctest.query.create("a.sub.example.tld.", "A") + res = isctest.query.tcp(msg, ns4.ip) + isctest.check.servfail(res) + + # The 4 formers lines are request to find sub.example2.tld NSs. + # The latest 20 are queries to sub.example2.tld NSs. + ips_and_queries = extract_dnstap(ns4, 24) + + # Checking the begining of the resulution + expect_next_ip_and_query( + [ + ("10.53.0.1", "./IN/NS"), + ("10.53.0.1", "tld/IN/NS"), + ("10.53.0.2", "example.tld/IN/NS"), + ("10.53.0.3", "sub.example.tld/IN/NS"), + ], + ips_and_queries, + ) + expect_query("a.sub.example.tld/IN/A", 20, ips_and_queries)