chg: usr: Add Extended DNS Error 13 (Cached Error) support

Extended DNS Error 13 (Cached Error) is now returned when the server
answers a message from a cached SERVFAIL.

See RFC 8914 section 4.14.

See #1836

Merge branch '1836-sfcache-ede' into 'main'

See merge request isc-projects/bind9!11322
This commit is contained in:
Colin Vidal
2025-12-05 23:28:36 +01:00
4 changed files with 52 additions and 2 deletions

View File

@@ -13,6 +13,8 @@
// NS5
{% set servfail_ttl = servfail_ttl | default(30) %}
options {
query-source address 10.53.0.5;
notify-source 10.53.0.5;
@@ -23,7 +25,7 @@ options {
listen-on-v6 { none; };
recursion yes;
dnssec-validation yes;
servfail-ttl 30;
servfail-ttl @servfail_ttl@;
};
key rndc_key {

View File

@@ -18,7 +18,6 @@ set -e
copy_setports ns1/named.conf.in ns1/named.conf
copy_setports ns2/named.conf.in ns2/named.conf
copy_setports ns5/named.conf.in ns5/named.conf
cd ns1 && $SHELL sign.sh && cd ..
cd ns5 && $SHELL sign.sh && cd ..

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.
import time
import isctest
from isctest.compat import EDECode
def check_sfcache_ede(ns, ede):
msg = isctest.query.create("foo.example.", "A")
res = isctest.query.udp(msg, ns.ip)
isctest.check.servfail(res)
if ede:
isctest.check.ede(res, EDECode.CACHED_ERROR)
else:
isctest.check.noede(res)
def test_sfcache_ede(ns5, templates):
# Reconfigure the server so servfail-ttl is 1 second
templates.render("ns5/named.conf", {"servfail_ttl": 1})
with ns5.watch_log_from_here() as watcher:
ns5.rndc("reload")
watcher.wait_for_line("running")
# First query do not have a cached SERVFAIL, no EDE
check_sfcache_ede(ns5, False)
# Immediates next queries are cached SERVFAIL, EDE present
check_sfcache_ede(ns5, True)
check_sfcache_ede(ns5, True)
# Wait enough time so we know he cached SERVFAIL is removed
time.sleep(2)
# And again, first query is not cached, subsequent ones are.
check_sfcache_ede(ns5, False)
check_sfcache_ede(ns5, True)
check_sfcache_ede(ns5, True)

View File

@@ -6832,6 +6832,7 @@ ns__query_sfcache(query_ctx_t *qctx) {
"0");
}
dns_ede_add(&qctx->client->edectx, DNS_EDE_CACHEDERROR, NULL);
qctx->client->inner.attributes |= NS_CLIENTATTR_NOSETFC;
QUERY_ERROR(qctx, DNS_R_SERVFAIL);
return ns_query_done(qctx);