Commit graph

46086 commits

Author SHA1 Message Date
Ondřej Surý
7e9bb91087
Inline prefix into radix tree node
Embed isc_prefix_t directly in isc_radix_node_t instead of heap-
allocating it separately. This eliminates per-node isc_mem_get/put
and isc_mem_attach/detach calls, removes a pointer dereference on
every search comparison, and simplifies the code by removing the
_new_prefix, _ref_prefix, and _deref_prefix helpers entirely.

Remove isc_mem_t from isc_prefix_t since it is now a plain value
type with no memory management. Remove per-node isc_mem_t since
nodes use the tree's memory context. Reorder struct fields to
eliminate padding holes.
2026-07-01 06:05:55 +02:00
Ondřej Surý
db9d9313c2
Remove prefix refcounting from radix tree
Radix tree prefixes were reference-counted to allow sharing between
nodes, with refcount==0 used as a sentinel for stack-allocated
prefixes. Since the radix tree is only modified during config
parsing (single-threaded) and read-only during query processing,
the sharing optimization is unnecessary. Always copy prefixes
instead, eliminating the refcount field and the sentinel hack.
2026-07-01 06:05:52 +02:00
Michal Nowak
219f23cb80 new: test: Add build-time check for unregistered rdata files
Fail at meson configure if an rdata source file in lib/dns/rdata is not
registered in dns_header_depfiles, so edits no longer silently skip
header regeneration (as happened with brid, dsync, hhit, and wallet).

Assisted-by: Claude:claude-opus-4-8

Merge branch 'mnowak/check-rdata-registration' into 'main'

See merge request isc-projects/bind9!12219
2026-06-30 19:20:11 +02:00
Michal Nowak
11539c7f4a Check for unregistered rdata files in CI
Verify in the misc CI job that every rdata source file under
lib/dns/rdata is an input of the generated lib/dns/code.h, i.e.
registered in dns_header_depfiles.  An unregistered file is still
compiled into BIND 9 (gen.c scans the directories directly), but
editing it does not trigger regeneration of code.h.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 19:19:37 +02:00
Michal Nowak
f27acdfd5a fix: dev: Assorted Meson fixes
Merge branch 'mnowak/meson-ci-fixes' into 'main'

See merge request isc-projects/bind9!12167
2026-06-30 19:01:50 +02:00
Michal Nowak
2541674a9a Fix typo in build_vars comment
Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Michal Nowak
6d4c84f92c Quote paths in the meson helper scripts
Quote variable expansions, guard MESON_BUILD_ROOT, and enable
nullglob so paths with spaces and empty globs are handled.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Michal Nowak
03bf372c67 Raise nm timeout in the sanitizer defaults check
A 1 second timeout could abort the check on loaded runners.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Michal Nowak
3d9adf2e4e Base the readline check on the configured flags
WITH_LIBEDIT/WITHOUT_LIBEDIT are always-set globals, so the check
always asserted libedit was absent. Inspect EXTRA_CONFIGURE instead.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Michal Nowak
b953ca2c4a Drop duplicate dnstap-read.rst entry
It was added both unconditionally and gated on HAVE_DNSTAP; keep
only the gated entry.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Michal Nowak
9bd37c733a Install the synthrecord man page
It was missing from man_srcset, unlike the other plugin man pages.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Michal Nowak
0802265776 Track new generic rdata files for header generation
brid, dsync, hhit and wallet were missing from the header
dependency list, so edits to them did not regenerate headers.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Michal Nowak
fd1260e675 Avoid leaking FLAKY into every unit test
meson stores the test env by reference, so mutating the shared
test_env leaked FLAKY and TIMEOUT into all later tests. Build a
fresh environment for flaky tests instead.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Michal Nowak
559814afd9 Fix named.conf and named.pid path substitutions
Both substitutions wrongly expanded to named.key.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Michal Nowak
8fd7e3395e Check the host system for dtrace on macOS
The macOS dtrace check used build_machine, breaking cross builds;
use host_machine like every other Darwin check.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Michal Nowak
fc5a6ea3fe Look up urcu-common without the lib prefix
cc.find_library() expects the bare library name, so liburcu-common
was never found on liburcu < 0.13.0.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Michal Nowak
7c27c7160b Set HAVE_ARM_YIELD instead of HAVE_SPARC_PAUSE on arm
pause.h keys the arm yield instruction off HAVE_ARM_YIELD, so 32-bit
arm never got the fast path.

