Commit graph

44949 commits

Author SHA1 Message Date
Ondřej Surý
d72b5fd5f6 fix: usr: Fix errors when retrying over TCP in notify_send_toaddr
If the source address is not available do not attempt
to retry over TCP otherwise clear the TSIG key from the
message prior to retrying.

Closes #5457

Merge branch '5457-remove-tcp-retry-in-notify-send-toaddr' into 'main'

See merge request isc-projects/bind9!10805
2026-02-19 13:47:03 +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
Ondřej Surý
5a5bc6de22
Don't retry notify over TCP if it could not successed
Prevent retrying the notify over TCP in case the source address is not
available or the source vs the destination address family mismatch or
when the destination address has been blackholed.  Properly log the
hard notify failures.
2026-02-19 13:44:28 +01:00
Ondřej Surý
ee3391a146
Fix assertion failure when sending notify fails over UDP
When dns_request_create() fails in notify_send_toaddr() the TSIG key was
not cleared when retrying over TCP causing assertion failure.  Set the
TSIG key to NULL in the dns_message to prevent the assertion failure.
2026-02-19 13:44:23 +01:00
Mark Andrews
ce954f1ded fix: dev: 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.

Merge branch 'marka-formerr-family-0' into 'main'

See merge request isc-projects/bind9!11563
2026-02-19 20:47:54 +11: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
Petr Špaček
efadf228b1 chg: ci: cross-version-config-tests should hard fail again
Merge branch 'reenable-cross-version-tests' into 'main'

See merge request isc-projects/bind9!11560
2026-02-18 15:20:14 +00:00
Petr Špaček
ae657429f6 Cross-version-config-tests should hard fail again
New tag was released so we can now re-enable check disabled in
093bef9211.
2026-02-18 15:19:28 +00:00
Ondřej Surý
aa546d5155 chg: nil: 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.

Merge branch 'ondrej/cleanup-dns_rdataslab' into 'main'

See merge request isc-projects/bind9!11376
2026-02-18 15:08:08 +01:00
Ondřej Surý
b8e07a0b5a
Use offsetof() instead of pointer arithmetics to get slabheader
In rdataset_getheader() a cast of the raw buffer to dns_slabheader_t and
pointer arithmetics was used to get the start of the slabheader
structure.  Use more correct offsetof(dns_slabheader_t, raw) to
calculate the correct start of the dns_slabheader_t from the flexible
member raw[].
2026-02-18 14:29:16 +01:00
Ondřej Surý
499cfc2f24
Move the count of items in the slabheader from raw data to struct
The count of items was stored in the raw data as first two bytes.
Instead of reading this from the raw header, move the number of the
items into the structure itself.

This needs the flexible member raw[] to be aligned on the size of the
pointer to prevent unaligned access to the start of the header from
rdataset_getheader() function that casts the raw[] to dns_slabheader_t.
2026-02-18 14:29:16 +01:00
Ondřej Surý
aaf3454079
Cleanup the unused members of dns_slabheader_t
After the rdataslab -> rdataslab,rdatavec split, there were couple of
unused struct members.  Remove all the unused members, reorder the
members to eliminate the padding holes and thus reduce the
dns_slabheader_t and dns_slabtop_t structure sizes.
2026-02-18 14:29:16 +01:00
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
Petr Špaček
8085b1bc23 Merge tag 'v9.21.18' 2026-02-18 10:29:45 +00:00
Mark Andrews
cc643cad17 fix: usr: DNSTAP wasn't logging forwarded queries correctly
Closes #5724

Merge branch '5724-dnstap-forwarder-queries-logging' into 'main'

See merge request isc-projects/bind9!11509
2026-02-17 14:32:22 +11:00
Mark Andrews
ea32141e48 Use shell function 'check_count' to check counts 2026-02-17 13:17:43 +11:00
Mark Andrews
24f85bc3f3 Document UPDATE QUERY and UPDATE RESPONSE 2026-02-17 13:17:43 +11:00
Mark Andrews
591096f131 Test forward query/response counts 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
Mark Andrews
77278beaf3 Add missed ret!=0 checks 2026-02-17 13:17:38 +11:00
Matthijs Mekking
dcf118f0a6 fix: doc: Minor documentation fixes for the 'rndc dnssec' command
List 'rndc dnssec' arguments in alphabetic order.
The `-step` argument was erroneously omitted from the usage output.

Closes #5731

Merge branch '5731-rndc-documentation-corrections' into 'main'

