Commit graph

16415 commits

Author SHA1 Message Date
Ondřej Surý
3a4ad1fd12
Remove dns_rdataslab_merge() and friends
After the split to dns_rdataslab and dns_rdatavec, the
dns_rdataslab_merge() function was unused and it suffered from the same
data race as fixed in the previous commit.  Instead of fixing it, just
remove the function and bunch of other unused functions from the
dns_rdataslab unit.
2026-02-18 14:29:16 +01:00
Mark Andrews
24f85bc3f3 Document UPDATE QUERY and UPDATE RESPONSE 2026-02-17 13:17:43 +11:00
Mark Andrews
38b626d58d Correctly identify forwarded queries with DNSTAP
Queries using forwarders where not being correctly identified
when using dnstap.
2026-02-17 13:17:43 +11:00
Alessio Podda
169cbe8431
Return node pointer in step
Part of an refactor to eliminate intermediate copies in qpzone_find.
2026-02-12 17:36:48 +01:00
Alessio Podda
33dfd3c0ce
Fewer name copies in step
Part of an refactor to eliminate intermediate copies in qpzone_find.
2026-02-12 17:32:34 +01:00
Alessio Podda
d0e04ed0e7
Fewer name copies in previous_closest_nsec
Part of an refactor to eliminate intermediate copies in qpzone_find.
2026-02-12 17:32:30 +01:00
Matthijs Mekking
04f39e92d1 Remove unused dns_view_load() and dns_zt_load()
We always load zones asynchronously.
2026-02-12 13:43:13 +00:00
Colin Vidal
f623ab1fb3 fetch loop detection improvements
The fetch loop detection occured in two places: when
`dns_resolver_createfetch()` is invoked (looking up through the parent
fetches chain and stops the fetch if a parent fetch is the same qname and
qtype) and right after calling `dns_adb_findname()` in the resolver
(stops the fetch if the current fetch is the same name from the ADB
lookup, and ADB lookup needs to fetch it).

Regarding fetch loop detection at the `dns_resulver_createfetch()`
entry, there are case where both qname and qtype are similar but the
zonecut is different. This will then query different name servers and
get different responses. For instance, the following delegation
parent-side (both for `foo.example.` and `dnshost.example.`):

	foo.example.		3600	NS	ns.dnshost.example.
	dnshost.example.	3600	NS	ns.dnshost.example.
	ns.dnshost.example.	3600	A	1.2.3.4

Then the child-side of `dnshost.example.`:

	dnshost.example.	300	NS	ns.dnshost.example.
	ns.dnshost.example.	300	A	1.2.3.4

Then the child-side of `foo.example.`:

	foo.example		3600	NS	ns.dnshost.example.
	a.foo.example		300	A	5.6.7.8

Obviously, there is a misconfiguration between the parent-side and the
child-side of `dnshost.example` (the mismatch of the TTL), but, this
happens...

Because the resolver is currently child-centric, the parent-side
delegation's glue of `dnshost.example.` will be overriden by the
child-side of the delegation. Once both A records will expires, the
resolver will attempt to find out the A RRs but will start from the
`foo.example.` zonecut, as the delegation itself is still valid.

Then the resolver will attempt to resolve `ns.dnshost.example.`, still
using the `foo.example.` zonecut, which will immediately trigger another
attempt to resolve `ns.foo.example.` (because the A RR is expired). This
is, however _not_ a loop, because the second attempt will have
`dnshost.example.` zonecut.  And this changes everything, because the
resolver detects the A name is in-domain, and pass a flag to ADB so
`dns_view_find()` won't use the cache. As a result, the zonecut will be
`.`, and the hints (root servers) will be queried instead.

From that point, they'll return the parent-side delegation, which
includes the glue for `ns.dnshost.example/A`, and the resolution can
continue. Previously, this wouldn't be possible because a loop would be
detected from the second attempt to looking `ns.foo.example/A` and would
result in a SERVFAIL.

Now, the loop detection is relaxed as the loop is detected if the qname,
qtype _and_ zonecut are equals.