Assisted-by: Claude:claude-opus-4-8
2026-06-30 17:03:25 +02:00
Alessio Podda
58c570e518 fix: dev: Fold receive_secure_serial into zone maintainance
Having two separate zone maintainance async jobs increases the risk of
race conditions. This commit folds the inline-signing resigning job
into the zone maintainance of the secure zone, ensuring only one async
job acts on a zone.

Closes #5816

Merge branch '5816-resign-single-source-of-truth' into 'main'

See merge request isc-projects/bind9!12005
2026-06-30 13:36:46 +00:00
Alessio Podda
c2e2776b86 Split inline sync state into a separate struct
The inline sync state is only needed when there is a raw-to-secure sync
in progress, and should be handled "atomically".

This commit creates a separate structure that holds all the inline sync
state to streamline the creation and cleanup.
2026-06-30 12:36:46 +00:00
Alessio Podda
0001066fb6 Rename inline sync related methods
The inline sync related methods and structs retained the old
receive_secure_ prefix. Since there is no async tasks involved anymore
we change the naming scheme to a more descriptive one.
2026-06-30 12:36:46 +00:00
Alessio Podda
158b411667 Fix rss_state leak in receive_secure_serial_cancel
Previously receive_secure_serial_cancel() could leak .rss_state on
inline secure bootstrap or zone shutdown, if a pre-existing DNSSEC
signing pass was paused. This has been fixed.
2026-06-30 12:36:46 +00:00
Alessio Podda
0d95e2575a Serialize zone maintenance requests
Some rndc-driven maintenance operations interact with raw-to-secure
synchronization in the same way as setting NSEC3PARAM did. They are
scheduled via async tasks, which can interleave with raw-to-secure sync
and cause crashes.

To solve this, treat them the same as NSEC3PARAM changes, and extend
the pending NSEC3PARAM change queue to a generic maintenance queue that
rndc can post commands to.

These commands are dispatched by the zone_maintenance() callback, which
delays them if a raw-to-secure sync is in progress.
2026-06-30 12:36:46 +00:00
Alessio Podda
5efad56c16 Fix setnsec3param DNSSEC maintenance ordering
Before this commit, NSEC3PARAM changes were scheduled through an async
callback. This leads to a similar problem of interleaving with an
existing raw-to-secure sync, which is unsound since only one writer
version can be active at a time.

The zone already has a queue of "pending" NSEC3PARAM changes, so the
use of async tasks is also redundant. With this commit, we schedule
NSEC3PARAM changes using the pre-existing queues plus a timer.
2026-06-30 12:36:46 +00:00
Alessio Podda
350134f68d Move inline sync into zone maintenance
Before this commit, synchronization between raw and secure zones ran as
async tasks split into quanta. As a consequence, it could interleave
with some zone maintenance operations.

However, synchronization between raw and secure zones needs to keep the
version open across the full operation. There can be only one writer
version open at a time, which makes any model where synchronization and
maintenance interleave unsound.

To fix that, this commit models raw-to-secure synchronization as an
explicit state machine and moves the synchronization operations inside
the zone_maintenance() callback.

This way, zone maintenance operations can be intercepted so they do not
run on a partially synced secure zone. Pending zone maintenance or sync
operations can also be flushed when a full database reload has happened
on the raw side.
2026-06-30 12:36:46 +00:00
Alessio Podda
0bb6cd432c Add NSEC3-to-NSEC rollover regression test
Before this commit, the NSEC3-to-NSEC transition was only tested by
test_nsec_case[nsec3-to-rsasha1-ds.kasp], which is gated by
RSASHA1_SUPPORTED.

Add another test that does not depend on RSASHA1_SUPPORTED, so this
coverage also runs when RSASHA1 signing is unavailable, such as with
newer OpenSSL configurations.
2026-06-30 12:36:46 +00:00
Alessio Podda
f2562548c8 Refactor zone timer time handling 2026-06-30 12:36:46 +00:00
Aydın Mercan
b362e0b30d fix: usr: validate query and response time nanosecs when parsing dnstap
An assertion is triggered inside `isc_time_set` when dnstap-read calls
`dns_dt_parse` on dnstap files with query/response time nanosecond
fields greater than a second.

