Add records that will be at end of each compressed bitmap less 1
of the NSEC3 record. Zone verification should still work.
(cherry picked from commit e9a58de251)
Nsupdate does not distinguish between a non-existing RDATA field
and an empty RDATA field when determining which action is desired
when the RDATA field is empty. This only affects a few data types,
like APL, which allow an empty RDATA field. Document a workaround
of using the '\# 0' form for entering these specific records. e.g.
# delete the APL RRset
update delete IN APL
# delete the APL record with a zero length rdata
update delete IN APL \# 0
(cherry picked from commit f45762a5be)
Add missing `|| ret=1` to six dig and nsupdate invocations in
tests.sh so that command failures are properly caught instead
of silently ignored.
(cherry picked from commit 9ba03a1848)
The system test was also subject to the same off by one bug that also
existed in the code. That is: if the inception time of the signature
is exactly equal to the inactive time of the key, we still have to
expect the signature.
(cherry picked from commit d9b6036e0f)
This specific test case triggered a bug where the SKR included bundles
with unsigned DNSKEY RRsets (signatures where omitted because the
inception time was equal to the inactive time of the key).
(cherry picked from commit 784a441e2d)
If the inception time of the signature is exactly equal to the
inactive time of the key, still include the signature. Otherwise there
may be corner cases where signatures are omitted erroneously.
(cherry picked from commit bc6dad585d)
Replace the hand-rolled threaded socket server with the standard
AsyncDnsServer framework used by other ans.py servers in the test suite.
The DNS wire-format message builders (IXFR diff, AXFR, SOA, SERVFAIL)
are retained unchanged since they produce carefully crafted messages
needed to trigger the IXFR->AXFR race condition. The server
infrastructure is replaced:
- Manual TCP/UDP socket management and threading replaced by
AsyncDnsServer, which handles both protocols, pidfile lifecycle,
and signal handling.
- Query parsing replaced by the framework's dns.message-based parser;
query dispatch moved into IxfrRaceHandler.get_responses().
- The axfr_done_event threading.Event replaced by a boolean instance
variable on IxfrRaceHandler, safe within the single asyncio event
loop.
- For IXFR over TCP, the handler yields two BytesResponseSend actions
(msg1 then msg2) so the framework sends both with TCP length prefixes,
preserving the race-triggering sequence.
- For IXFR over UDP, the TC flag is set on the response to force TCP
retry.
- Unused encode_name_compressed() and parse_dns_query() removed.
Also fix a timing issue that might result in the initial transfer not
being done by the time the test is executed -- since ns11 is started
after ns6. Ensure the initial transfer has happened before running the
ixfr_race test.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
(cherry picked from commit 187e571f4d)
The test initiates a zone transfer with IXFR, which produces
a big amount of differences and then generates an error. The
secondary should be able to gracefully shutdown the ongoing
IXFR transfer and retry with AXFR without race conditions
between them.
This test checks for an issue (GL#5767) but since a race
condition is usually time-sensitive it might require several
attempts before it reproduces the issue.
(cherry picked from commit 5c248e7d1a)
Test that a secondary receiving an IXFR transitioning a zone from
unsigned to NSEC-signed returns the correct covering NSEC record
for empty non-terminal names.
Add isctest.query.wait_for_serial() shared helper for waiting until
a server has a specific SOA serial.
(cherry picked from commit 8a4990d6ff)
Add test cases where dnssec-signzone and dnssec-verify use the
zone file's basename as the origin when '-o' is omitted.
(cherry picked from commit 1251ae896c)
In dnssec-signzone and dnssec-verify, if the zone origin is not
specified using the `-o` parameter, the default behavior is to try
to use the zone's file name as the origin. So, for example,
`dnssec-signzone -S example.com` or 'dnssec-verify example.com'
will work, so long as the file name matches the zone name.
This now also works if the zone is in a different directory.
For example, `dnssec-signzone -S zones/example.com` or
'dnssec-verify zones/example.com' will set the origin value
to `example.com`.
(cherry picked from commit b8cb65db93)
The prescan and main update loops in DNS UPDATE processing both used the
same counter to index the maxbytype[] quota array. The prescan loop
always incremented the counter, but the main loop had 14 continue paths
that skipped the increment. This allowed an authenticated DDNS client to
craft an UPDATE message with padding records (e.g. CNAME+A pairs that
trigger CNAME-conflict skips) to shift the counter and read wrong quota
entries, bypassing per-type record limits entirely.
Fix by incrementing the counter unconditionally at the start of each
iteration in the main loop.
(cherry picked from commit bac40394d5)
The "nsec3-delegation" test was added in a release branch, before commit
e40db975d9 introduced the current system
test naming convention. Rename the test to comply with that convention.
(cherry picked from commit 48bf3d3e65)
Race rndc reconfig (toggling between allow-update and update-policy)
against a stream of DNS UPDATEs for 5 seconds and verify that named
does not crash.
Before the fix, the race between send_update() and update_action()
reading the SSU table independently could trigger an assertion
failure (INSIST) when the zone's update policy changed between the
two reads.
(cherry picked from commit c503b6eee8)
If a zone is in named.conf, not originally added by rndc addzone,
rndc modzone for that zone succeeds once, but subsequent modzone
attempts fail. This is because do_modzone removes the zone config
from global or view options, but it would fail due to 'not found'
once the config is removed.
The fix is to ensure re-adding the updated zone config to the
global or view options. This also works as a more complete fix
for the issue 85453d3 atempted to solve, ensuring rndc showzone
shows the latest config: it now works for multple attemps of
modzone, and with named that is not built with LMDB.
The change in this commit relies on UNCONST in a few places.
That's not clean, but 'add/mod/delzone' generally seems to
need it (for example, delete_zoneconf uses it to modify the list
of zones). In that sense, this change follows the convention
(for a longer term, there may have to be a better API so that we
can modify config obtions that were once parsed).
This reverts commit 85453d393d.
This commit doesn't seem to be a complete solution of what
it appears to fix: showzone succeeds and shows the modified
config after first modzone, but subsequent attempts of modzone
fail (though not because of the commit being reverted), let
alone showing the correct new config.
Revering the change for now, and will provide a more comprehensive
fix in the next commit.
If named is built without LMDB and has a zone in named.conf,
then rndc modzone for that zone triggers an assertion failure
unless there's already an NZF file. This is because load_nzf
doesn't create 'nzf_config' when NZF is missing, while a valid
nzf_config is assumed in do_modzone when it tries to add the
modified zone config to add_parser.
The crash is fixed by skipping the call to cfg_parser_mapadd when
nzf_config is NULL. Skipping it should be okay since the config stored
in add_parser would be needed only for subsequently deleting a zone by
rndc delzone when the zone was originally added by rndc addzone, but
in this case the zone was not 'added'. Checking if nzf_config is NULL
before using it also seems to be consistent with other parts of the
implementation.
dns_view_flushnode() was called in the delete_expired() async
callback, which runs after the query that detected the NTA expiry.
This created a race: the query would proceed with stale cached data
from the NTA period before the flush had a chance to run, resulting
in transient SERVFAIL with EDE 22 (No Reachable Authority).
Skip dns_view_flushnode() in the older branches as the solutions for
older branches are too complicated and this was not a critical bug.
(cherry picked from commit da8e1c956a)
All system tests previously using a hyphen have been renamed to use
underscore instead. A couple of symlinks were corrected and one path in
`nsec3-answer` adjusted accordingly.
(cherry picked from commit 67aca1f8c6)
Change the convention for system test directory names to always use an
underscore rather than a hyphen. Names using underscore are valid python
package names and can be used with standard `import` facilities in
python, which allows easier code reuse.
The temporary directories for test execution and their convenience
symlinks have been switched to using hyphens rather than underscores to
keep the pytest collection, filtering and .gitignore working as
expected.
(cherry picked from commit 9f4c1d1993)
The keylist_lock rwlock is initialized at startup but never destroyed
on exit, unlike the sibling namelock mutex which is properly cleaned up.
(cherry picked from commit 5dc19a7d92)
'rndc modzone' deletes the old configuration. If we don't store the
new zone config, when we do a 'rndc showzone' it will be a failure.
This is not an issue in the 9.21 version, because of the effective
config behavior.
If we are modifiying the zone, the zone must have been added before.
Don't overwrite this value on modifications.
Also it feels cleaner to pass added=false to configure_zone() in
do_modzone().
(cherry picked from commit 780872e07e)
Some code paths try to lock an already locked view->newzone.lock.
For example, do_modzone() aqcuires the lock and then calls
delete_zoneconf(), that wants to acquire the same lock.
Add a parameter to delete_zoneconf() that informs the function if the
lock has already been acquired.
(cherry picked from commit 71587b0816)
Add test cases for 'rndc showzone' and 'rndc modzone' on a zone
that was configured in named.conf. This should not crash.
(cherry picked from commit 900127c460)
The asynchronous SIG(0) handling improperly used srcaddr, and dstaddr
from the caller's stack and didn't attach to aclenv. This could
possibly lead to ACL bypass as an invalid srcaddr could be matched or
possible assertion failure if the ACL environment would change between
the initial call and the SIG(0) processing due to the server
reconfiguration. This has been fixed.
(cherry picked from commit b4b81deed9)
This adds a system test to verify that asynchronous SIG(0)
validation correctly retains the ACL environment and network
addresses of the caller, preventing unauthorized ACL bypass
when evaluating match-clients and match-destinations.
(cherry picked from commit 613a93478b)
This new test sends two signed TKEY queries, one in delegation
mode and one in an unrecognized mode to check that named
correctly processes them.
Co-authored-by: Nicki Křížek <nicki@isc.org>
(cherry picked from commit ab77b3dffa)
Trigger a memory leak by adding extra RRSIG(NSEC) to a signed zone which
exceeds the resolver's configured max-records-per-type limit.
(cherry picked from commit a338e254be)
When a validating resolver processes a delegation from a DNSSEC-signed
zone which uses too many NSEC3 iterations, it should cease the attempt
to validate due to an NSEC3 iteration limit being exceeded and fall back
to insecure.
(cherry picked from commit 9bc14a89f1)
Enabling ans6 responses and xfr-and-reconfig zone reload sometimes takes
more time on FreeBSD than the default timeout allows; bump it to 30
seconds.
(cherry picked from commit 77a7430a5f)
Some dns message modifications like TSIG happen only after .to_wire() is
called on the message. To ensure there isn't a discrepancy between what
has been logged and what has been sent, log the query after
dns.query.udp() is executed (which calls .to_wire() on the message).
Co-Authored-By: Štěpán Balážik <stepan@isc.org>
(cherry picked from commit a22e03f71b)
A configuration where a key was defined inside a view, then used in a
`primary` statement wasn't covered. This is now fixed.
(cherry picked from commit d8f46b09a7)
Introduce a new system test (nsprocessinglimit) to verify that the
resolver strictly respects outgoing network fetch quotas when presented
with heavily delegated, unresponsive zones.
This test acts as a regression check for the recent Fisher-Yates nameserver
selection refactor. It sets up an authoritative server delegating a zone
to 23 distinct nameservers (all pointing to unresponsive loopback IPs).
Using dnstap, the test forces a resolution failure and verifies that:
1. The resolver successfully traverses the zone delegation path.
2. The resolver caps the outgoing network queries to the delegated
nameservers exactly at the processing limit (20 fetches), ensuring
array boundaries and dynamic fetch quotas are strictly enforced without
crashing or hanging.
(cherry picked from commit 5274e764c4)
More specific modules (like collections.abc) can now be used.
Generated with: ruff check --extend-select UP035 --fix
(cherry picked from commit ced002c4ab)
Add a pylint plugin that enforces:
- There is no bare `import dns` statement.
- All `dns.<module>` used are explicitly imported.
- There are no unused `dns.<module>` imports.
Fix all the imports to conform with this check.
(cherry picked from commit d3186c7038)
In Python 3.10 strings don't support the | operator, so ruff doesn't
attempt to fix these. Quote the entire type specification to avoid the
typing.Optional import.
Alternatives I considered:
- leaving it as is (only use of Optional in the code base)
- using `from future import __annotations__` (replacing one import with
another one)
(cherry picked from commit 1d5924c82f)