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
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
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
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.
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.
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.
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.
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.
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.
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.
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
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.
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
../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);
|
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
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
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.
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
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
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
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.
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
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
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
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
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
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
Collect every unregistered unit test file before exiting instead of
failing on the first one, so a single configure run lists them all.
Assisted-by: Claude:claude-opus-4-8
Merge branch 'mnowak/report-all-unregistered-unit-tests' into 'main'
See merge request isc-projects/bind9!12220
Collect every unregistered unit test file before exiting instead of
failing on the first one, so a single configure run lists them all.
Assisted-by: Claude:claude-opus-4-8
``named`` could hand a new query an idle forwarder/upstream TCP or TLS
connection that the peer had already closed, causing the query to fail
(and CLOSE-WAIT sockets to pile up). Idle reused connections are now
watched, so a close is noticed and the connection is dropped instead of
reused. A new ``tcp-reuse-timeout`` option controls how long an idle
outgoing connection is kept open for reuse (default 5 seconds).
Closes#6171
Merge branch '6171-tcp-reuse-idle-read' into 'main'
See merge request isc-projects/bind9!12289
The idle timeout that bounds how long a reused outgoing TCP/TLS
connection is held open for reuse was only tunable through the 'named -T
tcpidletimeout' developer hook added earlier on this branch. Make it a
proper configuration option, tcp-reuse-timeout (options block, in units
of 100 milliseconds like the other tcp-*-timeout options), and drop the
-T hook.
A reused TCP/TLS dispatch with no outstanding responses was left in the
reuse pool with no read pending, so a peer closing the idle connection
went unnoticed: the socket lingered in CLOSE-WAIT and the dead dispatch
was later handed to a new query, which failed and the fetch timed out.
Keep a read pending on an idle connected dispatch, bounded by an idle
timeout, so the close is seen promptly and the connection is dropped
from the pool instead of reused.
The idle read may only be (re)armed while the dispatch is still
connected; arming it on a dispatch that is already shutting down
re-reads a dying handle and double-schedules a netmgr job.
On shutdown, close the connection as soon as the dispatch reaches its
terminal state instead of waiting for the last reference to drop, so an
unexpected read (or a peer-side close) cannot leave the socket in
CLOSE-WAIT while a reference still lingers.
With the advent of the new development model involving security-*
branches and autorebasing, the value added by the pre-release testing
mechanism dropped drastically. The only remaining benefit of
pre-release testing is flagging in-progress security fixes targeting
open source branches that conflict with the corresponding bind-9.x-sub
branches. However, such conflicts are a rare occurrence and can be
handled after merging anyway.
Remove the Danger check related to pre-release testing.
Merge branch 'michal/drop-danger-check-related-to-pre-release-testing' into 'main'
See merge request isc-projects/bind9!12313
With the advent of the new development model involving security-*
branches and autorebasing, the value added by the pre-release testing
mechanism dropped drastically. The only remaining benefit of
pre-release testing is flagging in-progress security fixes targeting
open source branches that conflict with the corresponding bind-9.x-sub
branches. However, such conflicts are a rare occurrence and can be
handled after merging anyway.
Remove the Danger check related to pre-release testing.
RPM build jobs work by pushing a commits to main in a repository. Each
repository is identified by the `SERVICE variable and, since race
conditions may happen, the jobs are run serially via GitLab's
resource_group mechanism.
Merge branch 'andoni/use-resource-group-for-rpms-copr-ci-job' into 'main'
See merge request isc-projects/bind9!12295
RPM build jobs push commits to Git repositories. If multiple such jobs
are triggered simultaneously, some of these pushes may fail due to the
same Git branch getting updated by one job while another one attempts to
do the same thing in parallel. Use GitLab's resource group mechanism to
prevent such races: group jobs by the Git repository they push to, which
is indicated by the $SERVICE variable set for each job.