Avoid the assertion by validating the nanosecond fields to be subsecond
when parsing.

Closes #6123

Merge branch '6123-dnstap-parse-invalid-nsec-assert-md' into 'main'

See merge request isc-projects/bind9!12224
2026-06-30 12:40:20 +03:00
Aydın Mercan
1fc06937cd validate query and response time nanosecs when parsing dnstap
An assertion is triggered inside `isc_time_set` when dnstap-read calls
`dns_dt_parse` on dnstap files with query/response time nanosecond
fields greater than a second.

Avoid the assertion by validating the nanosecond fields to be subsecond
when parsing.
2026-06-30 12:08:29 +03:00
Aydın Mercan
c737e3160e add unit test for invalid dnstap entries
Test `dns_dt_parse` against:
- query nanosecond field over a second
- response nanosecond field over a second
- invalid message type field
2026-06-30 12:08:29 +03:00
Matthijs Mekking
9155946be8 fix: dev: Remove dead code warnings found by scan-build
Small cleanup, fixing the dead code issues found by scan-build.

Patch submitted by Tim Rühsen.

Closes #6165

Merge branch '6165-dead-code-warnings-found-by-scan-build' into 'main'

See merge request isc-projects/bind9!12293
2026-06-29 10:32:46 +00:00
Matthijs Mekking
19da825b72 Small update to patch
../lib/dns/rdataslab.c
../lib/dns/rdataslab.c:168:3: error: expression result unused; should this cast be to 'void'? [-Werror,-Wunused-value]
  168 |                 (void *)newslab(rdataset, mctx, region, 0, buflen);
      |
2026-06-29 10:00:17 +00:00
Matthijs Mekking
77754dad29 Remove dead code warnings found by scan-build
Small cleanup, fixing the dead code issues found by scan-build.

Patch submitted by Tim Rühsen.
2026-06-29 10:00:17 +00:00
Mark Andrews
aa8a07991d fix: usr: Tighten referral DS acceptance
Named was accepting DS records for sibling zones when it shouldn't
have.  This has been fixed.

Closes #5870

Merge branch '5870-tighten-referral-ds-acceptance' into 'main'

See merge request isc-projects/bind9!11837
2026-06-25 16:04:32 +10:00
Nicki Křížek
a2b9dcff54 Add dnssec_py/tests_sibling_ds: reject DS for sibling zones in referrals
Add a system test that verifies the resolver rejects DS records whose
owner name does not match the delegation (NS) name in a referral
response.

A custom authoritative server (ans4) serves the parent zone sibling-ds.
from zone file with delegations for child and sibling subzones.  Its
DomainHandler injects a DS record for sibling.sibling-ds into referrals
for child.sibling-ds.  The resolver must detect the mismatch, log "DS
doesn't match referral (NS)", and return SERVFAIL.

Assisted-by: Claude:claude-opus-4-8
2026-06-25 15:21:00 +10:00
Nicki Křížek
95a268f119 Don't include ORIGIN for AsyncDnsServer zones
The zone template can't use $ORIGIN with AsyncDnsServer because
AsyncDnsServer._load_zone_file_with_origin() rejects it for non-root
zones.
2026-06-25 15:21:00 +10:00
Mark Andrews
123934931f Tighten referral DS acceptance
Named was accepting DS records for sibling zones when it shouldn't
have.  Only DS rrsets that match the delegation name should have
been accepted.

Remove ds_name from struct respctx as it is no longer useful.
2026-06-25 15:21:00 +10:00
Evan Hunt
89e57b45e0 fix: usr: Check that an NSEC signer is at or above the name to be validated
Add a check that an NSEC record being used as a proof of nonexistence
for a given name is not signed by a name lower in the DNS hierarchy than
the one in question.

Closes #5876

Merge branch '5876-nsec-signer-above-name' into 'main'

See merge request isc-projects/bind9!12272
2026-06-24 21:04:20 +00:00
Alessio Podda
4fb662a171 Reproducer for #5876 child apex self-loop NSEC
Added to "nsec_synthesis" system test.

Co-Authored-By: Evan Hunt <each@isc.org>
2026-06-24 21:03:45 +00:00
Evan Hunt
c5f99f3508 Check that an NSEC signer is at or above the name to be validated
Add a check that an NSEC record being used as a proof of nonexistence
for a given name is not signed by a name lower in the DNS hierarchy than
the one in question.