See merge request isc-projects/bind9!11529
2026-02-16 16:28:58 +00:00
Matthijs Mekking
4a22921936 List 'rndc dnssec' arguments in alphabetic order
Same as rndc usage orderning,
2026-02-16 16:28:47 +00:00
Matthijs Mekking
0dd61d8773 Add rndc dnssec -step command to usage
The `-step` argument was erroneously omitted from the usage output.
2026-02-16 16:28:47 +00:00
Michał Kępień
9c4c48a8ae chg: test: Use isctest.asyncserver in the "pipelined" test
Replace the custom DNS server used in the "pipelined" system test with
new code based on the isctest.asyncserver module.

Merge branch 'michal/pipelined-asyncserver' into 'main'

See merge request isc-projects/bind9!11516
2026-02-13 15:03:36 +01:00
Michał Kępień
3954025218
Use isctest.asyncserver in the "pipelined" test
Replace the custom DNS server used in the "pipelined" system test with
new code based on the isctest.asyncserver module.
2026-02-13 14:27:10 +01:00
Michał Kępień
10a2fc7f1f
Implement a response handler that forwards queries
Add a new response handler, ForwarderHandler, which enables forwarding
all queries to another DNS server.  To simplify implementation, always
forward queries to the target server via UDP, even if they are
originally received using a different transport protocol.
2026-02-13 14:27:10 +01:00
Michał Kępień
d3d9d166ed
Log the server socket receiving each query
Extend AsyncDnsServer._log_query() and AsyncDnsServer._log_response() so
that they also log the <address, port> tuple for the socket on which a
given query was received on.  Minimize the signatures of those methods
by taking advantage of all the information contained in the QueryContext
instances passed to them.
2026-02-13 14:27:10 +01:00
Michał Kępień
94a4793596
Store server socket information in QueryContext
Extend the QueryContext class with a field holding the <address, port>
tuple for the socket on which a given query was received.  This will
enable query handlers to act upon that information in arbitrary ways.
2026-02-13 14:27:10 +01:00
Alessio Podda
db6fe7bd16 chg: dev: Remove unnecessary dns_name_copy copies in qpzone_lookup
Followup on !11339, which removes further unnecessary copies in the lookups in qpzone.c. The performance impact seems minor though.

Merge branch 'alessio/qpzone-fewer-name-copies' into 'main'

See merge request isc-projects/bind9!11418
2026-02-12 23:01:10 +00: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
242dd34ad8 rem: nil: Remove unused dns_view_load() and dns_zt_load()
We always load zones asynchronously.

Merge branch 'matthijs-remove-unused-zt-and-view-load' into 'main'

See merge request isc-projects/bind9!11515
2026-02-12 13:43:21 +00: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
bc0e9f1ccb fix: usr: fetch loop detection improvements
Fixes a case where an in-domain NS with an expired glue would fail to resolve.

Let's consider the following parent-side delegation (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
```
    
And then the child-side of `foo.example.`:

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

While there is a zone misconfiguration (the TTL of the delegation and glue doesn't match in the parent and the child), it is possible to resolve `a.foo.example` on a cold-cache resolver. However, after the `ns.dnshost.example.` glue expires, the resolution would have failed with a "fetch loop detected" error. This is now fixed.

Closes #5588

Merge branch '5588-loopfetches' into 'main'

See merge request isc-projects/bind9!11535
2026-02-11 15:12:02 +01:00
Colin Vidal
4f8788310b system test for the ADB fetch loop detection
Add a system test which implement the scenario described in the previous
commit "relaxes fetch loop detection".
2026-02-11 14:33:22 +01: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
a36853d7fd chg: dev: resolver: refactoring of the dns_fetchresponse_t handling
Instead of cloning fetch responses immediately after inserting them at the head of the `fetch_response` list, defer cloning until the events are actually sent.

This enables to:
- Remove the `fctx->cloned` state;
- Simplify the code by eliminating explicit calls to `clone_result()`;
- Remove the logic that enforced having a fetch response with a `sigrdataset` at the head of the list;
- Remove (just a bit of) locking in some places.

The fetch result is stored directly in new `fctx` properties, but there is no memory increase as those are grouped in an anonymous struct used in a union besides another (bigger) anonymous struct wrapping properties used by qmin fetch only (and, in the case of qmin fetch, those fetch result properties are not needed).

Merge branch 'colin/resolver-cloneresults' into 'main'

See merge request isc-projects/bind9!11458
2026-02-10 09:25:09 +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
Mark Andrews
c482a8ca42 fix: doc: Document that dig's query options are order sensitive
Closes #5730

Merge branch '5730-document-query-options-order-sensitive' into 'main'

See merge request isc-projects/bind9!11526
2026-02-10 09:46:45 +11:00
Mark Andrews
879d2ed480 Document that query options are order sensitive 2026-02-10 09:00:48 +11:00
Ondřej Surý
1b80394e5a fix: usr: 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.

Closes #5738

Merge branch '5738-null-pointer-dereference-in-qpcache-add' into 'main'

See merge request isc-projects/bind9!11539
2026-02-09 11:05:20 +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