From: Colin Vidal Date: Mon, 23 Feb 2026 13:27:44 +0000 (+0100) Subject: Add system test for minimal-responses behaviour X-Git-Tag: v9.21.21~4^2~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=35e19ee6608b88677d41f149df2df8b214cf5e84;p=thirdparty%2Fbind9.git Add system test for minimal-responses behaviour Add the 'minimalresponses' system test in order to cover the multiple combinations of server 'minimal-responses' configurations and contexts (resolver, auth only, etc.) when filling the ANSWER, AUTHORITY and ADDITIONAL sections. --- diff --git a/bin/tests/system/minimalresponses/README b/bin/tests/system/minimalresponses/README new file mode 100644 index 00000000000..9c2c2559a1e --- /dev/null +++ b/bin/tests/system/minimalresponses/README @@ -0,0 +1,15 @@ +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. + +ns1 is the root +ns2 is auth only +ns3 is resolver only +ns4 is both auth and resolver diff --git a/bin/tests/system/minimalresponses/common.py b/bin/tests/system/minimalresponses/common.py new file mode 100644 index 00000000000..9dad7c9d5c9 --- /dev/null +++ b/bin/tests/system/minimalresponses/common.py @@ -0,0 +1,121 @@ +# 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. + +# pylint: disable=global-statement + +from re import compile as Re + +from dns.rcode import NOERROR, REFUSED + +import isctest + +EXAMPLE2_NS = "example2. 300 IN NS ns.example2." +AEXAMPLE2_A = "a.example2. 300 IN A 10.53.0.20" +NSEXAMPLE2_A = "ns.example2. 300 IN A 10.53.0.2" + +EXAMPLE4_NS = "example4. 300 IN NS ns.example4." +AEXAMPLE4_A = "a.example4. 300 IN A 10.53.0.40" +NSEXAMPLE4_A = "ns.example4. 300 IN A 10.53.0.4" + +AROOTSERVER_NS = ". 999999 IN NS a.root-servers.nil." + +INPUTPARAMS = "ns, qname, qtype, rd, cached, rcode, answer, authority, additional" + +# `minimal-responses yes` and `minimal-responses no-auth` behaves the same, +# hence they share the same input. +# The only case AUTHORITY and ADDITIONAL are provided are when strictly needed: +# - either from an authoritative server for delegation +# (cases with ns1, both AUTHORITY and glues in ADDITIONAL); +# - either from a resolver with RD=0 and no cache, +# so the resolver can only return the root hints (AUTHORITY only). +INPUTS_YES_NOAUTH = [ + ("ns1", "a.example2", "A", True, False, NOERROR, None, EXAMPLE2_NS, NSEXAMPLE2_A), + ("ns1", "a.example4", "A", True, False, NOERROR, None, EXAMPLE4_NS, NSEXAMPLE4_A), + ("ns2", "a.example2", "A", True, False, NOERROR, AEXAMPLE2_A, None, None), + ("ns2", "a.example4", "A", True, False, REFUSED, None, None, None), + ("ns3", "a.example2", "A", True, False, NOERROR, AEXAMPLE2_A, None, None), + ("ns3", "a.example4", "A", True, False, NOERROR, AEXAMPLE4_A, None, None), + ("ns3", "a.example2", "A", True, True, NOERROR, AEXAMPLE2_A, None, None), + ("ns3", "a.example4", "A", True, True, NOERROR, AEXAMPLE4_A, None, None), + ("ns4", "a.example2", "A", True, False, NOERROR, AEXAMPLE2_A, None, None), + ("ns4", "a.example4", "A", True, False, NOERROR, AEXAMPLE4_A, None, None), + ("ns4", "a.example2", "A", True, True, NOERROR, AEXAMPLE2_A, None, None), + ("ns4", "a.example4", "A", True, True, NOERROR, AEXAMPLE4_A, None, None), + ("ns1", "a.example2", "A", False, False, NOERROR, None, EXAMPLE2_NS, NSEXAMPLE2_A), + ("ns1", "a.example4", "A", False, False, NOERROR, None, EXAMPLE4_NS, NSEXAMPLE4_A), + ("ns2", "a.example2", "A", False, False, NOERROR, AEXAMPLE2_A, None, None), + ("ns2", "a.example4", "A", False, False, REFUSED, None, None, None), + ("ns3", "a.example2", "A", False, False, NOERROR, None, AROOTSERVER_NS, None), + ("ns3", "a.example4", "A", False, False, NOERROR, None, AROOTSERVER_NS, None), + ("ns3", "a.example2", "A", False, True, NOERROR, AEXAMPLE2_A, None, None), + ("ns3", "a.example4", "A", False, True, NOERROR, AEXAMPLE4_A, None, None), + ("ns4", "a.example2", "A", False, False, NOERROR, None, AROOTSERVER_NS, None), + ("ns4", "a.example4", "A", False, False, NOERROR, AEXAMPLE4_A, None, None), + ("ns4", "a.example2", "A", False, True, NOERROR, AEXAMPLE2_A, None, None), + ("ns4", "a.example4", "A", False, True, NOERROR, AEXAMPLE4_A, None, None), + # Resolver always provides glues with associated NS for qtype=NS + ("ns3", "example2", "NS", True, False, NOERROR, EXAMPLE2_NS, None, NSEXAMPLE2_A), + ("ns3", "example2", "NS", False, False, NOERROR, None, AROOTSERVER_NS, None), + ("ns3", "example2", "NS", False, True, NOERROR, EXAMPLE2_NS, None, NSEXAMPLE2_A), + ("ns3", "example2", "NS", True, True, NOERROR, EXAMPLE2_NS, None, NSEXAMPLE2_A), +] + +TESTSERVERS = None + +FLUSHED_PATTERN = Re("flushing cache.*succeeded") + + +def check(ns, qname, qtype, rd, cached, rcode, answer, authority, additional): + ns = TESTSERVERS[ns] + msg = isctest.query.create(qname, qtype, rd=rd) + if cached: + cachingmsg = isctest.query.create(qname, qtype, rd=True) + isctest.query.udp(cachingmsg, ns.ip) + else: + with ns.watch_log_from_here() as watcher: + ns.rndc("flush") + watcher.wait_for_line(FLUSHED_PATTERN) + res = isctest.query.udp(msg, ns.ip) + isctest.check.rcode(res, rcode) + if answer: + assert len(res.answer) == 1 + # Clamp the answer TTL to 300 to match the expected answer + # (In case the server would be a bit slow to process the + # query, and we would end up with a TTL of ~299) + res.answer[0].ttl = 300 + assert str(res.answer[0]) == answer + else: + assert len(res.answer) == 0 + if authority: + assert len(res.authority) == 1 + assert str(res.authority[0]) == authority + else: + assert len(res.authority) == 0 + if additional: + assert len(res.additional) == 1 + # Clamp the answer TTL to 300 to match the expected answer + # (In case the server would be a bit slow to process the + # query, and we would end up with a TTL of ~299) + res.additional[0].ttl = 300 + assert str(res.additional[0]) == additional + else: + assert len(res.additional) == 0 + + +def reconfig(servers, templates, minresp): + global TESTSERVERS + for server in servers: + ns = servers[server] + with ns.watch_log_from_here() as watcher: + templates.render(f"{server}/named.conf", {"minresp": minresp}) + ns.rndc("reload") + watcher.wait_for_line("running") + TESTSERVERS = servers diff --git a/bin/tests/system/minimalresponses/ns1/named.conf.j2 b/bin/tests/system/minimalresponses/ns1/named.conf.j2 new file mode 100644 index 00000000000..4a4a414e3c7 --- /dev/null +++ b/bin/tests/system/minimalresponses/ns1/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. + */ + +{% set minresp = minresp | default("yes") %} + +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; + minimal-responses @minresp@; +}; + +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/minimalresponses/ns1/root.db b/bin/tests/system/minimalresponses/ns1/root.db new file mode 100644 index 00000000000..93d021e3010 --- /dev/null +++ b/bin/tests/system/minimalresponses/ns1/root.db @@ -0,0 +1,27 @@ +; 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 gson.nominum.com. 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 + +example2. NS ns.example2. +ns.example2. A 10.53.0.2 + +example4. NS ns.example4. +ns.example4. A 10.53.0.4 diff --git a/bin/tests/system/minimalresponses/ns2/example2.db b/bin/tests/system/minimalresponses/ns2/example2.db new file mode 100644 index 00000000000..b7fb5fa5d1e --- /dev/null +++ b/bin/tests/system/minimalresponses/ns2/example2.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 ; 5 minutes +@ IN SOA mname1. . ( + 2000042407 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + NS ns +ns A 10.53.0.2 + +a A 10.53.0.20 diff --git a/bin/tests/system/minimalresponses/ns2/named.conf.j2 b/bin/tests/system/minimalresponses/ns2/named.conf.j2 new file mode 100644 index 00000000000..d918d43067e --- /dev/null +++ b/bin/tests/system/minimalresponses/ns2/named.conf.j2 @@ -0,0 +1,42 @@ +/* + * 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. + */ + +{% set minresp = minresp | default("yes") %} + +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 no; + notify yes; + dnssec-validation no; + minimal-responses @minresp@; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.2 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "example2" { + type primary; + file "example2.db"; +}; diff --git a/bin/tests/system/minimalresponses/ns3/named.conf.j2 b/bin/tests/system/minimalresponses/ns3/named.conf.j2 new file mode 100644 index 00000000000..6756c00f10b --- /dev/null +++ b/bin/tests/system/minimalresponses/ns3/named.conf.j2 @@ -0,0 +1,44 @@ +/* + * 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. + */ + +{% set minresp = minresp | default("yes") %} + +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 yes; + notify yes; + dnssec-validation no; + minimal-responses @minresp@; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.3 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../_common/root.hint"; +}; + + diff --git a/bin/tests/system/minimalresponses/ns4/example4.db b/bin/tests/system/minimalresponses/ns4/example4.db new file mode 100644 index 00000000000..90e0399b4ff --- /dev/null +++ b/bin/tests/system/minimalresponses/ns4/example4.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 ; 5 minutes +@ IN SOA mname1. . ( + 2000042407 ; serial + 20 ; refresh (20 seconds) + 20 ; retry (20 seconds) + 1814400 ; expire (3 weeks) + 3600 ; minimum (1 hour) + ) + NS ns +ns A 10.53.0.4 + +a A 10.53.0.40 diff --git a/bin/tests/system/minimalresponses/ns4/named.conf.j2 b/bin/tests/system/minimalresponses/ns4/named.conf.j2 new file mode 100644 index 00000000000..c11a6397e7b --- /dev/null +++ b/bin/tests/system/minimalresponses/ns4/named.conf.j2 @@ -0,0 +1,47 @@ +/* + * 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. + */ + +{% set minresp = minresp | default("yes") %} + +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; }; + listen-on-v6 { none; }; + recursion yes; + notify yes; + dnssec-validation no; + minimal-responses @minresp@; +}; + +key rndc_key { + secret "1234abcd8765"; + algorithm @DEFAULT_HMAC@; +}; + +controls { + inet 10.53.0.4 port @CONTROLPORT@ allow { any; } keys { rndc_key; }; +}; + +zone "." { + type hint; + file "../../_common/root.hint"; +}; + +zone "example4" { + type primary; + file "example4.db"; +}; diff --git a/bin/tests/system/minimalresponses/tests_minimalresponses_no.py b/bin/tests/system/minimalresponses/tests_minimalresponses_no.py new file mode 100644 index 00000000000..febaf464adc --- /dev/null +++ b/bin/tests/system/minimalresponses/tests_minimalresponses_no.py @@ -0,0 +1,139 @@ +# 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 dns.rcode import NOERROR, REFUSED + +import pytest + +from minimalresponses.common import ( + AEXAMPLE2_A, + AEXAMPLE4_A, + AROOTSERVER_NS, + EXAMPLE2_NS, + EXAMPLE4_NS, + INPUTPARAMS, + NSEXAMPLE2_A, + NSEXAMPLE4_A, + check, + reconfig, +) + +INPUTS = [ + # ns1 provides AUTHORITY and ADDITIONAL as it delegate those zone. + ("ns1", "a.example2", "A", True, False, NOERROR, None, EXAMPLE2_NS, NSEXAMPLE2_A), + ("ns1", "a.example4", "A", True, False, NOERROR, None, EXAMPLE4_NS, NSEXAMPLE4_A), + ("ns1", "a.example2", "A", False, False, NOERROR, None, EXAMPLE2_NS, NSEXAMPLE2_A), + ("ns1", "a.example4", "A", False, False, NOERROR, None, EXAMPLE4_NS, NSEXAMPLE4_A), + # ns2 is authoritative on example2, so it gives us everything it can in any cases. + ( + "ns2", + "a.example2", + "A", + True, + False, + NOERROR, + AEXAMPLE2_A, + EXAMPLE2_NS, + NSEXAMPLE2_A, + ), + ( + "ns2", + "a.example2", + "A", + False, + False, + NOERROR, + AEXAMPLE2_A, + EXAMPLE2_NS, + NSEXAMPLE2_A, + ), + ("ns2", "a.example4", "A", True, False, REFUSED, None, None, None), + ("ns2", "a.example4", "A", False, False, REFUSED, None, None, None), + # ns3 being resolver only and having the answer, no AUTHORITY or ADDITIONAL are added. + # However, with RD=0 and no cache, it can't answer, so the root hints are provided + # in AUTHORITY. + ("ns3", "a.example2", "A", True, False, NOERROR, AEXAMPLE2_A, None, None), + ("ns3", "a.example4", "A", True, False, NOERROR, AEXAMPLE4_A, None, None), + ("ns3", "a.example2", "A", True, True, NOERROR, AEXAMPLE2_A, None, None), + ("ns3", "a.example4", "A", True, True, NOERROR, AEXAMPLE4_A, None, None), + ("ns3", "a.example2", "A", False, False, NOERROR, None, AROOTSERVER_NS, None), + ("ns3", "a.example4", "A", False, False, NOERROR, None, AROOTSERVER_NS, None), + ("ns3", "a.example2", "A", False, True, NOERROR, AEXAMPLE2_A, None, None), + ("ns3", "a.example4", "A", False, True, NOERROR, AEXAMPLE4_A, None, None), + # ns4 is authoritative on example4, so gives us everything in any cases. + # For example2, because it has the answer, it only provide the ANSWER section + # (except with no cache and RD=0, where we got the root hint, because it can't do anything else) + ("ns4", "a.example2", "A", True, True, NOERROR, AEXAMPLE2_A, None, None), + ( + "ns4", + "a.example4", + "A", + True, + True, + NOERROR, + AEXAMPLE4_A, + EXAMPLE4_NS, + NSEXAMPLE4_A, + ), + ("ns4", "a.example2", "A", True, False, NOERROR, AEXAMPLE2_A, None, None), + ( + "ns4", + "a.example4", + "A", + True, + False, + NOERROR, + AEXAMPLE4_A, + EXAMPLE4_NS, + NSEXAMPLE4_A, + ), + ("ns4", "a.example2", "A", False, True, NOERROR, AEXAMPLE2_A, None, None), + ("ns4", "a.example2", "A", False, False, NOERROR, None, AROOTSERVER_NS, None), + ( + "ns4", + "a.example4", + "A", + False, + False, + NOERROR, + AEXAMPLE4_A, + EXAMPLE4_NS, + NSEXAMPLE4_A, + ), + ( + "ns4", + "a.example4", + "A", + False, + True, + NOERROR, + AEXAMPLE4_A, + EXAMPLE4_NS, + NSEXAMPLE4_A, + ), + # Resolver always provides glues with associated NS for qtype=NS + ("ns3", "example2", "NS", True, False, NOERROR, EXAMPLE2_NS, None, NSEXAMPLE2_A), + ("ns3", "example2", "NS", False, False, NOERROR, None, AROOTSERVER_NS, None), + ("ns3", "example2", "NS", False, True, NOERROR, EXAMPLE2_NS, None, NSEXAMPLE2_A), + ("ns3", "example2", "NS", True, True, NOERROR, EXAMPLE2_NS, None, NSEXAMPLE2_A), +] + + +@pytest.fixture(scope="module", autouse=True) +def authsection_init(servers, templates): + reconfig(servers, templates, "no") + + +@pytest.mark.parametrize(INPUTPARAMS, INPUTS) +def test_minimalresponses_no( + ns, qname, qtype, rd, cached, rcode, answer, authority, additional +): + check(ns, qname, qtype, rd, cached, rcode, answer, authority, additional) diff --git a/bin/tests/system/minimalresponses/tests_minimalresponses_noauth.py b/bin/tests/system/minimalresponses/tests_minimalresponses_noauth.py new file mode 100644 index 00000000000..d1f12ab106c --- /dev/null +++ b/bin/tests/system/minimalresponses/tests_minimalresponses_noauth.py @@ -0,0 +1,26 @@ +# 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 pytest + +from minimalresponses.common import INPUTPARAMS, INPUTS_YES_NOAUTH, check, reconfig + + +@pytest.fixture(scope="module", autouse=True) +def authsection_init(servers, templates): + reconfig(servers, templates, "no-auth") + + +@pytest.mark.parametrize(INPUTPARAMS, INPUTS_YES_NOAUTH) +def test_minimalresponses_noauth( + ns, qname, qtype, rd, cached, rcode, answer, authority, additional +): + check(ns, qname, qtype, rd, cached, rcode, answer, authority, additional) diff --git a/bin/tests/system/minimalresponses/tests_minimalresponses_noauthrec.py b/bin/tests/system/minimalresponses/tests_minimalresponses_noauthrec.py new file mode 100644 index 00000000000..1465c1b6137 --- /dev/null +++ b/bin/tests/system/minimalresponses/tests_minimalresponses_noauthrec.py @@ -0,0 +1,111 @@ +# 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 dns.rcode import NOERROR, REFUSED + +import pytest + +from minimalresponses.common import ( + AEXAMPLE2_A, + AEXAMPLE4_A, + AROOTSERVER_NS, + EXAMPLE2_NS, + EXAMPLE4_NS, + INPUTPARAMS, + NSEXAMPLE2_A, + NSEXAMPLE4_A, + check, + reconfig, +) + +INPUTS = [ + # ns1 provides AUTHORITY and ADDITIONAL as it delegate those zone. + ("ns1", "a.example2", "A", True, False, NOERROR, None, EXAMPLE2_NS, NSEXAMPLE2_A), + ("ns1", "a.example4", "A", True, False, NOERROR, None, EXAMPLE4_NS, NSEXAMPLE4_A), + ("ns1", "a.example2", "A", False, False, NOERROR, None, EXAMPLE2_NS, NSEXAMPLE2_A), + ("ns1", "a.example4", "A", False, False, NOERROR, None, EXAMPLE4_NS, NSEXAMPLE4_A), + # ns2 behaves like `minimal-responses no` with RD=0 on `example2.` + # (which it makes authority on). + # Nothing for `example4.` as it's an authoritative server only, + # and doesn't own that zone. + # Otherwise, it behaves like `minimal-responses yes` + ("ns2", "a.example2", "A", True, False, NOERROR, AEXAMPLE2_A, None, None), + ("ns2", "a.example4", "A", True, False, REFUSED, None, None, None), + ( + "ns2", + "a.example2", + "A", + False, + False, + NOERROR, + AEXAMPLE2_A, + EXAMPLE2_NS, + NSEXAMPLE2_A, + ), + ("ns2", "a.example4", "A", False, False, REFUSED, None, None, None), + # ns3 behaviour (as resolver) is common between all variants with RD=1. + # With RD=0, it has the same behavior than `minimal-responses no;` + ("ns3", "a.example2", "A", True, False, NOERROR, AEXAMPLE2_A, None, None), + ("ns3", "a.example4", "A", True, False, NOERROR, AEXAMPLE4_A, None, None), + ("ns3", "a.example2", "A", True, True, NOERROR, AEXAMPLE2_A, None, None), + ("ns3", "a.example4", "A", True, True, NOERROR, AEXAMPLE4_A, None, None), + ("ns3", "a.example2", "A", False, False, NOERROR, None, AROOTSERVER_NS, None), + ("ns3", "a.example4", "A", False, False, NOERROR, None, AROOTSERVER_NS, None), + ("ns3", "a.example2", "A", False, True, NOERROR, AEXAMPLE2_A, None, None), + ("ns3", "a.example4", "A", False, True, NOERROR, AEXAMPLE4_A, None, None), + # ns4, with RD=1 has minimal responses (just the answer). + # But RD=0 behaves as `minimal-responses no`. + ("ns4", "a.example2", "A", True, False, NOERROR, AEXAMPLE2_A, None, None), + ("ns4", "a.example4", "A", True, False, NOERROR, AEXAMPLE4_A, None, None), + ("ns4", "a.example2", "A", True, True, NOERROR, AEXAMPLE2_A, None, None), + ("ns4", "a.example4", "A", True, True, NOERROR, AEXAMPLE4_A, None, None), + ("ns4", "a.example2", "A", False, False, NOERROR, None, AROOTSERVER_NS, None), + ( + "ns4", + "a.example4", + "A", + False, + False, + NOERROR, + AEXAMPLE4_A, + EXAMPLE4_NS, + NSEXAMPLE4_A, + ), + ("ns4", "a.example2", "A", False, True, NOERROR, AEXAMPLE2_A, None, None), + ( + "ns4", + "a.example4", + "A", + False, + True, + NOERROR, + AEXAMPLE4_A, + EXAMPLE4_NS, + NSEXAMPLE4_A, + ), + # Resolver always provides glues with associated NS for qtype=NS + ("ns3", "example2", "NS", True, False, NOERROR, EXAMPLE2_NS, None, NSEXAMPLE2_A), + ("ns3", "example2", "NS", False, False, NOERROR, None, AROOTSERVER_NS, None), + ("ns3", "example2", "NS", False, True, NOERROR, EXAMPLE2_NS, None, NSEXAMPLE2_A), + ("ns3", "example2", "NS", True, True, NOERROR, EXAMPLE2_NS, None, NSEXAMPLE2_A), +] + + +@pytest.fixture(scope="module", autouse=True) +def authsection_init(servers, templates): + reconfig(servers, templates, "no-auth-recursive") + + +@pytest.mark.parametrize(INPUTPARAMS, INPUTS) +def test_minimalresponses_noauthrec( + ns, qname, qtype, rd, cached, rcode, answer, authority, additional +): + check(ns, qname, qtype, rd, cached, rcode, answer, authority, additional) diff --git a/bin/tests/system/minimalresponses/tests_minimalresponses_yes.py b/bin/tests/system/minimalresponses/tests_minimalresponses_yes.py new file mode 100644 index 00000000000..049479c4b0b --- /dev/null +++ b/bin/tests/system/minimalresponses/tests_minimalresponses_yes.py @@ -0,0 +1,26 @@ +# 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 pytest + +from minimalresponses.common import INPUTPARAMS, INPUTS_YES_NOAUTH, check, reconfig + + +@pytest.fixture(scope="module", autouse=True) +def authsection_init(servers, templates): + reconfig(servers, templates, "yes") + + +@pytest.mark.parametrize(INPUTPARAMS, INPUTS_YES_NOAUTH) +def test_minimalresponses_yes( + ns, qname, qtype, rd, cached, rcode, answer, authority, additional +): + check(ns, qname, qtype, rd, cached, rcode, answer, authority, additional)