This commit also changes the way the loop detection post
`dns_adb_createfind()` works. From the same example above, there would
be two ADB fetches with the same name, but with two different ADB flags
(the first one without DNS_ADB_STARTATZONE, the second one with that
flag). It means that there will be two fetches out of those two ADB
lookups, both legit, and not a loop (i.e. it won't be stuck). To
differenciate between a find which has a pending fetch (which could be
from another find the current find has been attached to), a new find
option `DNS_ADBFIND_STARTEDFETCH` is introduced, which tells that the
current has did started a fetch.

That way, if a find doesn't have `DNS_ADBFIND_STARTEDFETCH` option but
has pending fetches, we know this is a find attached to a similar find
so this is a loop. Otherwise, with `DNS_ADBFIND_STARTEDFETCH`, we know
that even if there is a pending fetch, this is not a loop as the fetch
has just been started
2026-02-11 14:07:19 +01:00
Colin Vidal
e5f963262a extends named -T so ADB settings can be tweaked
ADB entry window and ADB min cache time can be tweaked using `named -T
adbentrywindow=<unsigned int>` and `named -T adbmincache=<unsigned
int>`.

While those values doesn't needs to be exposed to the operator, this can
be needed to be able to system test ADB behaviors without having to wait
as long as those values are by default.
2026-02-11 13:56:03 +01:00
Colin Vidal
e62cafd3c7 rename fetch response db field to cache
As the `dns_fetchresponse_t` `db` field can only be attached to the
resolver cache database, rename it into `cache` to avoid ambiguities.
2026-02-10 08:50:16 +01:00
Evan Hunt
feed0fb43c use a union for resp and qmin data
It's potentially confusing to use "resp_rdataset" for QNAME
minimization, but we can make it a union and have resp.rdataset
and qmin.rdataset using the same memory.

We can save even more space by using the same union to combine
qminname and resp_foundname and access them as qmin.name and
resp.foundname.
2026-02-10 08:50:16 +01:00
Colin Vidal
fd526c0ad0 resolver: remove qminrrset, qminsigrrset from fctx
Two rdataset property `qminrrset` and `qminsigrrset` are removed from
the fetch context. They only are used as temporary storage for the query
result of the qmin query, and are immediately detached from
`resume_qmin` once the query is over.

As an alternative, use `resp_rdataset` and `resp_sigrdataset`
instead; those are not needed for storing the response data until
after qmin_resume() is over.
2026-02-10 08:50:16 +01:00
Colin Vidal
5972ee2cd5 resolver: copy fetch responses and send events in one go
Instead of first copying query response data into each fetch response
and then iterating again to send the response to the caller, perform
both operations in one go.

Also removed some duplicate code.
2026-02-10 08:50:16 +01:00
Colin Vidal
a5b2a8c931 resolver: simplify fetch response handling
There is no longer a need to decide whether a fetch response should be
prepended or appended to the fetch response list. As query response data
is stored directly in the fetch context object, responses containing a
sigrdataset no longer need to be ordered first. Remove the code
implementing this logic.

Additionally, the distinction between `fetchstate_done` and
`fetchstate_sendevents` is no longer needed. New clients
`dns_fetchresponse_t` can be attached any time to the fetch context
until `fctx__done()` is called, since there is no dependency on the
first fetch response in the list. This simplifies the code and reduces
(just a bit) locking usage.
2026-02-10 08:50:16 +01:00
Colin Vidal
b764d43203 resolver: temporarily store query answer in fetch context
Query answers are now stored in dedicated fetch context properties,
instead of using `ISC_LIST_HEAD(fctx->resps)`.

This reduces lock critical section usage in some places, and enables
further simplifications. (In particular, it removes the need for special
logic to prepend a fetch response to the list when it contains a
sigrdataset.)
2026-02-10 08:50:16 +01:00
Colin Vidal
74a74b5f29 resolver: Defer cloning of fetch responses until events are sent
Instead of cloning fetch responses immediately after writing to the
head of the fetch response list, defer cloning until the events are
actually sent.

This removes the need for the `fctx->cloned` state. However, a new
fetch state value, fetchstate_sentevents, is introduced and occurs
after fetchstate_done.  To prevent new fetch responses from being
prepended after the head is written but before cloning occurs,
fetchstate_done is now set at all call sites that previously invoked
`clone_results()`.
2026-02-10 08:50:16 +01:00
Ondřej Surý
53b2bddd65
Fix NULL Pointer Dereference in QP-trie Cache add()
When RRSIG(rdtype) was independently cached before the RDATA for the
rdtype itself, named would crash on the subsequent query for the RDATA
itself.  This has been fixed.

ISC would like to thank Vitaly Simonovich for bringing this
vulnerability to our attention.
2026-02-07 11:50:14 +01:00
Ondřej Surý
3ad87f1ad6 Release gnamebuf also on the error path
In dst_gssapi_acceptctx(), the gnamebuf could leak a little bit of
memory if dns_name_fromtext() would theoretically fail.  This would
require a Kerberos principal with invalid DNS name.
2026-02-06 18:33:44 +01:00
Matthijs Mekking
a5f934b7a1 Minor logging improvements for key lifetime 2026-02-06 15:06:47 +00:00
Mark Andrews
479c737517
Record query time for all dnstap responses
The description in the protobuf specification is not a list of request
types to process but rather a list of examples to qualify the
description of whether the time indicates when the message is received
or sent.
2026-02-06 15:38:48 +01:00
Aydın Mercan
a531f00a75
wipe hmac keys correctly pre-3.0 libcrypto
A lingering `sizeof` from the prototype era of !11094 caused the
key-wipe in `isc_hmac_key_destroy` to use `sizeof(key->len)` instead of
`key->len` for the length argument of `isc_safe_memwipe`.

This results in a buffer overflow of zero bytes in HMAC keys that are
less than 4 bytes. As such, the overflow can only be visibile in keys
that are less than 32-bits, which is beyond broken and creating such
keys are only possible in testing.

Therefore, this change is *not* a security fix since the conditions are
never reachable in any imaginable deployment scenario.

Builds that use OpenSSL >=3.0 are unaffected as the `sizeof` was only
remaining in pre-3.0 builds.
2026-02-06 14:14:43 +03:00
Aydın Mercan
ecb677658f
don't transform errors in hmac_sign
The change from DST_R_OPENSSLFAILURE to ISC_R_CRYPTOFAILURE seems to be
benign. Furthermore it should a bug to rely on the exacts crypto failure
code.
2026-02-02 11:50:14 +03:00
Aydın Mercan
19c9053a6b
use isc_ossl_wrap to generate epheremal tls keys 2026-02-02 11:50:14 +03:00
Aydın Mercan
b748651bb0
explicitly set ec points properties in pre-3.0 openssl
Generating a P-256 key in pre-3.0 wasn't explicitly using uncompressed
named curves in DNSSEC but was when generating an epheremal TLS key.
2026-02-02 11:50:14 +03:00
Aydın Mercan
251af02fe7
make generate_pkcs11_ec_key consistent with others 2026-02-02 11:50:14 +03:00
Aydın Mercan
c2f3a23a3e
expose isc__crypto_md in isc/ossl_wrap.h
This is a bit of a namespace convention violation but it fits the spirit of
this header since it is exposing OpenSSL-isms to others.

Further work is needed to make sure the exposed EVP_MD isn't needed
anymore.
2026-02-02 11:50:14 +03:00
Aydın Mercan
21f80a2bd7
make isc_ossl_wrap_ecdsa_set_deterministic consistent with style 2026-02-02 11:50:14 +03:00
Aydın Mercan
8c69fedc7c
switch away from ossl_param builders from ecdsa functions 2026-02-02 11:50:14 +03:00
Aydın Mercan
fe617aa830
set parameters in batch for rsa keygen
On top on improving readability, doing so allows us to use a uint32_t
for setting the e value, getting rid of allocating an unneccessary
BIGNUM.
2026-02-02 11:50:14 +03:00
Aydın Mercan
3bd3754994
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.
2026-02-02 11:50:14 +03:00
Aydın Mercan
f4d88404e2
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.
2026-02-02 11:50:14 +03:00
Aydın Mercan
f21d237374
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.
2026-02-02 11:50:14 +03:00
Aydın Mercan
c4a25e633c
add openssl_wrap
The isc_ossl_wrap API is intended to separate OpenSSL version specific
code that needs to expose the libcrypto internals and keep isc_crypto
clean.
2026-02-02 11:50:14 +03:00
Aydın Mercan
5ae9b4d14c
cleanup unused header in isc/md.h
Use `isc/crypto.h` whenever needed instead.
2026-02-02 11:50:14 +03:00
Aydın Mercan
8f106f2b66
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.
2026-02-02 11:50:14 +03:00
Aydın Mercan
f9ec4a1cdf
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.
2026-02-02 11:12:55 +03:00
Aydın Mercan
35eeefb437
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.
2026-02-02 11:12:53 +03:00
Colin Vidal
d0d4b40b62 dns_rdataset_* const parameters
dns_rdataset_clone() now have a const source rdataset. Also,
dns_rdataset_isassociated() also takes a const rdataset.
2026-01-30 19:33:42 +01:00
Mark Andrews
5843289550 Use isc__zero_or_more when calling isc_base64_tobuffer 2026-01-28 00:25:04 +11:00
Mark Andrews
62fd89d4a1 Use isc_one_or_more when calling isc_base64_tobuffer 2026-01-28 00:25:04 +11:00
Mark Andrews
7feb0f5b53 Use isc_one_or_more when calling isc_hex_tobuffer 2026-01-27 23:57:34 +11:00
Mark Andrews
07610f8566 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.
2026-01-27 23:57:34 +11:00
Aram Sargsyan
31290eccb1 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.

Add a second condition for the "if" block.
2026-01-27 11:31:15 +00:00
Mark Andrews
10366e4f4e Remove extraneous space at start of brid and hhit records 2026-01-27 16:05:29 +11:00
Mark Andrews
bdb9c838a8 Fix isc_base64_tobuffer call for brid and hhit
Zero length records were not being rejected.
2026-01-27 16:05:24 +11:00
Mark Andrews
3180e50459 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.
2026-01-24 00:38:51 +11:00
Matthijs Mekking
24aa490a9b Lower case the NSEC next owner name when signing
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.
2026-01-23 11:52:59 +00:00
Matthijs Mekking
b68069f275 Refactor dns_kasp_attach/detach
Replace implementation with ISC_REFCOUNT_IMPL.
2026-01-23 09:59:52 +00:00
Colin Vidal
bc1a66a1d0 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.
2026-01-22 07:31:00 +01:00
Colin Vidal
6e63d5d02a 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()`.
2026-01-22 07:31:00 +01:00