diff --git a/bin/tests/system/auth_res_deleg/README b/bin/tests/system/auth_res_deleg/README new file mode 100644 index 0000000000..cc051658e9 --- /dev/null +++ b/bin/tests/system/auth_res_deleg/README @@ -0,0 +1,12 @@ +ns1 simulates a root server + +ns2 is an auth server (over example.) which is also a resolver. + +ns3 is an auth server on `sub.example.`. + +The point of the test is to show that because ns2 knows the IP address of the +NS delegating sub.example., there won't be any queries to resolve +ns.sub.example. + +In order to prove it, ns2 also does a DNSTAP dump of its outgoing queries and +checks there is no NS queries to ns3 (but only an AAAA query). diff --git a/bin/tests/system/auth_res_deleg/ns1/named.conf.j2 b/bin/tests/system/auth_res_deleg/ns1/named.conf.j2 new file mode 100644 index 0000000000..41a46be0d0 --- /dev/null +++ b/bin/tests/system/auth_res_deleg/ns1/named.conf.j2 @@ -0,0 +1,30 @@ +/* + * 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; }; + listen-on-v6 { none; }; + recursion no; + notify yes; + dnssec-validation no; +}; + +zone "." { + type primary; + file "root.db"; +}; diff --git a/bin/tests/system/auth_res_deleg/ns1/root.db b/bin/tests/system/auth_res_deleg/ns1/root.db new file mode 100644 index 0000000000..4613a4e050 --- /dev/null +++ b/bin/tests/system/auth_res_deleg/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 a.root.servers.nil. a.root.servers.nil. ( + 2000042100 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +. NS a.root-servers.nil. +a.root-servers.nil. A 10.53.0.1 + +example. NS ns.example. +ns.example. A 10.53.0.2 diff --git a/bin/tests/system/auth_res_deleg/ns2/example.db b/bin/tests/system/auth_res_deleg/ns2/example.db new file mode 100644 index 0000000000..e7d388b234 --- /dev/null +++ b/bin/tests/system/auth_res_deleg/ns2/example.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 example. example. ( + 2000042100 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +@ NS ns.example. +ns.example. A 10.53.0.2 + +sub.example. NS ns.sub.example. +ns.sub.example. A 10.53.0.3 diff --git a/bin/tests/system/auth_res_deleg/ns2/named.conf.j2 b/bin/tests/system/auth_res_deleg/ns2/named.conf.j2 new file mode 100644 index 0000000000..dbd8a992e7 --- /dev/null +++ b/bin/tests/system/auth_res_deleg/ns2/named.conf.j2 @@ -0,0 +1,41 @@ +/* + * 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; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; + dnssec-validation no; + dnstap { resolver query; }; + dnstap-output file "dnstap.out"; +}; + +zone "." { + type primary; + file "example.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/auth_res_deleg/ns3/named.conf.j2 b/bin/tests/system/auth_res_deleg/ns3/named.conf.j2 new file mode 100644 index 0000000000..503891d475 --- /dev/null +++ b/bin/tests/system/auth_res_deleg/ns3/named.conf.j2 @@ -0,0 +1,30 @@ +/* + * 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; }; + listen-on-v6 { none; }; + recursion no; + notify yes; + dnssec-validation no; +}; + +zone "." { + type primary; + file "sub.example.db"; +}; diff --git a/bin/tests/system/auth_res_deleg/ns3/sub.example.db b/bin/tests/system/auth_res_deleg/ns3/sub.example.db new file mode 100644 index 0000000000..da53af6250 --- /dev/null +++ b/bin/tests/system/auth_res_deleg/ns3/sub.example.db @@ -0,0 +1,23 @@ +; 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 sub.example. sub.example. ( + 2000042100 ; serial + 600 ; refresh + 600 ; retry + 1200 ; expire + 600 ; minimum + ) +@ NS ns.sub.example. +ns.sub.example. A 10.53.0.3 + +aaaa.sub.example. AAAA ac::dc diff --git a/bin/tests/system/auth_res_deleg/tests_auth_res_deleg.py b/bin/tests/system/auth_res_deleg/tests_auth_res_deleg.py new file mode 100644 index 0000000000..3656dc3424 --- /dev/null +++ b/bin/tests/system/auth_res_deleg/tests_auth_res_deleg.py @@ -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. + +import os + +import isctest +import isctest.mark + +pytestmark = [isctest.mark.with_dnstap] + + +def line_to_query(line): + # dnstap-read output line example + # 05-Feb-2026 11:00:57.853 RQ 10.53.0.6:38507 -> 10.53.0.3:22047 TCP 56b fooXXX.example./IN/NS + _, _, _, _, _, _, _, _, query = line.split(" ", 9) + return query + + +def extract_dnstap(ns): + 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() + return list(map(line_to_query, lines)) + + +def test_auth_res_deleg(ns2): + msg = isctest.query.create("aaaa.sub.example.", "AAAA") + res = isctest.query.udp(msg, ns2.ip) + isctest.check.noerror(res) + assert len(res.answer[0]) == 1 + res.answer[0].ttl = 300 + assert str(res.answer[0]) == "aaaa.sub.example. 300 IN AAAA ac::dc" + + queries = extract_dnstap(ns2) + assert len(queries) == 1 + assert queries[0] == "aaaa.sub.example/IN/AAAA" diff --git a/lib/dns/view.c b/lib/dns/view.c index 9f18357a24..2e4853d928 100644 --- a/lib/dns/view.c +++ b/lib/dns/view.c @@ -1180,7 +1180,17 @@ dns_view_bestzonecut(dns_view_t *view, const dns_name_t *name, if (result != ISC_R_SUCCESS) { result = DNS_R_NXDOMAIN; } else { - dns_delegset_fromrdataset(rdataset, delegsetp); + /* + * The rdataset came either from a local zone or a hint. Either + * way, we only considering the NS rdataset here, so if there + * are glues, they'll be ignored. This is okay: the delegation + * type will be DNS_DELEGSET_NS_NAMES, so ADB will do a NS name + * lookup but immediately find the results locally (because this + * came from a local zone or hint). So the resolution will be + * the same, and this avoid adding extra code here to extract + * A/AAAA rdataset if any. + */ + dns_delegset_fromnsrdataset(rdataset, delegsetp); } dns_rdataset_cleanup(rdataset); diff --git a/lib/ns/query.c b/lib/ns/query.c index d59d1f6f73..4deeda6074 100644 --- a/lib/ns/query.c +++ b/lib/ns/query.c @@ -8668,7 +8668,7 @@ query_delegation_recurse(query_ctx_t *qctx) { qctx->client->inner.now, 0, true, true, &delegset); if (tresult != ISC_R_SUCCESS) { - dns_delegset_fromrdataset(qctx->rdataset, &delegset); + dns_delegset_fromnsrdataset(qctx->rdataset, &delegset); fname = qctx->fname; }