Fixes: isc-projects/bind9#5876
2026-06-24 21:03:45 +00:00
Colin Vidal
6a41fa3e9c fix: test: Fix RRL test random failure
RRL test were randomly failing because `ns2` hint files uses

```
.	NS	ns1.
ns1.	A	10.53.0.1
```

Whereas `ns1` root zone didn't contains `ns1.` as NS (but only `ns.`).
This is a problem with the following scenario:

- A query starts before priming;
- It gets the root hints as zonecut (with `. NS ns1.`, and no glues, this
  is how parent-centric currently works);
- Priming starts and complete (so now rootdb contains the answer/glues
  from `ns1` root file);
- Then the query go to ADB to resolve `ns1.`.

Resolution of `ns1.` fails since it doesn't exists from the rootdb
anymore. This is a configuration issue (the resolver behavior is correct
and expected) whch is now fixed.

Closes #6032

Merge branch '6032-fix-rrl' into 'main'

See merge request isc-projects/bind9!12322
2026-06-24 22:31:27 +02:00
Colin Vidal
49cb99bb08 Fix RRL random failure
RRL test were randomly failing because `ns2` hint files uses

```
.	NS	ns1.
ns1.	A	10.53.0.1
```

Whereas `ns1` root zone didn't contains `ns1.` as NS (but only `ns.`).
This is a problem with the following scenario:

- A query starts before priming;
- It gets the root hints as zonecut (with `. NS ns1.`, and no glues, this
  is how parent-centric currently works);
- Priming starts and complete (so now rootdb contains the answer/glues
  from `ns1` root file);
- Then the query go to ADB to resolve `ns1.`.

Resolution of `ns1.` fails since it doesn't exists from the rootdb
anymore. This is a configuration issue (the resolver behavior is correct
and expected) whch is now fixed.
2026-06-24 21:56:16 +02:00
Michal Nowak
c20bab513b new: ci: Add Alpine Linux 3.24
Merge branch 'mnowak/alpine-3.24' into 'main'

See merge request isc-projects/bind9!12229
2026-06-24 17:45:14 +02:00
Michal Nowak
62670aa1b7 Fix a false positive compiler warning/error on Alpine 3.24
On Alpine Linux 3.24, GCC 15 with fortify-headers produces a compiler
warning when building bin/nsupdate/nsupdate.c:

    In function 'fgets',
        inlined from 'get_next_command' at ../bin/nsupdate/nsupdate.c:2414:13:
    /usr/include/fortify/stdio.h:48:16: error: 'cmdlinebuf' may be used uninitialized [-Werror=maybe-uninitialized]
       48 |         return __orig_fgets(__s, __n, __f);
          |                ^~~~~~~~~~~~~~~~~~~~~~~~~~~
    /usr/include/fortify/stdio.h:42:1: note: in a call to '*fgets' declared with attribute 'access (read_write, 1, 2)' here
       42 | _FORTIFY_FN(fgets) char *fgets(char * _FORTIFY_POS0 __s, int __n, FILE *__f)
          | ^~~~~~~~~~~
    ../bin/nsupdate/nsupdate.c:2405:14: note: 'cmdlinebuf' declared here
     2405 |         char cmdlinebuf[MAXCMD];
          |              ^~~~~~~~~~

This is a false positive, because fgets() only writes into the buffer;
the fortify-headers wrapper annotates the buffer argument with
'access (read_write, ...)', which makes GCC treat passing an
uninitialized buffer as a read of uninitialized memory.

Initialize the 'cmdlinebuf' buffer anyway to avoid the build error.

