Štěpán Balážik [Wed, 29 Oct 2025 17:59:31 +0000 (18:59 +0100)]
Allow users of AsyncDnsServer to set AA bit for all responses
Previously, all responses had to be set as authoritative explicitly
using DnsResponseSend(..., authoritative=True). After using this,
it became obvious that this is obnoxious.
Add an optional keyword-only parameter to AsyncDnsServer that sets the
default value of the AA bit on outgoing responses.
Make all the other parameters keyword-only as well.
Štěpán Balážik [Thu, 30 Oct 2025 12:41:23 +0000 (13:41 +0100)]
Refactor ControllableAsyncDnsServer setup
When this class was introduced, the constructor of its base class had no
parameters. This was changed in the meantime and these parameters were
not accessible by users of the subclass.
Don't override the constructor.
Move command setup to methods.
Move subclass-specific storage to cached properties.
Take instances of Command instead of the classes themselves for
symmetry with install_response_handler.
Arаm Sаrgsyаn [Wed, 17 Dec 2025 14:55:43 +0000 (14:55 +0000)]
fix: usr: Fix a possible catalog zone issue during reconfiguration
The :iscman:`named` process could terminate unexpectedly during
reconfiguration when a catalog zone update was taking place at
the same time. This has been fixed.
Merge branch 'aram/catz-reconfig-crash-fix' into 'main'
Aram Sargsyan [Fri, 5 Dec 2025 10:06:28 +0000 (10:06 +0000)]
Lock the catalog zone when reconfiguring it
A catalog zone is updated in an offloaded thread, which is not
stopped during a reconfiguration in an exclusive mode, and so
can cause a race condition with it.
Waiting for the offloaded threads to complete their work before
entering into the exclusive mode can potentially cause unwanted
delays, because offloaded threads are generally "allowed" to take
a longer amount of time before they complete.
Add a dns_catz_zone_prereconfig()/dns_catz_zone_postreconfig() pair
of functions which currently just lock the catalog zone when
reconfiguring it. The change should eliminate the race.
As a side note, there was already a similar pair of functions,
dns_catz_prereconfig() and dns_catz_postreconfig() which are called
before and after reconfiguring a 'dns_catz_zones_t' object.
Below are the stack traces of the reconfiguration thread which has
asserted, and a catalog zone update thread which was caught in the
middle of its work despite the fact that the exclusive mode is
turned on.
Ondřej Surý [Wed, 17 Dec 2025 07:38:34 +0000 (08:38 +0100)]
Cleanup the extra dns_rdataset_disassociate() code
Manually go through the code using dns_rdataset_isassociated() and
use dns_rdataset_cleanup() where appropriate in places that a simple
semantic patch is not able to find automatically.
Add a tag pipeline CI job to update the stable tag after a release
Introduce a CI job to update the "stable" tag with the latest released
stable version tag. This is a manual job that only runs in tag
pipelines in the context of a release.
Colin Vidal [Wed, 17 Dec 2025 09:18:53 +0000 (10:18 +0100)]
new: usr: Add support for Extended DNS Error 9 (Missing DNSKEY)
Extended DNS Error 9 (Missing DNSKEY) is now sent when a validating resolver attempts to validate a response but can't get the DNSKEY from the authoritative server of the zone, while the DS record is present in the parent zone.
Colin Vidal [Tue, 16 Dec 2025 18:33:50 +0000 (19:33 +0100)]
update SERVFAIL cache test
An existing SERVFAIL cache test is updated as it initially checks there
are no EDE (the first SERVFAIL) then immediately re-does the same query,
(still SERVFAIL), and expect the CACHED_ERROR EDE.
However, the configuration used for this test to generate a SERVFAIL is
a broken DNSSEC configuration, where the DNSKEY is not the expected one
(it's a ZSK instead of a KZK). As a result, the first attempt also now
raise an EDE (MISSING_DNSKEY).
Colin Vidal [Wed, 3 Dec 2025 13:22:43 +0000 (14:22 +0100)]
add system tests covering EDE 9
The authoritative server on "missing-dnskey." zone is ns2, the zone is
initially signed normally, but then the DNSKEY are pulled out from the
signed generated zone file. As a consequence, a quering the resolver ns4
returns a SERVFAIL with EDE9 as the chain of trust is broken: the DS is
prsent in the parent zone (the root zone in ns1), but the DNSKEY is
missing from the zone.
A similar is "wrong-dnskey.", but here the zone is signed correctly,
but the DS points to a different DNSKEY. Hence no supported matching
DNSKEY record could be found for the child.
Colin Vidal [Wed, 3 Dec 2025 13:20:20 +0000 (14:20 +0100)]
add support for EDE 9
Extended DNS Error 9 (Missing DNSKEY) is now sent when a validating resolver
attempts to validate a response but can't get the DNSKEY from the authoritative
server of the zone, while the DS record is present in the parent zone.
Note the EDE 9 is send as part of the proveunsecure flow, after the
validator successfully fetched the DS of the zone from the parent. So if
the DS is also missing, the EDE 9 won't be sent.
Michal Nowak [Tue, 16 Dec 2025 20:25:37 +0000 (21:25 +0100)]
chg: test: Temporarily change pytest.PytestRemovedIn9Warning error to warning
We need this to be able to use pytest 9.0 from Debian "sid".
Additionally, this error needs to be addressed before pytest 9.1 is
released, as the filter will no longer work. Also, all pytests in CI
images need to be upgraded to version 7, where the new API is supported.
Related #5690
Merge branch 'mnowak/ignore-pytest-PytestRemovedIn9Warning' into 'main'
Michal Nowak [Tue, 16 Dec 2025 18:03:38 +0000 (19:03 +0100)]
Temporarily change pytest.PytestRemovedIn9Warning error to warning
We need this to be able to use pytest 9.0 from Debian "sid".
Additionally, this error needs to be addressed before pytest 9.1 is
released, as the filter will no longer work. Also, all pytests in CI
images need to be upgraded to version 7, where the new API is supported.
We can't have the "filterwarnings" section in pytest.ini directly as
only pytest 8.0 knows about it.
Ondřej Surý [Tue, 16 Dec 2025 10:11:05 +0000 (11:11 +0100)]
Copy only the raw data when we are copying dns_slab{header,vec}
The makeslab function in rdataslab.c contains an optimization for cases
where the source is already an rdataslab. In these cases, it copies the
entire slab using memmove. However, this creates a race condition: while
the target slab is protected by a node lock, the source slab is not
protected. This becomes problematic because the TTL heap needs to
modify the heap index stored in the slab header, potentially while the
memmove operation is reading from it.
A closer look at makeslab shows that copying the header part of the slab
is unnecessary, the header can be default-initialized instead. This MR
modifies makeslab to copy only the raw part of the slab, while
default-initializing the header, eliminating the race condition. For
consistency, it also applies the same change to vecheader/makevec.
Alessio Podda [Tue, 16 Dec 2025 17:06:12 +0000 (17:06 +0000)]
fix: dev: Unpack struct vecheader
The bitset packing of the resign_lsb and heap_index in struct vecheader was causing a race condition, since both bindrdataset and heap operations tried to access the same byte (even though they are accessing different fields).
While heap operations are protected by the node lock of the header being inserted, they aren't protected by the node locks of the headers being displaced, leading to the race condition.
This MR fixes the issue by reverting the struct packing optimization.
Closes #5688
Merge branch '5688-no-heap-index-bitset' into 'main'
Alessio Podda [Tue, 16 Dec 2025 14:39:45 +0000 (15:39 +0100)]
Unpack struct vecheader
The bitset packing of the resign_lsb and heap_index in struct vecheader
was causing a race condition, since both bindrdataset and heap
operations tried to access the same byte (even though they are accessing
different fields).
While heap operations are protected by the node lock of the header being
inserted, they aren't protected by the node locks of the headers being
displaced, leading to the race condition.
This commit fixes the issue by reverting the struct packing
optimization.
Arаm Sаrgsyаn [Wed, 10 Dec 2025 17:30:50 +0000 (17:30 +0000)]
fix: usr: Fix the charts in the statistics channel
The charts in the statistics channel could sometimes fail
to render in the browser, and were completely disabled for
Mozilla-based browsers for historical reasons. This has
been fixed.
Merge branch 'aram/stats-channel-charts-fix' into 'main'
The statistics channel's HTML presentation has charts, but it has
a couple of problems.
1. Because of an inconsistent condition, a chart's JS code might have
been executed, while the HTML markup wasn't present, and this is
causing a JS error.
2. The feature is turned off on Mozilla-based browsers.
Fix the inconsistency in conditions, remove the conditional rendering
which disabled the feature for Mozilla-based browsers by looking at
the XSLT processor's name, and fix indentation inconsistencies.
This is a new seek function for dbiterator that is meant to find an
NSEC3 node in a zone database. The difference with dns_dbiterator_seek
is that if the node does not exist, this seek function will point the
iterator to the next NSEC3 name.
This test signs a large delegation with mostly insecure delegations
with NSEC3 optout. Once the NSEC3PARAM record is published, run
dnssec-verify to ensure the zone is correctly signed.
Alessio Podda [Tue, 9 Dec 2025 20:05:27 +0000 (21:05 +0100)]
Add DNS_VECHEADER_FOREACH
Add a FOREACH macro modelled around the DNS_RDATASET_FOREACH one, that
uses vecheader directly. Useful when you want to manipulate a vecheader
without binding it to avoid having to take the node lock inside qpzone.c.
Alessio Podda [Mon, 24 Nov 2025 08:16:18 +0000 (09:16 +0100)]
Add rdatavec
Add an implementation of rdataset specialized for authoritative
workloads. For now, it is a copy of rdataslab, with redundant fields
from the header removed.
Alessio Podda [Wed, 10 Dec 2025 11:15:24 +0000 (11:15 +0000)]
chg: dev: Remove unused foundname parameter
The `foundname` parameter in `qp.c:dns_qp_lookup` was effectively used only in unit tests, as in every case the name is needed, it can be retrieved directly from the node pointer. It also required an inefficient implementation that extracted the name by converting it into a key and then immediately converting it back.
This MR refactors `qp.c:dns_qp_lookup` not to have a foundname parameter, resulting in a 5% speedup in the handling of NXDOMAIN responses in perflab.
Merge branch 'alessio/qp-no-foundname' into 'main'
Alessio Podda [Tue, 9 Dec 2025 16:41:33 +0000 (17:41 +0100)]
Fix formatting after refactor
The removal of the foundname and name parameters from various qp.c
functions led to formatting issues. Restore the correct formatting via
clang-format.
Alessio Podda [Mon, 1 Dec 2025 14:12:01 +0000 (15:12 +0100)]
Remove maybe_set_name
Outside of unit tests, the name parameter in dns_qpiter_<...> and
dns_qpchain_<...> is only used in context where the name can be
extracted directly from the underlying node.
This commits modifies the signatures of dns_qpiter_<...> and
dns_qpchain_<...> not to have a name parameter. Where the name parameter
was needed, we now query the node and copy the name directly from it.
This allows us to remove maybe_set_name from qp.c. Besides simplifying
the API, this leads to a performance speedup for NXDOMAIN handling,
as we avoid calling maybe_set_name inside step, and maybe_set_name is
very inefficient.
A copy of the implementation maybe_set_name is retained for the unit
tests.
Alessio Podda [Sun, 23 Nov 2025 13:59:30 +0000 (14:59 +0100)]
Remove unused foundname parameter
The `foundname` parameter in dns_qp_lookup is used only in the unit
tests. This commit simplifies the API by removing it, and modifying the
unit tests to extract the name from pval.
Evan Hunt [Tue, 9 Dec 2025 21:20:06 +0000 (21:20 +0000)]
fix: dev: dns_name_totext() can now resize dynamic buffers
When `dns_name_totext()` is called with a dynamically allocated
target buffer which is too small for the name, it will now resize
the buffer instead of returning `ISC_R_NOSPACE`.
Merge branch 'each-name-totext-resize' into 'main'
Evan Hunt [Wed, 26 Nov 2025 03:48:02 +0000 (19:48 -0800)]
dns_name_totext() can now resize dynamic buffers
When dns_name_totext() is called with a dynamically allocated
target buffer which is too small for the name, it will resize
the buffer instead of returning ISC_R_NOSPACE.
Ondřej Surý [Fri, 28 Nov 2025 14:13:58 +0000 (15:13 +0100)]
Add more information to the rndc recursing output about fetches
It is possible to have a fetch that is active, but it has been cloned,
so it won't be used when found in the hash table. The fetch options
also prevent matching in the hash table, so add a hexadecimal dump of
the fctx->options to the output.
Nicki Křížek [Tue, 9 Dec 2025 13:27:31 +0000 (14:27 +0100)]
chg: test: Convert all named.conf in system tests to jinja2
Replace all the `named.conf*.in` files to use jinja2 templates instead. This makes it possible to drop the `copy_setports` function, makes room for further `setup.sh` cleanup, and prepares for future de-duplication of the configs (common settings as well as shared configs within one test dir).
Merge branch 'nicki/convert-to-jinja2-templates' into 'main'
Nicki Křížek [Mon, 1 Dec 2025 15:25:16 +0000 (16:25 +0100)]
Use jinja2 templates in kasp test
- ns3 had fips/rsasha1 config variants. These were refactored similarly
to the way they're handled in nsec3 test.
- ns3 special character zone contains @, which is interpreted by jinja2.
To avoid, {% raw %} directive was added
- ns6 contained unused policies and named2.conf, these were removed
Nicki Křížek [Fri, 5 Dec 2025 16:04:33 +0000 (17:04 +0100)]
Use jinja2 templates in serve-stale test
The ns1 named.conf files were sufficiently similar to allow for
de-duplication. No attempt to de-duplicate ns3 was made due to
significant differences among the config files.
Nicki Křížek [Fri, 5 Dec 2025 16:03:24 +0000 (17:03 +0100)]
Use jinja2 templates in catz test
- Use a common ns2/named.conf.j2 template for all the "#TN"
replacements. Instead of commenting out with sed, render the template
differently into ns/namedX.conf using variables.
- Keep the final ns2/named7.conf.j2 (formerly ns2/named2.conf.in) as a
separate template for readability due to significant differences.
Nicki Křížek [Fri, 5 Dec 2025 16:17:46 +0000 (17:17 +0100)]
Use jinja2 templates in rpz test
- The ns3/named.conf.j2 uses has a "#BAD" section that is only included
after restart. Turn it into ns3/named2.conf.
- Since the original config is then restored, keep a copy of it as
ns3/named1.conf using a symlink, causing it to be rendered twice.
- Use jinja2 templates for test* files to render the port number instead
of calling copy_setports in load_db().
Nicki Křížek [Fri, 5 Dec 2025 16:04:47 +0000 (17:04 +0100)]
Use jinja2 templates in staticstub test
- Instead of strings to be replaced by sed, use proper jinja templates.
- ns3/named1.conf.j2 is basically a copy of the default config, because
it needs to be restored later in the test.
Nicki Křížek [Mon, 8 Dec 2025 10:10:47 +0000 (11:10 +0100)]
Use jinja2 templates in resolver test
- Move ns1/named.conf.j2 to ns1/named2.conf.j2 and adjust the python
test to render this template.
- Convert remaining .in files to .j2 and handle the multiple configs.
Nicki Křížek [Fri, 5 Dec 2025 16:39:23 +0000 (17:39 +0100)]
Use jinja2 templates in views test
- Rename named.conf.j2 to named3.conf.j2 and adjust the python test to
render this template.
- Handle the n2 and ns3 multiple configs as in other similar cases
(ns2/named1.conf.in was moved to ns2/named.conf.j2).
Nicki Křížek [Fri, 5 Dec 2025 16:19:59 +0000 (17:19 +0100)]
Use jinja2 templates in statistics test
- Merge ns*/statistics-channels.conf.in config snippets into
conditionally rendered section in ns*/named.conf.j2 files.
- Turn ns2/named.conf.in into ns2/named1.conf.j2 because it is used
later in the test to restore the original config.
- Symlink the ns2/named.conf.j2 ns2/named1.conf.j2 to pick a starting
config.
Nicki Křížek [Fri, 5 Dec 2025 16:04:25 +0000 (17:04 +0100)]
Use jinja2 templates in rpzrecurse test
- Change ns2 header into jinja2 template.
- Keep the various ns2 config files as non-templates, same for the
named.default.conf to be consistent.
- Symlink the ns2/named.default.conf as a jinja2 template to pick a
starting config. It is rendered as a template to avoid an error when
the test would overwrite a git-tracked file.
- Use jinja2 templates for the ns3 files, keep named1.conf around
because it's needed later in the test to restore the config. Symlink
it to `ns3/named.conf.j2` to select a default config.
Nicki Křížek [Fri, 5 Dec 2025 16:04:16 +0000 (17:04 +0100)]
Use jinja2 templates in nsupdate test
- Merge ns1/tls.options.in into ns1/named.conf.j2 and render it
conditionally. Also conditionally include the additional
ns1/tls.conf.j2 which is always rendered.
- Use multiple templates for ns7 and replace the copy_setports.
- Use jinja2 template for verylarge.in as well.
Nicki Křížek [Fri, 5 Dec 2025 16:04:08 +0000 (17:04 +0100)]
Use jinja2 templates in notify test
- Merge options-tls.conf into named.conf in ns2 and ns4 and render it
conditionally. Also conditionally include the additional
named-tls.conf which is always rendered.
Nicki Křížek [Fri, 5 Dec 2025 16:03:51 +0000 (17:03 +0100)]
Use jinja2 templates in forward test
- Merge options-tls.conf into named.conf in ns2 and ns4 and render it
conditionally. Also conditionally include the additional
named-tls.conf which is always rendered.
- Use multiple templates for ns3 and ns9 and replace the copy_setports.
- In ns3/named2.conf, use "root2.db" directly rather than replacing it
with "sed" later.
Nicki Křížek [Fri, 5 Dec 2025 13:50:55 +0000 (14:50 +0100)]
Use jinja2 templates in logfileconf test
- Replace all named*.in files with jinja2 templates.
- Rename the config files to named.*.conf convention.
- Rename named.plain.in to named.plain.conf.j2 and symlink it as te
default config.
- Rename named.plainconf.in to named.plainlog.conf.j2 (there is a slight
difference from named.plain, despite the similar name)
Nicki Křížek [Fri, 5 Dec 2025 14:12:29 +0000 (15:12 +0100)]
Use jinja2 templates in runtime test
- Replace named-altX.conf.in with namedX.conf.j2 to stick with the same
naming convention across the entire code base. Note than due to
named1.conf being the first (default) config, the numbers for the altX
are incremented.
- Turn alt9 into named7 to stick with the same number sequence. Adjust
the related file names accordingly.
Nicki Křížek [Tue, 9 Dec 2025 08:57:12 +0000 (09:57 +0100)]
Replace .in with .j2 templates for cases with namedX.conf
The following tests use multiple named configs. Previously, these have
been rendered with copy_setports in tests.sh when needed. Transform
these into jinja2 templates and render them during setup. In the tests,
the copy_setports invocations can be then replaced with a simple cp.
Nicki Křížek [Mon, 1 Dec 2025 16:01:52 +0000 (17:01 +0100)]
Allow any named*.conf file as a system test artifact
This allows rendering multiple named*.conf files using the jinja2
template engine at test start and then simply copying the required
config to named.conf as needed.
Alessio Podda [Tue, 9 Dec 2025 13:06:03 +0000 (13:06 +0000)]
fix: usr: Resolve "Inbound IXFR performance regression between 9.18.31 and 9.20.9"
This MR adds add some specialized logic to handle IXFR in qpzone, avoiding the need to have one qp transaction per rdataset.
We do this in multiple steps:
- We extend dns_rdatacallbacks_t vtable to allow subtraction and resigning.
- We add a new set of api (begin|commit|abort)update to the dbmethods vtable. These API model an incremental update that can be aborted, and make diff apply use these functions instead of adding the rdatasets directly to the database.
- We add a specialization of dns_rdatacallbacks_t to qpzone that uses a single qp transaction for the entire IXFR.
With this batch API, we see performance improvements over adding one rdataset at a time.
Closes #5442
Merge branch '5442-ixfr-batch-transaction' into 'main'
Andoni Duarte [Tue, 9 Dec 2025 12:17:57 +0000 (12:17 +0000)]
[9.21.16] fix: usr: Adding NSEC3 opt-out records could leave invalid records in chain
When creating an NSEC3 opt-out chain, a node in the chain could be removed too soon, causing the previous NSEC3 being unable to be found, resulting in invalid NSEC3 records to be left in the zone. This has been fixed.
Closes isc-projects/bind9#5671
Backport of isc-projects/bind9!11328
Merge branch '5671-fix-dbiterator-prev-9.21.16' into 'v9.21.16-release'
Alessio Podda [Sat, 25 Oct 2025 09:01:35 +0000 (11:01 +0200)]
Implement qpzone specific update path
This commit implements a batch update function for qpzone. The main
reason for this is speed: using addrdataset would cause a qp transaction
per rrdataset added, leading to a substantial slowdown compared to
RBTDB. The new API results in a qp transaction per applied diff.
Alessio Podda [Fri, 24 Oct 2025 22:47:42 +0000 (00:47 +0200)]
Abstract updates into a vtable
This commit adds a layer of indirection to the apply_diff logic used by
IXFR and resigning by having the database updates go through a vtable.
We do this in three steps:
- We extend dns_rdatacallbacks_t vtable to allow subtraction and
resigning.
- We add a new set of api (begin|commit|abort)update to the dbmethods
vtable, that model an incremental update that can be aborted.
- We extract the core logic of diff_apply into a function that
satisfies the new interface.
- We make diff_apply use this new function, and log the results.
The intent of this commit is to allow databases to expose a batch
incremental update implementation, just like they expose a custom
batch creation implementation through (begin|end)load.
Alessio Podda [Sat, 25 Oct 2025 09:01:27 +0000 (11:01 +0200)]
Clean up ixfr transaction API
Make the API tighter. The idea of this commit is to highlight the
distinction between a database transaction and a journal transaction,
and ensure we run dns_zone_verifydb on error.