From 56fa811fe564f58a70767275498fc0f933d182c9 Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Tue, 16 Sep 2025 17:14:46 +0200 Subject: [PATCH 1/3] test that cache is preserved on reconfing failure A named bug scrap the cache on a second reload after an initial reload failure. Adds a test checking that the cache is preserved between server reconfiguration/reloads even if it fails at some point (after attempting to re-use the cache) and the server is re-loaded later. (cherry picked from commit 714693742e9361c4ad9397debae530070a4b1cd2) --- bin/tests/system/resolver/ns1/named.conf.j2 | 49 +++++++++++++++++++ bin/tests/system/resolver/tests_resolver.py | 39 +++++++++++++++ .../system/resolver/tests_sh_resolver.py | 1 + 3 files changed, 89 insertions(+) create mode 100644 bin/tests/system/resolver/ns1/named.conf.j2 create mode 100644 bin/tests/system/resolver/tests_resolver.py diff --git a/bin/tests/system/resolver/ns1/named.conf.j2 b/bin/tests/system/resolver/ns1/named.conf.j2 new file mode 100644 index 0000000000..ff3caa8216 --- /dev/null +++ b/bin/tests/system/resolver/ns1/named.conf.j2 @@ -0,0 +1,49 @@ +/* + * 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 wrongoption = wrongoption | default(False) %} + +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 yes; + dnssec-validation no; + attach-cache "globalcache"; + max-zone-ttl unlimited; + resolver-query-timeout 5000; # 5 seconds + max-recursion-queries 100; + request-zoneversion yes; +}; + +view "default" { + zone "." { + type hint; + file "root.hint"; + }; +{% if wrongoption %} + forwarders port 9999999 { 127.0.0.1; }; +{% endif %} +}; + +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/resolver/tests_resolver.py b/bin/tests/system/resolver/tests_resolver.py new file mode 100644 index 0000000000..286a33e4e0 --- /dev/null +++ b/bin/tests/system/resolver/tests_resolver.py @@ -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. + +import time + + +import isctest + + +def test_resolver_cache_reloadfails(ns1, templates): + ns1.rndc("flush") + msg = isctest.query.create("www.example.org.", "A") + res = isctest.query.udp(msg, "10.53.0.1") + isctest.check.noerror(res) + assert res.answer[0].ttl == 300 + templates.render("ns1/named.conf", {"wrongoption": True}) + try: + # The first reload fails, and the old cache list will be preserved + ns1.rndc("reload") + except isctest.rndc.RNDCException: + templates.render("ns1/named.conf", {"wrongoption": False}) + # The second reload succeed, and the cache is still there, as preserved + # from the old cache list + ns1.rndc("reload") + time.sleep(3) + msg = isctest.query.create("www.example.org.", "A") + res = isctest.query.udp(msg, "10.53.0.1") + isctest.check.noerror(res) + # The ttl being lower than 300 (provided by fake authoritative) proves + # the cache is still in use + assert res.answer[0].ttl < 300 diff --git a/bin/tests/system/resolver/tests_sh_resolver.py b/bin/tests/system/resolver/tests_sh_resolver.py index 10a36ce4e4..0a90735408 100644 --- a/bin/tests/system/resolver/tests_sh_resolver.py +++ b/bin/tests/system/resolver/tests_sh_resolver.py @@ -11,6 +11,7 @@ import pytest + pytestmark = pytest.mark.extra_artifacts( [ ".digrc", From a4c3e6f3dd992bc78af02f2062e7c5bdc48ec39e Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Tue, 16 Sep 2025 17:14:33 +0200 Subject: [PATCH 2/3] preserve cache when reload fails If the server is reloaded, new views are created and preexisting cache is attached to those _but_ something goes wrong later, the previous views are restored but the previous cache list is destroyed. This makes the subsequent reload to drop the existing cache. This fixes it by avoiding a mutation of the old cache list. (cherry picked from commit a1703fa35b1ad3e2be1ff961122b5fdc39654b5e) --- bin/named/server.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/bin/named/server.c b/bin/named/server.c index 5168c47ca0..6145e9181e 100644 --- a/bin/named/server.c +++ b/bin/named/server.c @@ -4839,13 +4839,15 @@ configure_view(dns_view_t *view, dns_viewlist_t *viewlist, cfg_obj_t *config, dns_cache_getname(nsc->cache)); nsc = NULL; } else { - if (oldcache) { - ISC_LIST_UNLINK(*oldcachelist, nsc, link); - ISC_LIST_APPEND(*cachelist, nsc, link); - nsc->primaryview = view; - } - dns_cache_attach(nsc->cache, &cache); shared_cache = true; + dns_cache_attach(nsc->cache, &cache); + if (oldcache) { + /* + * We need to re-use the cache, but we don't + * want to mutate the old production list. + */ + nsc = NULL; + } } } else if (strcmp(cachename, view->name) == 0) { result = dns_viewlist_find(&named_g_server->viewlist, cachename, From fe4d9d9e6ae327564dc6a761e875b5a4ce3963ed Mon Sep 17 00:00:00 2001 From: Colin Vidal Date: Thu, 18 Sep 2025 09:04:39 +0200 Subject: [PATCH 3/3] remove useless namedconf option in test namedconf `request-zoneversion` option doesn't exists on 9.20, and was actually useless for the purpose of the reload/fail/success cache test. Remove this option so the test can run on 9.20 --- bin/tests/system/resolver/ns1/named.conf.j2 | 1 - 1 file changed, 1 deletion(-) diff --git a/bin/tests/system/resolver/ns1/named.conf.j2 b/bin/tests/system/resolver/ns1/named.conf.j2 index ff3caa8216..52e4a33a39 100644 --- a/bin/tests/system/resolver/ns1/named.conf.j2 +++ b/bin/tests/system/resolver/ns1/named.conf.j2 @@ -26,7 +26,6 @@ options { max-zone-ttl unlimited; resolver-query-timeout 5000; # 5 seconds max-recursion-queries 100; - request-zoneversion yes; }; view "default" {