Commit graph

13216 commits

Author SHA1 Message Date
Nicki Křížek
495be0bb9e Disable statschannel RTT tests on FreeBSD
These tests rely on somewhat precise timing, as they test that answers
arrive in a particular latency bucket within the statschannel stats.
These tests are affected by various timing and network issues on our
FreeBSD CI runners and the results are very unstable. Skip these on
FreeBSD entirely.
2026-03-10 15:36:10 +01:00
Michal Nowak
77a7430a5f
Bump xfer timeout to 30 seconds
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.
2026-03-10 12:39:14 +01:00
Nicki Křížek
a22e03f71b Log dnspython queries after .to_wire() is called
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>
2026-03-09 09:54:12 +01:00
Ondřej Surý
c1ba80169c
Introduce max-delegation-servers configuration option
Make the maximum number of processed delegation nameservers configurable
via the new 'max-delegation-servers' option (default: 13), replacing the
hardcoded NS_PROCESSING_LIMIT (20).

The default is reduced to 13 to precisely match the maximum number of
root servers that can fit into a classic 512-byte UDP payload.  This
provides a natural, historically sound cap that mitigates resource
exhaustion and amplification attacks from artificially inflated or
misconfigured delegations.

The configuration option is strictly bounded between 1 and 100 to ensure
resolver stability.
2026-03-04 16:13:49 +01:00
Michal Nowak
239464f276
Use clang-format-22 to update formatting 2026-03-04 10:56:41 +01:00
Colin Vidal
d8f46b09a7 add checkconf test with key defined inside a view
A configuration where a key was defined inside a view, then used in a
`primary` statement wasn't covered. This is now fixed.
2026-02-28 17:11:02 -08:00
Aram Sargsyan
165a776137 Add RTT statistics tests both for XML and JSON outputs
Add a resolver instance "ns4" in the statschannel test and a "ans5"
instance which adds latency to the queries delegeated to it from the
resolver.

Make queries which add latency, and compare the expected values to
the values received from the statistics channel.
2026-02-26 14:00:10 +00:00
Aram Sargsyan
0affd0dbcb Show the incoming/outgoing queries' RTT statistics in stats channel
Expose the new isc_histo_t-based RTT statistics in the statistics
channel for the XML and JSON versions.
2026-02-26 14:00:10 +00:00
Aram Sargsyan
e41fbea843 Replace the outgoing queries RTT histogram code with isc_histomulti
The granularity of the simple histogram with fixed number of ranges
sometimes isn't good enough. As there's a need to implement a new
histogram statistics for the incoming query times (RTT), it was decided
to also update the existing RTT statistics of the outgoing queries
so that they look similar and use common code.

Remove the old histogram code from the resolver and from the statistics
channel. Reimplement the outgoing queries RTT histogram using the
isc_histomulti module, and prepare the necessary base for implementing
the incoming queries RTT histogram. The statistics channel will be
updated to expose the new histograms in an upcoming commit.
2026-02-26 14:00:10 +00:00
Colin Vidal
5274e764c4
Add test coverage for nameserver processing limits
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.
2026-02-26 06:57:54 +01:00
Colin Vidal
c67b52684f system test covering NS randomization
Add randomizens system test which ensures that NS are randomly selected.
The test relies of the fact that `getaddresses_allowed()` logic won't
allow to query more than 3 NS at the top-level. The `example.` zone has
4 NS and the 3 formers are lame. As a result, if the resolved doesn't
randomize the NS selection, it will only quiery the 3 formers, which
won't give an answer, and fails. With randomization enabled, there is a
chance that the resolver queries the fourth NS, and gets the result.
2026-02-25 09:31:14 +01:00
Ondřej Surý
a82773ea89 Add system tests that imports invalid SKR file
Try to import invalid SKR file and observe whether the named is still
alive.  This test only triggers under ASAN.
2026-02-24 19:44:57 +01:00
Ondřej Surý
8ab4827a0c Importing invalid SKR file might overflow the stack buffer
If an invalid SKR file is imported, reading the time from the token
buffer might overflow the buffer on the local stack.  This has been
fixed by removing the intermediate buffer and parsing the lexer token
directly.
2026-02-24 19:44:57 +01:00
Ondřej Surý
7b737bc1c4
Add tests for NSEC3 invalid length
Adds a static system test that fails to load an NSEC3 record with an
invalid next part length.  Additionally, introduces a dynamic test using
a crafted authoritative DNS proxy to inject invalid NSEC3 records on the
fly to test runtime behavior.
2026-02-24 14:57:58 +01:00
Mark Andrews
3801d0ebbf
Enforce NSEC3 record consistency
NSEC3 hashes are required to fit within a single DNS label.  Since there
are 5 bits per label byte without pad characters, the maximum hash size
is floor(63*5/8) (39 bytes).