Assisted-by: Claude:claude-fable-5
2026-06-24 17:44:42 +02:00
Michal Nowak
774a9661fc Add Alpine Linux 3.24 2026-06-24 17:44:42 +02:00
Michal Nowak
28cddaaba6 fix: test: Retry pipequeries on a transient EADDRINUSE in the pipelined test
On FreeBSD, the TCP connect() call can transiently fail with
EADDRINUSE under parallel CI load.  The netmgr already retries such
connects (see #3451), but it retries on the same socket, which is
already bound to the same ephemeral source port, so when the
four-tuple is genuinely busy (e.g. in TIME_WAIT) every retry fails
the same way.  pipequeries then exits with "request event result:
address in use", leaving raw.1 empty and failing the first check.

All eight requests share a single TCP dispatch, so the failed connect
means no query ever reached ns4 and its cache is still cold.  It is
therefore safe to run pipequeries again: a fresh process binds a new
ephemeral port, and the out-of-order check keeps its meaning.  Retry
for up to ten attempts, but only on this specific transient error.

Assisted-by: Claude Code:claude-fable-5

Merge branch 'mnowak/pipelined-retry-transient-eaddrinuse' into 'main'

See merge request isc-projects/bind9!12228
2026-06-24 17:16:14 +02:00
Michal Nowak
b9cf877277 Retry pipequeries on a transient EADDRINUSE in the pipelined test
On FreeBSD, the TCP connect() call can transiently fail with
EADDRINUSE under parallel CI load.  The netmgr already retries such
connects (see #3451), but it retries on the same socket, which is
already bound to the same ephemeral source port, so when the
four-tuple is genuinely busy (e.g. in TIME_WAIT) every retry fails
the same way.  pipequeries then exits with "request event result:
address in use", leaving raw.1 empty and failing the first check.

All eight requests share a single TCP dispatch, so the failed connect
means no query ever reached ns4 and its cache is still cold.  It is
therefore safe to run pipequeries again: a fresh process binds a new
ephemeral port, and the out-of-order check keeps its meaning.  Retry
for up to ten attempts, but only on this specific transient error.

Assisted-by: Claude:claude-fable-5
Assisted-by: Claude:claude-opus-4-8
2026-06-24 17:15:42 +02:00
Michal Nowak
74a3c561aa new: dev: Print OS platform in "named -V"
The "running on" line emitted by `named -V` (as well as the startup
log and `rndc status`, which share the same source) now appends the
PRETTY_NAME value from /etc/os-release in parentheses after the uname
output, e.g.:

    running on Linux x86_64 6.19.14-... (Fedora Linux 42 (Workstation Edition))

This helps disambiguate environments where the kernel string is not a
reliable indicator of the userspace, such as RHEL clones and
containers whose kernel does not match the host OS.

When /etc/os-release is absent, /usr/lib/os-release is tried as a
fallback per the systemd os-release(5) specification. When neither is
available or no PRETTY_NAME is found, the output is unchanged.

Assisted-by: Claude:claude-opus-4-7

Closes #5334

Merge branch '5334-add-os-platform-to-named-V' into 'main'

See merge request isc-projects/bind9!12055
2026-06-24 17:06:30 +02:00
Michal Nowak
b5ca9d3372 Print OS platform in "named -V"
The "running on" line emitted by `named -V` (as well as the startup
log and `rndc status`, which share the same source) now appends the
PRETTY_NAME value from /etc/os-release in parentheses after the uname
output, e.g.:

    running on Linux x86_64 6.19.14-... (Fedora Linux 42 (Workstation Edition))

This helps disambiguate environments where the kernel string is not a
reliable indicator of the userspace, such as RHEL clones and
containers whose kernel does not match the host OS.

When /etc/os-release is absent, /usr/lib/os-release is tried as a
fallback per the systemd os-release(5) specification. When neither is
available or no PRETTY_NAME is found, the output is unchanged.

Assisted-by: Claude:claude-opus-4-7
2026-06-24 17:05:35 +02:00
Ondřej Surý
ff3721d501 new: test: Add extra expired RRSIGs test to dnssec_py
Related #5760

Merge branch 'nicki/pytest-add-extra-expired-rrsigs-test' into 'main'

See merge request isc-projects/bind9!11808
2026-06-24 16:32:15 +02:00
Nicki Křížek
fe2fea73a4 Add extra expired RRSIGs test to dnssec_py
The test verifies that a validating resolver enforces the
max-validations-per-fetch limit when encountering a record with multiple
expired RRSIGs followed by a valid one. One of the records is signed
three times: twice with expired timestamps (to produce two expired
RRSIGs for a.rrsigs-extra-expired/A) and once with valid timestamps,
after which the expired RRSIGs are injected back into the signed zone
file. max-validations-per-fetch is set to 2 via the template variable so
that the third (valid) RRSIG is never reached, causing SERVFAIL.

Assisted-by: Claude:claude-opus-4-8
2026-06-24 15:09:38 +02:00