Aydın Mercan [Mon, 2 Feb 2026 09:43:48 +0000 (12:43 +0300)]
chg: dev: initial openssl version splitting
Dealing with OpenSSL has been rapidly turning into an unwieldy situation
as post-3.0 changes turn the library into a different beast.
Start treating pre and post-3.0 versions differently for easier
maintenance.
To help with this Sisyphean task, this MR had to shift things around.
`OPENSSL_NO_DEPRECATED` is now declared in BIND alongside an appropriate
`OPENSSL_API_COMPAT` value. The former value will set to declare either
OpenSSL 1.1.0 or 3.0 as the bare minimum version.
Instead of splitting `md.c` and `hmac.c` into separate version-specific
files, they now live inside `crypto/ossl1_1.c` and `crypto/ossl3.c`.
This way, these functions will be able to utilize the same static
`OSSL_PARAM` tables, removing redundant reconstruction for HMAC.
For pre-3.0, `isc_hmac` has been reverted back to using the `HMAC_`
interface. Using `EVP_MD_CTX`-based functions for HMAC will end up
libcrypto calling the same `HMAC_` functions in the end, giving no
advantage while confusingly using the digest functions.
A new API, `isc_ossl_wrap` has been added. This family of functions
aim to provide a common interface for libcrypto version specific code
while not abstracting away OpenSSL's structures such as `EVP_PKEY`.
Currently the main user of this API is the `dst` family of functions
where some ECDSA and RSA opeations need to use the new `OSSL_PARAM`
functionality by requirement or to avoid speed penalties.
Furthermore OpenSSL based logging has been moved from `isc_tls` to
`isc_ossl_wrap` as its a more appropriate place for such functionality.
Merge branch 'aydin/openssl-version-split' into 'main'
Aydın Mercan [Mon, 1 Dec 2025 14:07:54 +0000 (17:07 +0300)]
remove libcrypto version specific code in opensslecdsa_link
Using `EVP_SIGNATURE` explicit algoritms for signatures have been added
in OpenSSL 3.4 and so is skipped for the initial OpenSSL version
specific code splitting.
Aydın Mercan [Mon, 1 Dec 2025 13:23:37 +0000 (16:23 +0300)]
remove libcrypto version specific code in opensslrsa_link
Using `EVP_SIGNATURE` explicit algoritms for signatures have been added
in OpenSSL 3.4 and so is skipped for the initial OpenSSL version
specific code splitting.
Aydın Mercan [Mon, 1 Dec 2025 10:49:46 +0000 (13:49 +0300)]
move openssl error reporting to isc/ossl_wrap
While being the best place at the time, the tlserr2result doesn't belong
inside TLS code since it is generic to OpenSSL and mostly used in the
dst interface. The newly created ossl_wrap interface is the idea place
for flushing the OpenSSL thread error queue.
Aydın Mercan [Wed, 17 Sep 2025 12:52:35 +0000 (14:52 +0200)]
Separate isc_hmac between pre and post OpenSSL 3.0
Instead of the `EVP_MD_CTX` based functions, use either the new
`EVP_MAC` or the old `HMAC_CTX` based functions.
`EVP_MAC` is the recommended way using using MAC functions in post-3.0
while `HMAC_CTX` is used internally by `EVP_MD_CTX`, making the latter
redundant.
Aydın Mercan [Tue, 16 Sep 2025 13:11:37 +0000 (15:11 +0200)]
switch isc_md_type_t to a proper enum
Get rid of the OpenSSL-isms that plague the codebase where the hash type
is `EVP_MD *`
By using a proper enum, alongside the cleanup, we also get the ability
to use constants for known hash sizes instead of having a function call
every time.
`EVP_MD_CTX_get0_md` has been removed instead of being adapted since it
wasn't used anymore.
Ondřej Surý [Thu, 29 Jan 2026 03:29:45 +0000 (04:29 +0100)]
chg: usr: Enable minimal ANY answers by default
ANY queries are widely abused by attackers doing reflection attacks as
they return the largest answers. Enable minimal ANY answers by default
to reduce the attack surface of the DNS servers.
Closes #5723
Merge branch '5723-change-minimal_any-default-to-yes' into 'main'
Ondřej Surý [Wed, 28 Jan 2026 14:04:58 +0000 (15:04 +0100)]
Enable minimal ANY answers by default
ANY queries are widely abused by attackers doing reflection attacks as
they return the largest answers. Enable minimal ANY answers by default
to reduce the attack surface of the DNS servers.
Mark Andrews [Wed, 28 Jan 2026 10:23:48 +0000 (21:23 +1100)]
fix: test: ISC_RUN_TEST_IMPL should use a static declaration
These functions don't need to be called from multiple places and
by making them static we will detect when they are not added to the
list functions to be tested.
Closes #5715
Merge branch '5715-isc_run_test_impl-should-use-a-static-declaration' into 'main'
Mark Andrews [Fri, 23 Jan 2026 04:57:42 +0000 (15:57 +1100)]
ISC_RUN_TEST_IMPL should use a static declaration
These functions don't need to be called from multiple places and
by making them static we will detect when they are not added to the
list functions to be tested.
Mark Andrews [Tue, 27 Jan 2026 20:22:59 +0000 (07:22 +1100)]
chg: dev: Use enum rather than numbers for isc_base64_tobuffer and isc_hex_tobuffer
Use isc_one_or_more and isc_zero_or_more rather than (-2) and
(-1) when calling isc_base64_tobuffer. Similarly for
isc_hex_tobuffer. This should help reduce the probability
that the wrong number is used and it makes the intent clearer.
Closes #5713
Merge branch '5713-use-macros-with-isc_base64_tobuffer-and-isc_hex_tobuffer' into 'main'
Mark Andrews [Fri, 23 Jan 2026 03:53:18 +0000 (14:53 +1100)]
Add enum for use with isc_base64_tobuffer and isc_hex_tobuffer
This adds the following enum isc_one_or_more and isc_zero_or_more
which specify if one or more or zeror or more bytes are required
when reading the unbounded base64 / hex encoded data.
Arаm Sаrgsyаn [Tue, 27 Jan 2026 11:32:07 +0000 (11:32 +0000)]
fix: usr: Fix a possible issue with reponse policy zones and catalog zones
If a response policy zone (RPZ) or a catalog zone contained an
`$INCLUDE` directive, then manually reloading that zone could
fail to process the changes in the response policy or in the
catalog, respectively. This has been fixed.
Closes #5714
Merge branch '5714-zone_loaddone-rpz-and-catz-bugfix' into 'main'
Aram Sargsyan [Mon, 26 Jan 2026 15:34:00 +0000 (15:34 +0000)]
Fix a bug in zone_loaddone()
The zone_loaddone() function disables database notifications for
a catalog zones and response policy zones (RPZ) when loading had
failed. Howerer, the 'result != ISC_R_SUCCESS' check is insufficient,
because the DNS_R_SEENINCLUDE result also indicates success.
Nicki Křížek [Tue, 27 Jan 2026 10:46:55 +0000 (11:46 +0100)]
fix: test: Resolve the system_test_dir in pytest
If the system_test_dir contains a symlink, then it might cause issues
further down when using relative_to(), unless it is resolved first. This
has been observed on FreeBSD13 in CI where /home is a symlink to
/usr/home.
Merge branch 'nicki/pytest-freebsd13-artifacts-path' into 'main'
Nicki Křížek [Mon, 26 Jan 2026 17:37:00 +0000 (18:37 +0100)]
Resolve the system_test_dir in pytest
If the system_test_dir contains a symlink, then it might cause issues
further down when using relative_to(), unless it is resolved first. This
has been observed on FreeBSD13 in CI where /home is a symlink to
/usr/home.
Nicki Křížek [Mon, 26 Jan 2026 12:10:25 +0000 (13:10 +0100)]
fix: test: Fix a race condition in dnssec test
When dumpdb command is executed, it might take a while until the file is
written. Rather than checking the file once, use the WatchLog mechanism
to allow the desired line to appear before a timeout happens.
This affected test_validation_recovery and test_cache tests which have
been intermittently failing on EL8 in our CI.
Merge branch 'nicki/fix-dnssec-test-dumpdb-race' into 'main'
Nicki Křížek [Mon, 26 Jan 2026 09:45:34 +0000 (10:45 +0100)]
Fix a race condition in dnssec test
When dumpdb command is executed, it might take a while until the file is
written. Rather than checking the file once, use the WatchLog mechanism
to allow the desired line to appear before a timeout happens.
This affected test_validation_recovery and test_cache tests which have
been intermittently failing on EL8 in our CI.
Štěpán Balážik [Thu, 25 Dec 2025 15:58:35 +0000 (16:58 +0100)]
Store the most specific matched domain in DomainHandler
Store the most specific matching domain in DomainHandler and
expose it through the `matched_domain` property for subclasses
to use in their implementations of `get_responses`.
Mark Andrews [Fri, 23 Jan 2026 14:24:04 +0000 (01:24 +1100)]
fix: usr: DSYNC record incorrectly used two octets for the Scheme Field
When creating the `DSYNC` record from a structure, `uint16_tobuffer` was used instead of `uint8_tobuffer` when adding the scheme, causing a `DSYNC` record that was one octet too long. This has been fixed.
Closes #5711
Merge branch '5711-dsync_fromstruct-produces-an-invalid-record' into 'main'
Mark Andrews [Fri, 23 Jan 2026 02:32:41 +0000 (13:32 +1100)]
dsync_from struct produced an invalid record
uint16_tobuffer was used instead of uint8_tobuffer when adding the
scheme to the buffer. This produced a record that was one octet
too long. This has been fixed.
Matthijs Mekking [Fri, 23 Jan 2026 12:46:51 +0000 (12:46 +0000)]
chg: usr: Lowercase the NSEC next owner name when signing
When building the NSEC rdata, lowercase the next owner name before
storing it in the Next Domain Name Field.
Note that this is not required according to RFC 6840, but since there
is inconsistency in the documents over time, having uppercase next
owner names in the NSEC records may cause validation failures if
validators are not following RFC 6840.
Closes #5702
Merge branch '5702-lowercase-nsec-next-owner-name' into 'main'
When building the NSEC rdata, lower case the next owner name before
storing it in the Next Domain Name Field.
Note that this is not required according to RFC 6840, Section 5.1:
When canonicalizing DNS names (for both ordering and signing), DNS
names in the RDATA section of NSEC resource records are not converted
to lowercase. DNS names in the RDATA section of RRSIG resource
records are converted to lowercase.
The guidance in the above paragraph differs from what has been
published before but is consistent with current common practice.
Item 3 of Section 6.2 of [RFC4034] says that names in both of these
RR types should be converted to lowercase. The earlier [RFC3755]
says that they should not.
Since there is inconsistency in the documents over time, having
uppercase next owner names in the NSEC records may cause validation
failures if validators are not implementing RFC 6840.
Also, RFC 4034 section 6.2 is not about how NSEC record content is
created, but how RRset content is normalized in order to produce and
validate RRSIG records for a given RRset. Since the next owner name
of the NSEC record is about ordening, and the canonical DNS name order
requires that uppercase US-ASCII letters must be treated as if they
were lowercase US-ASCII letters, case is not meaningful for NSEC
next owner names, as it cannot be compressed on the wire, so we may
lowercase the next owner name in the NSEC rdata before signing, being
more kind to validators.
Andoni Duarte [Fri, 23 Jan 2026 11:33:53 +0000 (11:33 +0000)]
chg: ci: Use a small always-on runner for lightweight CI jobs
Some CI jobs spend more time pulling the docker image and setting up their environment than running the script. This MR adds a tag `smalljob` to jobs considered lightweight in order to run them on a dedicated small VM.
Merge branch 'andoni/try-small-vm-for-lightweight-ci-jobs' into 'main'
Move CI stage "other-checks" right after "quick-checks"
Move CI stage "other-checks" right after "quick-checks" and get the jobs
in it as close to each other as possible in .gitlab-ci.yml.
Since no job is allowed to depend (via "needs") on any job that is
assigned to a stage later than its own, move the "tsan:stress" and
"gcov" jobs to the "system" stage.
Rename the "postcheck" stage to "other-checks" in CI
Rename the "postcheck" CI stage to the more generic "other-checks".
Slower jobs that still run in autoscaled runners belong here, as opposed
to the lightweight ones in "quick-checks".
Rename the "precheck" stage in CI to "quick-checks"
Most jobs in the "precheck" stage spend more time setting up their
environment than running the script (seconds), this allows us to add a
small always on dedicated runner instead of the autoscaled ones.
Hence, the stage is renamed to "quick-checks", and a tag "smalljob" is
added to the anchor so that these jobs are picked by the dedicated
runner.
Andoni Duarte [Thu, 22 Jan 2026 18:40:33 +0000 (18:40 +0000)]
fix: ci: Read the Docs picking old version when stable tag is updated
Read the Docs fails to pick the latest version when updating the `stable` tag, i.e. a build is triggered but it takes the previous version of it. This is a known bug in RtD: https://github.com/readthedocs/readthedocs.org/issues/10838.
The only approach that seems to solve this on our end, is to wait some time and trigger the build again so that it picks the latest version of the tag.
Merge branch 'andoni/fix-rtd-picking-old-version-when-stable-branch-update' into 'main'
Read the Docs fails to pick the latest version of the stable tag when
updated, i.e. a build is triggered but it takes the previous version.
This commit triggers a second build after 5 minutes to ensure that the
correct tag version is used for the documentation.
This is a known bug in RtD:
https://github.com/readthedocs/readthedocs.org/issues/10838.
Colin Vidal [Mon, 19 Jan 2026 14:52:30 +0000 (15:52 +0100)]
resolver: add comment when recursing
When a fetch result gets a delegation, `rctx_referral()` sets the
`rctx->get_nameserver = true`, which tells the resolver to retry another
server, not because of an error with the current server, but simply to
follow the delegation.
Update the comment of `rctx_nextserver()` which is quite confusing here
(as it's not immediately obvious from the code how we recurse when
getting a delegation back from a query).
Also add a log line, which helps figuring out this is happening.
Colin Vidal [Mon, 19 Jan 2026 12:46:03 +0000 (13:46 +0100)]
fix resolver query response doc
In case on positive response, the `rctx_authority_positive()` function
is called to scan the AUTHORITY section to find NS servers and related
RR (glues) to be cached.
The doc says the function was called `rctx_authority_scan()`, but it is
called `rctx_authority_positive()`.
Nicki Křížek [Wed, 21 Jan 2026 15:11:25 +0000 (16:11 +0100)]
chg: pkg: Update requirements for system test suite
Python 3.10 or newer is now required for running the system test suite. The required python packages and their version requirements are now tracked in `bin/tests/system/requirements.txt`.
Support for pytest 9.0.0 has been added its minimum supported version has been raised to 7.0.0. The minimum supported dnspython version has been raised to 2.3.0.
Nicki Křížek [Tue, 30 Dec 2025 12:36:41 +0000 (13:36 +0100)]
Prefer Python 3.12 if available
This ensures that python3.12 is used testing on older distributions
like EL8 and EL9, where the platform default python3 is older.
python3.11 was explicitly added due to FreeBSD, which doesn't have that
binary symlinked to any other name (like python3). Previously, it worked
only incidentally - when python3 was listed first, it triggered special
meson code for python detection, which is no longer the case when
python3.12 is listed first.
Nicki Křížek [Tue, 30 Dec 2025 12:45:50 +0000 (13:45 +0100)]
Bump the minimum required python version to 3.10
Drop support of EoL python versions for running system tests. The
maintenance cost of supporting end of life ecosystem, especially Python
3.6 on EL8 and the related outdated packages (pytest, dnspython, ...),
has become unreasonable.
Nicki Křížek [Tue, 16 Dec 2025 17:27:20 +0000 (18:27 +0100)]
Add requirements.txt for system tests
This file lists the required Python packages and versions for running
system tests. The easiest way to obtain them is:
pip install -r requirements.txt
The minimum dnspython version is 2.7.0 because it supports TSIG parsing
without validation (for tsig/tests_tsig_hypothesis.py) and wire() (for
names/tests_names.py).
The minimum pytest version was bumped to 7.0.0 because it supports the
collection hook API required by pytest 9.
The minimum hypothesis version was set to 4.41.2 as prior versions might
have issues on FIPS systems.
Arаm Sаrgsyаn [Wed, 21 Jan 2026 10:47:31 +0000 (10:47 +0000)]
fix: dev: Fix a bug in qpzone.c:first_existing_header_indirect()
There is a bug in qpzone.c:first_existing_header_indirect() where
it does not advance the pointer in the FOREACH type loop.
Remove the static function altogether, as it was used only once and
had some other problems too, and use simpler custom code instead in
the place where it was used.
Closes #5691
Merge branch '5691-qpzone.c-first_existing_header_indirect-fix' into 'main'
Aram Sargsyan [Tue, 20 Jan 2026 16:20:35 +0000 (16:20 +0000)]
Add a new dbversion unit test
Test that closing a writer with a rollback, then opening another
writer and adding a rdataset (while still holding the node reference)
works correctly.
This test checks that the bugfix in the previous commit is correct.
Aram Sargsyan [Fri, 16 Jan 2026 14:07:39 +0000 (14:07 +0000)]
Remove qpzone.c:first_existing_header_indirect() which had bugs
The first_existing_header_indirect() static function is used only
in one place and it has bugs:
1. It doesn't advance the pointer and can cause an infinite loop
if it doesn't break out from the loop on the first iteration.
2. It doesn't check if the header EXISTS, though its name indicates
that it should.
3. Even if the infinite loop bug is fixed, it would eventually
return the last checked header's pointer even if all the
candidates do not match the criteria of the selection.
Instead of fixing it, remove the function and use simpler code in
the place where it was being called.