This patch enforces this maximum length for unknown algorithms, while
strictly enforcing the exact expected digest length for known algorithms
like SHA-1.
2026-02-24 14:57:22 +01:00
Ondřej Surý
46f15f4f9d
Add test for mixed unsupported DS records
Add a system test that has one invalid DS record with supported
algorithm and one unsupported DS record.  Both DNSKEY and A queries must
fail with SERVFAIL.
2026-02-23 19:53:48 +01:00
Ondřej Surý
f983a64152
Fail DNSKEY validation when supported but invalid DS is found
A regression was introduced when adding the EDE code for unsupported
DNSKEY and DS algorithms.  When the parent has both supported and
unsupported algorithm in the DS record, the validator would treat the
supported DS algorithm as insecure when validating DNSKEY records
instead of BOGUS.  This has not security impact as the rest of the child
zone correctly ends with BOGUS status, but it is incorrect and thus the
regression has been fixed.
2026-02-23 11:34:43 +01:00
Matthijs Mekking
c32de7df95 Test serve-stale with upstream zones and CNAMEs
Three variants of YWH-PGM40640-56: Stale/Wrong DNS Data Served via
CNAME Flag Leak (DNS_DBFIND_STALEOK persistence) are presented in
GitLab issue #5751. All these variants have been converted to system
tests.

Variant 1 forwards source.stale to another server, that provides a
CNAME record, while the resolver is authoritative for target.stale.
The CNAME points to a non-existing name. A stale CNAME record should
result in a stale NXDOMAIN (instead of SERVFAIL).

Variant 2 forwards both source.stale and target.stale to other servers.
This time the CNAME points to an A RRset. If the source.stale server
is not available (and stale-answer-client-timeout is off), the cached
CNAME should be followed and pick up the fresh RRset (instead of the
stale A RRset).

Variant 3 is similar to variant 2, but this time the CNAME points to
a non-existing name again. After flushing the target, BIND should
return a stale NXDOMAIN (instead of SERVFAIL).
2026-02-23 08:07:12 +01:00
Julia Evans
8972ed9424 Add examples to the dig man page
The goal here is to help new or infrequent users figure out the most
basic ways to use dig.

Notes on the choice of examples:

* I wrote examples that users can copy and paste exactly as is, without
  having to come up with an appropriate IP address or domain name to use.
  The one exception is the `dig -x` example which uses an IP from the
  example range.
* `dig +noall +answer` here is because learning about `+noall +answer`
  was lifechanging for me when I learned about it, I've heard from
  others that they find it helpful too, and it's pretty hard to infer
  from the man page as is that it might be useful
* I thought about adding `+trace` but left it out because 5 examples was
  already starting to feel like a lot.
2026-02-22 11:03:10 -05:00
Štěpán Balážik
ced002c4ab Replace deprecated typing imports
More specific modules (like collections.abc) can now be used.

Generated with: ruff check --extend-select UP035 --fix
2026-02-20 15:17:32 +01:00
Štěpán Balážik
d3186c7038 Clean up imports of dnspython modules
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.
2026-02-20 15:17:32 +01:00
Štěpán Balážik
1d5924c82f Replace Optional["T"] with "T | None"
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)
2026-02-20 15:17:32 +01:00
Štěpán Balážik
fe38515ad0 Replace Optional[T] with T | None
Generated with: ruff check --extend-select UP045 --fix && black .
2026-02-20 15:17:32 +01:00
Štěpán Balážik
cdb7428431 Remove the rest of Union usages by hand
These require some manual changes.
2026-02-20 15:17:32 +01:00
Štěpán Balážik
ce9c9a1a9c Replace Union[S, T] with S | T
Generated with: ruff check --extend-select UP007 --fix && black .
2026-02-20 15:17:32 +01:00
Štěpán Balážik
790745da18 Built-in types are now subscriptable
Generated with: ruff check --extend-select UP006 --fix
2026-02-20 15:17:32 +01:00
Štěpán Balážik
08f5e5ebd1 Remove superfluous 'pylint: disable' directives
Some of these have been fixed already, fix the rest.
2026-02-20 15:17:32 +01:00
Štěpán Balážik
b00f16f026 Remove unused imports
Generated with: ruff check --extend-select F401 --fix
2026-02-20 15:17:32 +01:00
Štěpán Balážik
7178c97e5c Set pytestmark explicitly in rollover* and nsec3* tests
Importing pytestmark confuses static analysis tools as they flag it as
unused.
2026-02-20 15:17:32 +01:00
Štěpán Balážik
ef21b77912 Make default_algorithm accessible through a fixture and method
Importing pytest fixture trips up static analysis tools, so move
default_algorithm to conftest.py and use it instead of os.environ
accesses in various system tests.

For use outside test function, use Algorithm.default().
2026-02-20 15:17:32 +01:00
Štěpán Balážik
2b9c5ccd77 Define __all__ in __init__.py files
Fix ruff's F401 unused-import errors in these files.

Also sort them with: ruff check --extend-select RUF022 --fix.
2026-02-20 15:17:32 +01:00
Štěpán Balážik
ffd5b6ac26 Automatically sort imports in Python code
Generated with: ruff check --extend-select I --fix (with the changes to
pyproject.toml applied).
2026-02-20 15:17:32 +01:00
Štěpán Balážik
57ecaee95d Fix vulture warnings and tweak ignore lists
Run vulture on the whole repository, fix most errors in previously
unchecked code, adjust ignore lists.
2026-02-20 15:17:32 +01:00
Štěpán Balážik
19076c0d4d Fix 'Too many return statements' pylint error
Refactor `Key.match_properties` into multiple functions.
2026-02-20 15:17:32 +01:00
Štěpán Balážik
50ed74197c Fix pylint's 'invalid-name' errors
Where possible comply with the naming rules. Add exceptions for the
function names used in KASP tests.
2026-02-20 15:17:32 +01:00
Štěpán Balážik
c47b076494 Set dist=loadscope for pytest in pytest.ini
Previously there was some handling of old pytest-xdist versions which is
no longer needed.
2026-02-20 15:17:31 +01:00
Štěpán Balážik
a384283497 Fix the rest of 'Formatting a regular string which could be an f-string'
Some fixes have to be done manually.
2026-02-20 15:17:31 +01:00
Štěpán Balážik
df0be6b4bd Fix some 'Formatting a regular string which could be an f-string' errors
Generated with:
ruff check --select UP031,UP032 --fix --unsafe-fixes && black .
2026-02-20 15:17:31 +01:00
Štěpán Balážik
4253d7298c Fix 'Import should be placed at the top of the module'
In preparation for running pylint on more Python code.
2026-02-20 15:17:31 +01:00
Štěpán Balážik
38a47d9f7c Fix 'Using open without explicitly specifying an encoding'
In preparation for running pylint on more code.
2026-02-20 15:17:31 +01:00
Štěpán Balážik
d0079b5722 Use relative imports and __init__.py in the statschannel test
This is in preparation for automatic import sorting.
2026-02-20 15:17:31 +01:00
Štěpán Balážik
4684c9c091 Issue errors on re.compile only when isctest is imported
This is in preparation of running pylint on more parts of the codebase.
2026-02-20 15:17:31 +01:00
Štěpán Balážik
407df9599c Run custom servers as Python modules
Use `python -m` for running the custom servers.

This allows the use of relative imports in the server modules and in
turn linting the modules.
2026-02-20 15:17:31 +01:00
Ondřej Surý
295139f8ca
Rename isc_net_getudpportrange() to isc_net_getportrange()
This better reflects the true nature of the function as we are reading
the ephemeral port range which is not related to UDP at all.
2026-02-20 14:06:23 +01:00
Ondřej Surý
04c81b55d2
Implement IP_LOCAL_PORT_RANGE socket option for Linux
For Linux >= 6.8:

Since 2023, Linux has introduced a change to the IP_LOCAL_PORT_RANGE
socket option that eliminates the need for the random window
shifting (implemented as a fallback in the next commit).

By setting IP_LOCAL_PORT_RANGE option, we tell the kernel to use better
approach to the source port selection.

For Linux << 6.8:

This implement selecting port by random shifting range leveraging the
IP_LOCAL_PORT_RANGE socket option.  The network manager is initialized
with the ephemeral port range (on startup and on reconfig) and then for
every outgoing TCP connection, we define a custom port range (1000
ports) and then randomly shift the custom range within the system range.

This helps the kernel to reduce the search space to the custom window
between <random_offset, random_offset + 1000>.

Reference:
https://blog.cloudflare.com/linux-transport-protocol-port-selection-performance/#kernel
2026-02-20 14:06:23 +01:00
Ondřej Surý
c3ec414d88
Remove return value from isc_net_getudpportrange()
The function was already marked as never failing, always returning
ISC_R_SUCCESS, so there was a lot of dead code around checking whether
the result would be ISC_R_SUCCESS.  This has been cleaned up.
2026-02-20 14:06:23 +01:00
Mark Andrews
f99d7f4217
Check notify with bad notify source address and tsig
named was asserting when the notify source address was not available
and TSIG was being used.  Check this scenario by adding a nameserver
to the zone which is configured to uses a non-existent source address
and a blackholed destination address and a TSIG using a server clause
for that destination address.
2026-02-19 13:44:33 +01:00
Mark Andrews
757e503536 Return FORMERR for ECS family 0
RFC 7871 only defines family 1 (IPv4) and 2 (IPv6). Additionally
it requires FORMERR to be returned for all unknown families.
2026-02-19 13:17:19 +11:00
Mark Andrews
ea32141e48 Use shell function 'check_count' to check counts 2026-02-17 13:17:43 +11:00
Mark Andrews
591096f131 Test forward query/response counts 2026-02-17 13:17:43 +11:00