Commit graph

9768 commits

Author SHA1 Message Date
Ondřej Surý
4448f1adb2 Add bindrdatasets() function that binds both rdatasets
This removes code duplication between the dual bindrdataset() calls.  It
also unifies the handling as there were small differences between the
calls: one variant was checking for !NEGATIVE(found) condition and one
wasn't, and it is technically ok to do the check for all variants.
2025-02-18 20:15:00 +00:00
Ondřej Surý
53d9ef5bd0 Refactor check_stale_header() function
The check_stale_header() function now updates header_prev directly
so it doesn't have to be handled in the outer loop; it's always
set to the correct value of the previous header in the chain.
2025-02-18 20:15:00 +00:00
Evan Hunt
5281c708d3 clean up unnecessary code in qpcache
some code was left in the cache database implementation after
it was separated from the zone database, and can be cleaned up
and refactored now:

- the DNS_SLABHEADERATTR_IGNORE flag is never set in the cache
- support for loading the cache from was removed, but the add()
  function still had a 'loading' flag that's always false
- two different macros were used for checking the
  DNS_SLABHEADERATTR_NONEXISTENT flag - EXISTS() and NONEXISTENT().
  it's clearer to just use EXISTS().
- the cache doesn't support versions, so it isn't necessary to
  walk down the 'down' pointer chain when iterating through the
  cache or looking for a header to update.  'down' now only points
  to records that are deleted from the cache but have not yet been
  purged from memory. this allows us to simplify both the iterator
  and the add() function.
2025-02-18 20:15:00 +00:00
Artem Boldariev
fd3beaba2e Fix wrong logging severity in do_nsfetch()
ISC_LOG_WARNING was used while ISC_LOG_DEBUG(3) was implied.
2025-02-18 10:28:23 +02:00
Evan Hunt
fffa150df3 fix dns_qp_insert() checks in qpzone
in some places there were checks for failures of dns_qp_insert()
after dns_qp_getname(). such failures could only happen if another
thread inserted a node between the two calls, and that can't happen
because the calls are serialized with dns_qpmulti_write(). we can
simplify the code and just add an INSIST.
2025-02-17 12:21:50 -08:00
Aram Sargsyan
d5d63d6253 Fix a bug in generic_totext_in_svcb()
The 'sbpr_dohpath' case was missing from the switch-case. Add the
'sbpr_dohpath' case, which should work similarly as the 'sbpr_text'
case.
2025-02-17 17:33:43 +00:00
Aram Sargsyan
c6e3695478 Use named Service Parameter Keys (SvcParamKeys) by default
When converting SVCB records to text representation use named
SvcParamKeys values unless backward-compatible mode is activated,
in which case the values which were not defined initially in
RFC9460 and were added later (see [1]) are converted to opaque
"keyN" syntax, like, for example, "key7" instead of "dohpath".

[1] https://www.iana.org/assignments/dns-svcb/dns-svcb.xhtml

Co-authored-by: sdomi <ja@sdomi.pl>
2025-02-17 17:33:43 +00:00
Mark Andrews
04b1484ed8 Re-fetch pending records that failed validation
If a deferred validation on data that was originally queried with
CD=1 fails, we now repeat the query, since the zone data may have
changed in the meantime.
2025-02-17 08:57:58 +11:00
Mark Andrews
8b900d1808 Complete the deferred validation if there are no RRSIGs
When a query is made with CD=1, we store the result in the
cache marked pending so that it can be validated later, at
which time it will either be accepted as an answer or removed
from the cache as invalid.  Deferred validation was not
attempted when there were no cached RRSIGs for DNSKEY and
DS.  We now complete the deferred validation in this scenario.
2025-02-17 08:57:58 +11:00
Mark Andrews
5e49a9e4ae Fix "CNAME and other data" detection
prio_type was being used in the wrong place to optimize cname_and_other.
We have to first exclude and accepted types and we also have to
determine that the record exists before we can check if we are at
a point where a later CNAME cannot appear.
2025-02-14 01:51:38 +00:00
Ondřej Surý
732fc338a9
Switch the locknum generation for qpznode to random
Instead of using on hash of the name modulo number of the buckets,
assign the locknum randomly with isc_random_uniform().  This makes
the locknum assignment aligned with qpcache and allows the bucket
number to be non-prime in the future.
2025-02-04 22:50:49 +01:00
Ondřej Surý
1fa5219fdf
Rely on call_rcu() to destroy the qpzone outside of locks
Reduce the number of qpzone_ref() and qpzone_unref() calls in
qpzone_detachnode() by relying on the call_rcu to delay
the destruction of the lock buckets.
2025-02-04 21:37:46 +01:00
Ondřej Surý
6dcc398726
Reduce false sharing in dns_qpzone
Instead of having many node_lock_count * sizeof(<member>) arrays, pack
all the members into a qpzone_bucket_t that is cacheline aligned and have
a single array of those.
2025-02-04 21:37:46 +01:00
Ondřej Surý
c602d76c1f
Reduce false sharing in dns_qpcache
Instead of having many node_lock_count * sizeof(<member>) arrays, pack
all the members into a qpcache_bucket_t struct that is cacheline aligned
and have a single array of those.

Additionaly, make both the head and the tail of isc_queue_t padded, not
just the head, to prevent false sharing of the lock-free structure with
the lock that follows it.
2025-02-04 21:37:46 +01:00
Ondřej Surý
355fc48472
Print the expiration time of the stale records (not ancient)
In #1870, the expiration time of ANCIENT records were printed, but
actually the ancient records are very short lived, and the information
carries a little value.

Instead of printing the expiration of ANCIENT records, print the
expiration time of STALE records.
2025-02-03 15:47:06 +01:00
Ondřej Surý
36a3ceb19f
Restore the .ttl field for slabheader in dns_qpzone
The original .ttl field was actually used as TTL in the dns_qpzone unit.
Restore the field by adding it to union with the .expire struct member
and cleanup all the code that added or subtracted 'now' from the ttl
field as that was misleading as 'now' would be always 0 for qpzone
database.
2025-02-03 14:39:06 +01:00
Ondřej Surý
60f6b88c63
Remove duplicate 'now' argument from find_coveringnsec()
The find_coveringnsec() was getting the 'now' from two sources -
search->now and separate now argument.  Things like this are ticking
bombs, remove the extra 'now' argument and use single source of 'now'.
2025-02-03 14:39:06 +01:00
Ondřej Surý
58179e6a19
Expand the usage of mark_ancient() helper functions
When the mark_ancient() helper function was introduced, couple of places
with duplicate (or almost duplicate) code was missed.  Move the
mark_ancient() function closer to the top of the file, and correctly use
it in places that mark the header as ANCIENT.
2025-02-03 14:39:06 +01:00
Ondřej Surý
cfee6aa565
Add better ZEROTTL handling in bindrdataset()
If we know that the header has ZEROTTL set, the server should never send
stale records for it and the TTL should never be anything else than 0.
The comment was already there, but the code was not matching the
comment.
2025-02-03 14:39:06 +01:00
Ondřej Surý
e07f5a4a5b
In dns_slabheader_t structure, change .ttl to .expire
The old name was misleading as it never meant time-to-live, e.g. number
of seconds from now when the header should expire.  The true meaning was
an expiration time e.g. now + ttl.  This was the original design bug
that caused the slip when we assigned header->ttl to rdataset->ttl.
Because the name was matching, nobody has questioned the correctness of
the code both during the MR review and during the numerous re-reviews
when we were searching for the cause of the 54 year TTL.
2025-02-03 14:39:06 +01:00
Ondřej Surý
1bbb57f81b
In cache, set rdataset TTL to 0 when the header is not active
When the header has been marked as ANCIENT, but the ttl hasn't been
reset (this happens in couple of places), the rdataset TTL would be
set to the header timestamp instead to a reasonable TTL value.

Since this header has been already expired (ANCIENT is set), set the
rdataset TTL to 0 and don't reuse this field to print the expiration
time when dumping the cache.  Instead of printing the time, we now
just print 'expired (awaiting cleanup'.
2025-02-03 14:39:06 +01:00
Mark Andrews
6469ebd08e Set PENDINGOK if STARTATZONE is set
When there are parent and child zones on the same server, the DNSKEY
lookup was failing as the pending record we are validating is needed
to fetch the DNSKEY records.  This change allows that to happen.
The caller is already setting STARTATZONE when the name being looked
up is a subdomain of the current domain.
2025-02-03 00:24:34 +00:00
Mark Andrews
ea9d7080cd Validate address lookups from ADB
The address lookups from ADB were not being validated, allowing
spoofed responses to be accepted and used for other lookups.

Validate the answers except when CD=1 is set in the triggering
request.  Separate ADB names looked up with CD=1 from those without
CD=1, to prevent the use of unvalidated answers in the normal lookup
case (CD=0).  Set the TTL on unvalidated (pending) responses to
ADB_CACHE_MINIMUM when adding them to the ADB.
2025-02-03 00:24:34 +00:00
Evan Hunt
1f095b902c
fix the cache findzonecut implementation
the search for the deepest known zone cut in the cache could
improperly reject a node containing stale data, even if the
NS rdataset wasn't the data that was stale.

this change also improves the efficiency of the search by
stopping it when both NS and RRSIG(NS) have been found.
2025-02-02 18:43:50 +01:00
Evan Hunt
d4f791793e Clarify reference counting in QP databases
Change the names of the node reference counting functions
and add comments to make the mechanism easier to understand:

- newref() and decref() are now called qpcnode_acquire()/
  qpznode_acquire() and qpcnode_release()/qpznode_release()
  respectively; this reflects the fact that they modify both
  the internal and external reference counters for a node.

- qpcnode_newref() and qpznode_newref() are now called
  qpcnode_erefs_increment() and qpznode_erefs_increment(), and
  qpcnode_decref() and qpznode_decref() are now called
  qpcnode_erefs_decrement() and qpznode_erefs_decrement(),
  to reflect that they only increase and decrease the node's
  external reference counters, not internal.
2025-01-30 20:08:46 -08:00
Ondřej Surý
431513d8b3
Remove db_nodelock_t in favor of reference counted qpdb
This removes the db_nodelock_t structure and changes the node_locks
array to be composed only of isc_rwlock_t pointers.  The .reference
member has been moved to qpdb->references in addition to
common.references that's external to dns_db API users.  The .exiting
members has been completely removed as it has no use when the reference
counting is used correctly.
2025-01-30 16:43:02 +01:00
Ondřej Surý
36a26bfa1a
Remove origin_node from qpcache
The origin_node in qpcache was always NULL, so we can remove the
getoriginode() function and origin_node pointer as the
dns_db_getoriginnode() correctly returns ISC_R_NOTFOUND when the
function is not implemented.
2025-01-30 16:43:02 +01:00
Ondřej Surý
814b87da64
Refactor decref() in both qpcache.c and qpzone.c
Cleanup the pattern in the decref() functions in both qpcache.c and
qpzone.c, so it follows the similar patter as we already have in
newref() function.
2025-01-30 16:43:02 +01:00
Colin Vidal
9021f9d802 detect dup EDE with bitmap and store next pos
In order to avoid to loop to find the next position to store an EDE in
a dns_edectx_t, add a "nextede" state which holds the next available
position.

Also, in order ot avoid to loop to find if an EDE is already existing in
a dns_edectx_t, and avoid a duplicate, use a bitmap to immediately know
if the EDE is there or not.

Those both changes applies for adding or copying EDE.

Also make the direction of dns_ede_copy more explicit/avoid errors by
making "edectx_from" a const pointer.
2025-01-30 11:52:53 +01:00
Colin Vidal
7b01cbfb04 add lib/dns/ede.c documentation
Add documentation usage of EDE compilation unit as well as centralize
all EDE-related macros in the same lib/dns/include/dns/ede.h header.
2025-01-30 11:52:53 +01:00
Colin Vidal
f9f41190b3 Refactor test covering dns_ede API
Migrate tests cases in client_test code which were exclusively testing
code which is now all wrapped inside ede compilation unit. Those are
testing maximum number of EDE, duplicate EDE as well as truncation of
text of an EDE.

Also add coverage for the copy of EDE from an edectx to another one, as
well as checking the assertion of the maximum EDE info code which can be
used.
2025-01-30 11:52:53 +01:00
Ondřej Surý
2f8e0edf3b Split and simplify the use of EDE list implementation
Instead of mixing the dns_resolver and dns_validator units directly with
the EDE code, split-out the dns_ede functionality into own separate
compilation unit and hide the implementation details behind abstraction.

Additionally, the EDE codes are directly copied into the ns_client
buffers by passing the EDE context to dns_resolver_createfetch().

This makes the dns_ede implementation simpler to use, although sligtly
more complicated on the inside.

Co-authored-by: Colin Vidal <colin@isc.org>
Co-authored-by: Ondřej Surý <ondrej@isc.org>
2025-01-30 11:52:53 +01:00
Andoni Duarte Pintado
3a64b288c1 Merge tag 'v9.21.4' 2025-01-29 17:17:18 +01:00
Michal Nowak
5dbc87730e
Use archived version of draft-icann-dnssec-keymgmt-01.txt
The iana.org link is gone.
2025-01-28 12:13:57 +01:00
Colin Vidal
78274ec2b1 fix EDE 22 time out detection
Extended DNS error 22 (No reachable authority) was previously detected
when `fctx_expired` fired. It turns out this function is used as a
"safety net" and the timeout detection should be caught earlier.

It was working though, because of another issue fixed by !9927. Since
this change, the recursive request timed out detection occurs before
`fctx_expired` so EDE 22 is not added to the response message anymore.

The fix of the problem is to add the EDE 22 code in two situations:

- When the dispatch code timed out (rctx_timedout) the resolver code
  checks various properties to figure out if it needs to make another
  fetch attempt. One of the paramters if the fetch expiration time. If
  it expires, the whole recursion is canceled, so it now adds the EDE 22
  code.

- If the fetch expiration time doesn't expires in the case above (and
  other parameters allows it) a new fetch attempt is made (fctx_query).
  But before the new request is actually made, the fetch expiration time
  is re-checked. It might then has elapsed, and the whole recursion is
  canceled. So it now also adds the EDE 22 code here as well.
2025-01-27 11:49:44 +01:00
Colin Vidal
46a58acdf5 add support for EDE code 1 and 2
Add support for EDE codes 1 (Unsupported DNSKEY Algorithm) and 2
(Unsupported DS Digest Type) which might occurs during DNSSEC
validation in case of unsupported DNSKEY algorithm or DS digest type.

Because DNSSEC internally kicks off various fetches, we need to copy
all encountered extended errors from fetch responses to the fetch
context. Upon an event, the errors from the fetch context are copied
to the client response.
2025-01-24 12:26:30 +00:00
Evan Hunt
a19f6c6654 clean up result codes that are never used
the following result codes are obsolete and have been removed
from result.h and result.c:

        - ISC_R_NOTHREADS
        - ISC_R_BOUND
        - ISC_R_NOTBOUND
        - ISC_R_NOTDIRECTORY
        - ISC_R_EMPTY
        - ISC_R_NOTBLOCKING
        - ISC_R_INPROGRESS
        - ISC_R_WOULDBLOCK

        - DNS_R_TOOMANYHOPS
        - DNS_R_NOREDATA
        - DNS_R_BADCKSUM
        - DNS_R_MOREDATA
        - DNS_R_NOVALIDDS
        - DNS_R_UNKNOWNOPT
        - DNS_R_NOVALIDKEY
        - DNS_R_NTACOVERED

        - DST_R_COMPUTESECRETFAILURE
        - DST_R_NORANDOMNESS
        - DST_R_NOCRYPTO
2025-01-23 15:54:57 -08:00
Evan Hunt
10accd6260 clean up uses of ISC_R_NOMEMORY
the isc_mem allocation functions can no longer fail; as a result,
ISC_R_NOMEMORY is now rarely used: only when an external library
such as libjson-c or libfstrm could return NULL. (even in
these cases, arguably we should assert rather than returning
ISC_R_NOMEMORY.)

code and comments that mentioned ISC_R_NOMEMORY have been
cleaned up, and the following functions have been changed to
type void, since (in most cases) the only value they could
return was ISC_R_SUCCESS:

- dns_dns64_create()
- dns_dyndb_create()
- dns_ipkeylist_resize()
- dns_kasp_create()
- dns_kasp_key_create()
- dns_keystore_create()
- dns_order_create()
- dns_order_add()
- dns_peerlist_new()
- dns_tkeyctx_create()
- dns_view_create()
- dns_zone_setorigin()
- dns_zone_setfile()
- dns_zone_setstream()
- dns_zone_getdbtype()
- dns_zone_setjournal()
- dns_zone_setkeydirectory()
- isc_lex_openstream()
- isc_portset_create()
- isc_symtab_create()

(the exception is dns_view_create(), which could have returned
other error codes in the event of a crypto library failure when
calling isc_file_sanitize(), but that should be a RUNTIME_CHECK
anyway.)
2025-01-23 15:54:57 -08:00
Matthijs Mekking
5e3aef364f dnssec-signzone retain signature if key is offline
Track inside the dns_dnsseckey structure whether we have seen the
private key, or if this key only has a public key file.

If the key only has a public key file, or a DNSKEY reference in the
zone, mark the key 'pubkey'. In dnssec-signzone, if the key only
has a public key available, consider the key to be offline. Any
signatures that should be refreshed for which the key is not available,
retain the signature.

So in the code, 'expired' becomes 'refresh', and the new 'expired'
is only used to determine whether we need to keep the signature if
the corresponding key is not available (retaining the signature if
it is not expired).

In the 'keysthatsigned' function, we can remove:
  -	key->force_publish = false;
  -	key->force_sign = false;

because they are redundant ('dns_dnsseckey_create' already sets these
values to false).
2025-01-23 09:43:07 +00:00
Matthijs Mekking
7ae7851173 Fix possible truncation in dns_keymgr_status()
If the generated status output exceeds 4096 it was silently truncated,
now we output that the status was truncated.
2025-01-23 09:31:00 +01:00
Mark Andrews
89afc11389 Terminate yaml string after negative comment 2025-01-22 21:33:08 +00:00
Colin Vidal
4096f27130 add support for multiple EDE
Extended DNS error mechanism (EDE) enables to have several EDE raised
during a DNS resolution (typically, a DNSSEC query will do multiple
fetches which each of them can have an error). Add support to up to 3
EDE errors in an DNS response. If duplicates occur (two EDEs with the
same code, the extra text is not compared), only the first one will be
part of the DNS answer.

Because the maximum number of EDE is statically fixed, `ns_client_t`
object own a static vector of `DNS_DE_MAX_ERRORS` (instead of a linked
list, for instance). The array can be fully filled (all slots point to
an allocated `dns_ednsopt_t` object) or partially filled (or
empty). In such case, the first NULL slot means there is no more EDE
objects.
2025-01-22 21:07:44 +01:00
Aram Sargsyan
a6d6c3cb45 Clean up fctx->next_timeout
Since the support for non-zero values of stale-answer-client-timeout
was removed in bd7463914f, 'next_timeout'
is unused. Clean it up.
2025-01-22 13:40:45 +00:00
Aram Sargsyan
87c453850c Fix rtt calculation bug for TCP in the resolver
When TCP is used, 'fctx_query()' adds one second to the rtt
(round-trip time) value, but there's a bug when the decision
about using TCP is made already after the calculation. Move the
block of the code which looks up the peers list to decide
whether to use TCP into a place that's before the rtt calculation
is performed. This commit doesn't add or remove any code, it just
moves the code and adds a comment block.
2025-01-22 13:40:45 +00:00
Aram Sargsyan
e61ba5865f Use a suitable response in tcp_connected() when initiating a read
When 'ISC_R_TIMEDOUT' is received in 'tcp_recv()', it times out the
oldest response in the active responses queue, and only after that it
checks whether other active responses have also timed out. So when
setting a timeout value for a read operation after a successful
connection, it makes sense to take the timeout value from the oldest
response in the active queue too, because, theoretically, the responses
can have different timeout values, e.g. when the TCP dispatch is shared.
Currently 'resp' is always NULL. Previously when connect and read
timeouts were not separated in dispatch this affected only logging, but
now since we are setting a new timeout after a successful connection,
we need to choose a suitable response from the active queue.
2025-01-22 13:40:45 +00:00
JINMEI Tatuya
7f4471594d
Optimize database decref by avoiding locking with refs > 1
Previously, this function always acquires a node write lock if it
might need node cleanup in case the reference decrements to 0.  In
fact, the lock is unnecessary if the reference is larger than 1 and it
can be optimized as an "easy" case. This optimization could even be
"necessary". In some extreme cases, many worker threads could repeat
acquring and releasing the reference on the same node, resulting in
severe lock contention for nothing (as the ref wouldn't decrement to 0
in most cases). This change would prevent noticeable performance
drop like query timeout for such cases.

Co-authored-by: JINMEI Tatuya <jtatuya@infoblox.com>
Co-authored-by: Ondřej Surý <ondrej@isc.org>
2025-01-22 14:27:13 +01:00
Ondřej Surý
9f945c8b67
Shutdown the fetch context after canceling the last fetch
Currently, the fetch context will continue running even when the last
fetch (response) has been removed from the context, so named can process
and cache the answer.  This can lead to a situation where the number of
outgoing recursing clients exceeds the the configured number for
recursive-clients.

Be more stringent about the recursive-clients limit and shutdown the
fetch context immediately after the last fetch has been canceled from
that particular fetch context.
2025-01-22 14:19:20 +01:00
Ondřej Surý
05faff6d53
Remove memory limit on ADB finds and fetches
Address Database (ADB) shares the memory for the short lived ADB
objects (finds, fetches, addrinfo) and the long lived ADB
objects (names, entries, namehooks).  This could lead to a situation
where the resolver-heavy load would force evict ADB objects from the
database to point where ADB is completely empty, leading to even more
resolver-heavy load.

Make the short lived ADB objects use the other memory context that we
already created for the hashmaps.  This makes the ADB overmem condition
to not be triggered by the ongoing resolver fetches.
2025-01-22 14:13:35 +01:00
Aram Sargsyan
612d76b83d Remove dispatch timeout INT16_MAX limitation
In some places there was a limitation of the maximum timeout
value of INT16_MAX, which is only about 32 seconds. Refactor
the code to remove the limitation.
2025-01-22 11:57:53 +00:00
Aram Sargsyan
64ffbe82c0 Separate the connect and the read timeouts in dispatch
The network manager layer has two different timers with their
own timeout values for TCP connections: connect timeout and read
timeout. Separate the connect and the read TCP timeouts in the
dispatch module too.
2025-01-22 11:57:52 +00:00
Aram Sargsyan
9ccd1be482 Update the dns_dispatch_add() function's documentation
The 'timedout' callback no longer exists. Remove the mentioning of
the 'timedout' callback.
2025-01-22 11:52:24 +00:00
Colin Vidal
c9529c0acb remove ISC_LINK(link) property from fetchctx
Likely because of historical reasons, struct fetchctx does have a list
link property but is never used as a list. Remove this link property.
2025-01-22 09:56:09 +00:00
Colin Vidal
93e6e72eb6 remove validator link form fetchctx
struct fetchctx does have a list of pending validators as well as a
pointer to the HEAD validator. Remove the validator pointer to avoid
confusion, as there is no perticular reasons to have it directly
accessible outside of the list.
2025-01-22 09:56:09 +00:00
Ondřej Surý
a1982cf1bb Limit the additional processing for large RDATA sets
Limit the number of records appended to ADDITIONAL section to the names
that have less than 14 records in the RDATA.  This limits the number
of the lookups into the database(s) during single client query.

Also don't append any additional data to ANY queries.  The answer to ANY
is already big enough.
2025-01-14 09:57:54 +00:00
Ondřej Surý
8356179953 Rename the qpzone and qpcache methods that implement DB api
All the database implementations share the same names for the methods
implementing the database.  That has some advantages like knowing what
to expect, but it turns out that any time such method shows up in any
kind of tracing - be it perf record, backtrace or anything else that
uses symbol names, it is very hard to distinguish whether the find()
belongs to qpcache, qpzone, builtin or sdlz implementation.

Make at least the names for qpzone and qpcache unique.
2025-01-14 09:57:54 +00:00
Evan Hunt
71e1c91695 dns_nsec3_addnsec3() can fail when iterating back
when adding a new NSEC3 record, dns_nsec3_addnsec3() uses a
dbiterator to seek to the newly created node and then find its
predecessor.  dbiterators in the qpzone use snapshots, so changes
to the database are not reflected in an already-existing iterator.
consequently, when we add a new node, we have to create a new iterator
before we can seek to it.
2025-01-09 17:04:08 -08:00
Evan Hunt
ad4bab306c qpzone find() function could set foundname incorrectly
when a requested name is found in the QP trie during a lookup, but its
records have been marked as nonexistent by a previous deletion, then
it's treated as a partial match, but the foundname could be left
pointing to the original qname rather than the parent. this could
lead to an assertion failure in query_findclosestnsec3().
2025-01-09 17:03:51 -08:00
Aram Sargsyan
d75bdabe51 Fix a typo in dns/master.h
The ISC_R_SEENINCLUDE definition does not exist, the correct one
is DNS_R_SEENINCLUDE.
2025-01-08 14:00:55 +00:00
Aram Sargsyan
3d7a9fba3b Don't disable RPZ and CATZ for zones with an $INCLUDE statement
The code in zone_startload() disables RPZ and CATZ for a zone if
dns_master_loadfile() returns anything other than ISC_R_SUCCESS,
which makes sense, but it's an error because zone_startload() can
also return DNS_R_SEENINCLUDE upon success when the zone had an
$INCLUDE statement.
2025-01-08 14:00:55 +00:00
Michał Kępień
7bdf5152d6
Adjust dns_message_logpacketfrom() log prefixes
Ensure the log prefixes passed to the dns_message_logpacketfrom()
function by its callers do not include the word "from" as the latter is
now emitted by the logfmtpacket() helper function.
2024-12-31 05:40:48 +01:00
Michał Kępień
58d38352ee
Adjust dns_message_logpacketfromto() log prefixes
Ensure the log prefixes passed to the dns_message_logpacketfromto()
function by its callers do not include the words "from" or "to" as those
are now emitted by the logfmtpacket() helper function.
2024-12-31 05:40:48 +01:00
Michał Kępień
c5555a5ca2
Log both "from" and "to" socket in debug messages
Move dns_dispentry_getlocaladdress() calls around so that they are not
only invoked when dnstap support is compiled in.  This function calls
isc_nmhandle_localaddr(), which may issue a system call, but only if the
ISC_SOCKET_DETAILS preprocessor macro is set at compile time.

Pass the value extracted by dns_dispentry_getlocaladdress() to
dns_message_logpacketfromto() so that it gets logged, adding useful
information to the relevant debug messages.
2024-12-31 05:40:48 +01:00
Michał Kępień
4ab35f6839
Rename dns_message_logpacket()
Since dns_message_logpacket() only takes a single socket address as a
parameter (and it is always the sending socket's address), rename it to
dns_message_logpacketfrom() so that its name better conveys its purpose
and so that the difference in purpose between this function and
dns_message_logpacketfromto() becomes more apparent.
2024-12-31 05:40:48 +01:00
Michał Kępień
fa073a0a63
Rename dns_message_logfmtpacket()
Since dns_message_logfmtpacket() needs to be provided with both "from"
and "to" socket addresses, rename it to dns_message_logpacketfromto() so
that its name better conveys its purpose.  Clean up the code comments
for that function.
2024-12-31 05:40:48 +01:00
Michał Kępień
bafa5d3c2e
Enable logging both "from" and "to" socket
Change the function prototype for dns_message_logfmtpacket() so that it
takes two isc_sockaddr_t parameters: one for the sending side and
another one for the receiving side.  This enables debug messages to be
more precise.

Also adjust the function prototype for logfmtpacket() accordingly.
Unlike dns_message_logfmtpacket(), this function must not require both
'from' and 'to' parameters to be non-NULL as it is still going to be
used by dns_message_logpacket(), which only provides a single socket
address.  Adjust its log format to handle both of these cases properly.

Adjust both dns_message_logfmtpacket() call sites accordingly, without
actually providing the second socket address yet.  (This causes the
revised REQUIRE() assertion in dns_message_logfmtpacket() to fail; the
issue will be addressed in a separate commit.)
2024-12-31 05:40:48 +01:00
Michał Kępień
05d69bd7a4
dns_message_logfmtpacket(): drop 'style' parameter
Both existing callers of the dns_message_logfmtpacket() function set the
argument passed as 'style' to &dns_master_style_comment.  To simplify
these call sites, drop the 'style' parameter from the prototype for
dns_message_logfmtpacket() and use a fixed value of
&dns_master_style_comment in the function's body instead.
2024-12-31 05:40:48 +01:00
Michał Kępień
064b2c6889
logfmtpacket(): drop useless local variables
All callers of the logfmtpacket() helper function require the argument
passed as 'address' to be non-NULL.  Meanwhile, the 'newline' and
'space' local variables in logfmtpacket() are only set to values
different than their initial values if the 'address' parameter is NULL.
Replace the 'newline' and 'space' local variables in logfmtpacket() with
fixed strings to improve code readability.
2024-12-31 05:40:48 +01:00
Michał Kępień
d6f9785ac6
Enable extraction of exact local socket addresses
Extracting the exact address that each wildcard/TCP socket is bound to
locally requires issuing the getsockname() system call, which libuv
exposes via its uv_*_getsockname() functions.  This is only required for
detailed logging and comes at a noticeable performance cost, so it
should not happen by default.  However, it is useful for debugging
certain problems (e.g. cryptic system test failures), so a convenient
way of enabling that behavior should exist.

Update isc_nmhandle_localaddr() so that it calls uv_*_getsockname() when
the ISC_SOCKET_DETAILS preprocessor macro is set at compile time.
Ensure proper handling of sockets that wrap other sockets.

Set the new ISC_SOCKET_DETAILS macro by default when --enable-developer
is passed to ./configure.  This enables detailed logging in the system
tests run in GitLab CI without affecting performance in non-development
BIND 9 builds.

Note that setting the ISC_SOCKET_DETAILS preprocessor macro at compile
time enables all callers of isc_nmhandle_localaddr() to extract the
exact address of a given local socket, which results e.g. in dnstap
captures containing more accurate information.

Mention the new preprocessor macro in the section of the ARM that
discusses why exact socket addresses may not be logged by default.
2024-12-29 12:32:05 +01:00
Michał Kępień
086c325ad3
Improve reuse of outgoing TCP connections
The dns_dispatch_gettcp() function is used for finding an existing TCP
connection that can be reused for sending a query from a specified local
address to a specified remote address.  The logic for matching the
provided <local address, remote address> tuple to one of the existing
TCP connections is implemented in the dispatch_match() function:

  - if the examined TCP connection already has a libuv handle assigned,
    it means the connection has already been established; therefore,
    compare the provided <local address, remote address> tuple against
    the corresponding address tuple for the libuv handle associated with
    the connection,

  - if the examined TCP connection does not yet have a libuv handle
    assigned, it means the connection has not yet been established;
    therefore, compare the provided <local address, remote address>
    tuple against the corresponding address tuple that the TCP
    connection was originally created for.

This logic limits TCP connection reuse potential as the libuv handle
assigned to an existing dispatch object may have a more specific local
<address, port> tuple associated with it than the local <address, port>
tuple that the dispatch object was originally created for.  That's
because the local address for outgoing connections can be set to a
wildcard <address, port> tuple (indicating that the caller does not care
what source <address, port> tuple will be used for establishing the
connection, thereby delegating the task of picking it to the operating
system) and then get "upgraded" to a specific <address, port> tuple when
the socket is bound (and a libuv handle gets associated with it).  When
another dns_dispatch_gettcp() caller then tries to look for an existing
TCP connection to the same peer and passes a wildcard address in the
local part of the tuple, the function will not match that request to a
previously-established TCP connection (unless isc_nmhandle_localaddr()
returns a wildcard address as well).

Simplify dispatch_match() so that the libuv handle associated with an
existing dispatch object is not examined for the purpose of matching it
to the provided <local address, remote address> tuple; instead, always
examine the <local address, remote address> tuple that the dispatch
object was originally created for.  This enables reuse of TCP
connections created without providing a specific local socket address
while still preventing other connections (created for a specific local
socket address) from being inadvertently shared.
2024-12-29 10:22:20 +01:00
Artem Boldariev
740292d3ec BIND - enable TLS SNI support for outgoing TLS connections
This commit ensures that BIND enables TLS SNI support for outgoing DoT
connections (when possible) in order to improve compatibility with
other DNS server software.
2024-12-26 17:23:25 +02:00
Artem Boldariev
6691a1530d TLS SNI - add low level support for SNI to the networking code
This commit adds support for setting SNI hostnames in outgoing
connections over TLS.

Most of the changes are related to either adapting the code to accept
and extra argument in *connect() functions and a couple of changes to
the TLS Stream to actually make use of the new SNI hostname
information.
2024-12-26 17:23:12 +02:00
Ondřej Surý
f7316b44b9 Use CMM_{STORE,LOAD}_SHARED to store/load glue in gluelist
ThreadSanitizer has trouble understanding that gluelist->glue is
constant after it is assigned to the slabheader with cmpxchg.  Help
ThreadSanitizer to understand the code by using CMM_STORE_SHARED and
CMM_LOAD_SHARED on gluelist->glue.

The ThreadSanitizer report:

    WARNING: ThreadSanitizer: data race
      Read of size 8 at 0x000000000001 by thread T0001:
	#0 addglue lib/dns/qpzone.c:5304 (BuildId: 62aa74b0423f77cc56d705f02c2412b4762577cb)
	#1 dns_db_addglue lib/dns/db.c:1119 (BuildId: 62aa74b0423f77cc56d705f02c2412b4762577cb)
	#2 query_additional lib/ns/query.c:2230 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#3 query_addrrset lib/ns/query.c:2324
	#4 query_prepare_delegation_response lib/ns/query.c:8595 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#5 query_delegation lib/ns/query.c:8780 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#6 query_notfound lib/ns/query.c:8552 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#7 query_gotanswer lib/ns/query.c:7553 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#8 query_lookup lib/ns/query.c:6020 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#9 ns__query_start lib/ns/query.c:5690 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#10 query_setup lib/ns/query.c:5239 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#11 ns_query_start lib/ns/query.c:11979 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#12 ns_client_request_continue lib/ns/client.c:2466 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#13 ns_client_request lib/ns/client.c:2142 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#14 isc___nm_readcb netmgr/netmgr.c:1859 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#15 isc__nm_readcb netmgr/netmgr.c:1874
	#16 isc__nm_udp_read_cb netmgr/udp.c:589 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#17 uv__udp_recvmmsg src/unix/udp.c:202 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#18 uv__udp_recvmsg src/unix/udp.c:245 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#19 uv__udp_io src/unix/udp.c:142
	#20 uv__io_poll src/unix/linux.c:1564 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#21 uv_run src/unix/core.c:458 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#22 loop_thread lib/isc/loop.c:328 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#23 thread_body lib/isc/thread.c:85 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#24 thread_run lib/isc/thread.c:100

      Previous write of size 8 at 0x000000000001 by thread T0002:
	#0 create_gluelist lib/dns/qpzone.c:5253 (BuildId: 62aa74b0423f77cc56d705f02c2412b4762577cb)
	#1 addglue lib/dns/qpzone.c:5281
	#2 dns_db_addglue lib/dns/db.c:1119 (BuildId: 62aa74b0423f77cc56d705f02c2412b4762577cb)
	#3 query_additional lib/ns/query.c:2230 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#4 query_addrrset lib/ns/query.c:2324
	#5 query_prepare_delegation_response lib/ns/query.c:8595 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#6 query_delegation lib/ns/query.c:8780 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#7 query_notfound lib/ns/query.c:8552 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#8 query_gotanswer lib/ns/query.c:7553 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#9 query_lookup lib/ns/query.c:6020 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#10 ns__query_start lib/ns/query.c:5690 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#11 query_setup lib/ns/query.c:5239 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#12 ns_query_start lib/ns/query.c:11979 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#13 ns_client_request_continue lib/ns/client.c:2466 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#14 ns_client_request lib/ns/client.c:2142 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#15 isc___nm_readcb netmgr/netmgr.c:1859 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#16 isc__nm_readcb netmgr/netmgr.c:1874
	#17 isc__nm_udp_read_cb netmgr/udp.c:589 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#18 uv__udp_recvmmsg src/unix/udp.c:202 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#19 uv__udp_recvmsg src/unix/udp.c:245 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#20 uv__udp_io src/unix/udp.c:142
	#21 uv__io_poll src/unix/linux.c:1564 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#22 uv_run src/unix/core.c:458 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#23 loop_thread lib/isc/loop.c:328 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#24 thread_body lib/isc/thread.c:85 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#25 thread_run lib/isc/thread.c:100

      Location is heap block of size 88 at 0x000000000024 allocated by thread T0002:
	#0 malloc <null> (BuildId: c08afb1c60772d9b4e4d4be38d0c0434c5b41990)
	#1 mallocx lib/isc/jemalloc_shim.h:41 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#2 mem_get lib/isc/mem.c:303
	#3 isc__mem_get lib/isc/mem.c:654
	#4 new_gluelist lib/dns/qpzone.c:5012 (BuildId: 62aa74b0423f77cc56d705f02c2412b4762577cb)
	#5 create_gluelist lib/dns/qpzone.c:5241
	#6 addglue lib/dns/qpzone.c:5281
	#7 dns_db_addglue lib/dns/db.c:1119 (BuildId: 62aa74b0423f77cc56d705f02c2412b4762577cb)
	#8 query_additional lib/ns/query.c:2230 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#9 query_addrrset lib/ns/query.c:2324
	#10 query_prepare_delegation_response lib/ns/query.c:8595 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#11 query_delegation lib/ns/query.c:8780 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#12 query_notfound lib/ns/query.c:8552 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#13 query_gotanswer lib/ns/query.c:7553 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#14 query_lookup lib/ns/query.c:6020 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#15 ns__query_start lib/ns/query.c:5690 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#16 query_setup lib/ns/query.c:5239 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#17 ns_query_start lib/ns/query.c:11979 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#18 ns_client_request_continue lib/ns/client.c:2466 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#19 ns_client_request lib/ns/client.c:2142 (BuildId: 9cc0711aeddfa6164f4f6fd94b0187f7bfa13ff2)
	#20 isc___nm_readcb netmgr/netmgr.c:1859 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#21 isc__nm_readcb netmgr/netmgr.c:1874
	#22 isc__nm_udp_read_cb netmgr/udp.c:589 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#23 uv__udp_recvmmsg src/unix/udp.c:202 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#24 uv__udp_recvmsg src/unix/udp.c:245 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#25 uv__udp_io src/unix/udp.c:142
	#26 uv__io_poll src/unix/linux.c:1564 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#27 uv_run src/unix/core.c:458 (BuildId: 355edf0d38120d6761c51ee8cab2c162dff57b0a)
	#28 loop_thread lib/isc/loop.c:328 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#29 thread_body lib/isc/thread.c:85 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#30 thread_run lib/isc/thread.c:100

      Thread T0001 'isc-loop-0002' (running) created by main thread at:
	#0 pthread_create <null> (BuildId: c08afb1c60772d9b4e4d4be38d0c0434c5b41990)
	#1 isc_thread_create lib/isc/thread.c:139 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#2 isc_loopmgr_run lib/isc/loop.c:508 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#3 main bin/named/main.c:1532 (BuildId: d03d7837520674921fd1fe7c353cb790cab69b3b)

      Thread T0002 'isc-loop-0003' (running) created by main thread at:
	#0 pthread_create <null> (BuildId: c08afb1c60772d9b4e4d4be38d0c0434c5b41990)
	#1 isc_thread_create lib/isc/thread.c:139 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#2 isc_loopmgr_run lib/isc/loop.c:508 (BuildId: de1ebc9b2642ead6bbd0f4553c7144c016b01ffc)
	#3 main bin/named/main.c:1532 (BuildId: d03d7837520674921fd1fe7c353cb790cab69b3b)

    SUMMARY: ThreadSanitizer: data race lib/dns/qpzone.c:5304 in addglue
2024-12-25 15:06:01 +00:00
Ondřej Surý
06f9163d51
Remove C++ support from the public header
Since BIND 9 headers are not longer public, there's no reason to keep
the ISC_LANG_BEGINDECL and ISC_LANG_ENDDECL macros to support including
them from C++ projects.
2024-12-18 13:10:39 +01:00
Ondřej Surý
29bde687b5
Rewrite the GLUE cache in QP zone database
This is a second attempt to rewrite the GLUE cache to not use per
database version hash table.  Instead of keeping a hash table indexed by
the node, use a directly linked list of GLUE records for each
slabheader.  This was attempted before, but there was a data race caused
by the fact that the thread cleaning the GLUE records could be slower
than accessing the slab headers again and reinitializing the wait-free
stack.

The improved design builds on the previous design, but adds a new
dns_gluelist structure that has a pointer to the database version.

If a dns_gluelist belonging to a different (old) version is detected, it
is just detached from the slabheader and left for the closeversion() to
clean it up later.
2024-12-13 21:48:11 +01:00
Ondřej Surý
759d59801b
Revert "Fix the glue table in the QP and RBT zone databases"
This reverts commit 5beae5faf9.
2024-12-13 21:48:11 +01:00
Michal Nowak
57b64dc397
Apply more SET_IF_NOT_NULL() changes
coccinelle v1.2 found more cases where the SET_IF_NOT_NULL macro
applies.
2024-12-13 13:52:52 +01:00
Evan Hunt
3394aa9c25 remove "sortlist"
this commit removes the deprecated "sortlist" option. the option
is now marked as ancient; it is a fatal error to use it in
named.conf.

the sortlist system test has been removed, and other tests that
referenced the option have been modified.

the enabling functions, dns_message_setsortorder() and
dns_rdataset_towiresorted(), have also been removed.
2024-12-11 15:09:24 -08:00
Mark Andrews
6d44e7320e Check that a zone that serves A/AAAA is served over IPv4/IPv6
named-checkzone will now, as part of the zone's integrity checks,
look to see if there are A or AAAA records being served and if so
check that the nameservers have A or AAAA records respectively.

These are a sometimes overlooked checks that, if not met, can mean
that a service that is supposed to reachable over IPv6 will not be
resolvable when the recursive resolver is IPv6 only.  Similarly for
IPv4 servers when there are IPv4 only resolvers.
2024-12-11 21:32:21 +00:00
Evan Hunt
95a0b6f479 clean up log module names
- remove obsolete DNS_LOGMODULE_RBT and DNS_LOGMODULE_RBTDB
- correct the misuse of the wrong log modules in dns/rpz.c and
  dns/catz.c, and add DNS_LOGMODULE_RPZ and DNS_LOGMODULE_CATZ
  to support them.
2024-12-11 17:11:32 +00:00
Matthijs Mekking
b6ca209292 Remove trusted-keys and managed-keys options
These options have been deprecated in 9.19 in favor of the trust-anchors
option. They are now removed to clean up the configuration and the code.
2024-12-11 14:04:37 +01:00
Matthijs Mekking
b6d031462f Drop single-use RETERR macro
If the RETERR define is only used once in a file, just drop the macro.
2024-12-10 08:46:22 +00:00
Petr Menšík
e7ddd3d7b4 Remove artificial search limit from libirs
Search directive from resolv.conf had a maximum of 8 domains. Any
more were ignored. Do not ignore them anymore; iterate over any
number of domains.

Test resolv.conf support by checking the first and last domain in
the search list. Ignore the domains between; just ensure that the
last domain in the configuration is the last domain parsed.
2024-12-10 00:51:56 +00:00
Mark Andrews
eb78ad2080 Fix parsing of unknown directives in resolv.conf
Only call eatline() to skip to the next line if we're not
already at the end of a line when parsing an unknown directive.
We were accidentally skipping the next line when there was only
a single unknown directive on the current line.
2024-12-09 16:08:06 -08:00
Ondřej Surý
2089996f96
Replace remaining usage of DNS_R_MUSTBESECURE with DNS_R_NOVALIDSIG
The DNS_R_MUSTBESECURE lost its meaning with removal of
dnssec-must-be-secure option, so replace the few remaining (and a bit
confusing) use of this result code with DNS_R_NOVALIDSIG.
2024-12-09 13:10:21 +01:00
Ondřej Surý
dcd1f5b842
Remove dnssec-must-be-secure feature
The dnssec-must-be-secure feature was added in the early days of BIND 9
and DNSSEC and it makes sense only as a debugging feature.  There are no
reasons to keep this feature in the production code anymore.

Remove the feature to simplify the code.
2024-12-09 13:10:21 +01:00
Ondřej Surý
64b5c2a743
Remove fixed value for the rrset-order option
Remove the "fixed" value from the "rrset-order" option and from the
autoconf script.
2024-12-09 13:09:26 +01:00
Aydın Mercan
8d093a6b66 disable deterministic ecdsa for fips builds
FIPS 186-5 [1] allows the usage deterministic ECDSA (Section 6.3) which
is compabile with RFC 6979 [2] but OpenSSL seems to follow FIPS 186-4
(Section 6.3) [3] which only allows for random k values, failing
k value generation for OpenSSL >=3.2. [4]

Fix signing by not using deterministic ECDSA when FIPS mode is active.

[1]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-5.pdf
[2]: https://datatracker.ietf.org/doc/html/rfc6979
[3]: https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.186-4.pdf
[4]: 85f17585b0/crypto/ec/ecdsa_ossl.c (L201-L207)
2024-12-09 10:33:01 +00:00
Matthijs Mekking
5b1ae4a948 Use query counters in validator code
Commit af7db89513 as part of #4141 was
supposed to apply the 'max-recursion-queries' quota to validator
queries, but the counter was never actually passed on to
dns_resolver_createfetch(). This has been fixed, and the global query
counter ('max-query-count', per client request) is now also added.
2024-12-09 10:55:32 +01:00
Ondřej Surý
7a99d1baf8
Revert "Attach dnssecsignstats, rcvquerystats, and requeststats"
This reverts commit fb50a71159.
2024-12-06 19:46:39 +01:00
Matthijs Mekking
397ca34e34 Remove unused maxquerycount
While implementing the global limit 'max-query-count', initially I
thought adding the variable to the resolver structure. But the limit
is per client request so it was moved to the view structure (and
counter in ns_query structure). However, I forgot to remove the
variable from the resolver structure again. This commit fixes that.
2024-12-06 11:19:18 +01:00
Mark Andrews
fb50a71159 Attach dnssecsignstats, rcvquerystats, and requeststats
In dns_zone_getdnssecsignstats, dns_zone_getrcvquerystats and
dns_zone_getrequeststats attach to the statistics structure.
2024-12-06 04:23:31 +00:00
Mark Andrews
aa686512df INSIST that the zone in locked before unlocking
This is the counterpart to the INSIST(!zone->locked) when the zone
is locked.
2024-12-06 04:23:31 +00:00
Matthijs Mekking
74f845d62f Add +maxtotalqueries option to delv
The max-query-count value can now be set on the command line in delv
with +maxtotalqueries.
2024-12-05 14:17:08 +01:00
Matthijs Mekking
16b3bd1cc7 Implement global limit for outgoing queries
This global limit is not reset on query restarts and is a hard limit
for any client request.
2024-12-05 14:17:07 +01:00
Matthijs Mekking
bbc16cc8e6 Implement 'max-query-count'
Add another option to configure how many outgoing queries per
client request is allowed. The existing 'max-recursion-queries' is
per restart, this one is a global limit.
2024-12-05 14:01:57 +01:00
Colin Vidal
d13e94b930 Add EDE 22 No reachable authority code
Add support for Extended DNS Errors (EDE) error 22: No reachable
authority. This occurs when after a timeout delay when the resolver is
trying to query an authority server.
2024-12-04 16:19:30 +01:00
Ondřej Surý
b61739836d
Remove dns_badcache usage in the resolver (lame-ttl)
The lame-ttl processing was overriden to be disabled in the config,
but the code related to the lame-ttl was still kept in the resolver
code.  More importantly, the DNS_RESOLVER_BADCACHETTL() macro would
cause the entries in the resolver badcache to be always cached for at
least 30 seconds even if the lame-ttl would be set to 0.

Remove the dns_badcache code from the dns_resolver unit, so we save some
processing time and memory in the resolver code.
2024-11-27 17:44:53 +01:00
Ondřej Surý
2cb5a6210f
Improve the badcache cleaning by adding LRU and using RCU
Instead of cleaning the dns_badcache opportunistically, add per-loop
LRU, so each thread-loop can clean the expired entries.  This also
allows removal of the atomic operations as the badcache entries are now
immutable, instead of updating the badcache entry in place, the old
entry is now deleted from the hashtable and the LRU list, and the new
entry is inserted in the LRU.
2024-11-27 17:44:53 +01:00
alessio
32c7060bd2 Optimize memory layout of core structs
Reduce memory footprint by:

 - Reordering struct fields to minimize padding.
 - Using exact-sized atomic types instead of *_least/*_fast variants
 - Downsizing integer fields where possible

Affected structs:

 - dns_name_t
 - dns_slabheader_t
 - dns_rdata_t
 - qpcnode_t
 - qpznode_t
2024-11-27 16:04:25 +01:00
Ondřej Surý
ee122ba025
Make dns_validator_cancel() respect the data ownership
There was a data race dns_validator_cancel() was called when the
offloaded operations were in progress.  Make dns_validator_cancel()
respect the data ownership and only set new .shuttingdown variable when
the offloaded operations are in progress.  The cancel operation would
then finish when the offloaded work passes the ownership back to the
respective thread.
2024-11-27 13:41:16 +01:00
Aram Sargsyan
3262ebd0f3 xfrin: refactor and fix the ISC_R_CANCELED case handling
Previously a ISC_R_CANCELED result code switch-case has been added to
the zone.c:zone_xfrdone() function, which did two things:

1. Schedule a new zone transfer if there's a scheduled force reload of
   the zone.

2. Reset the primaries list.

This proved to be not a well-thought change and causes problems,
because the ISC_R_CANCELED code is used not only when the whole transfer
is canceled, but also when, for example, a particular primary server is
unreachable, and named still needs to continue the transfer process by
trying the next server, which it now no longer does in some cases. To
solve this issue, three changes are made:

1. Make sure dns_zone_refresh() runs on the zone's loop, so that the
   sequential calls of dns_zone_stopxfr() and dns_zone_forcexfr()
   functions (like done in 'rndc retransfer -force') run in intended
   order and don't race with each other.

2. Since starting the new transfer is now guaranteed to run after the
   previous transfer is shut down (see the previous change), remove the
   special handling of the ISC_R_CANCELED case, and let the default
   handler to handle it like before. This will bring back the ability to
   try the next primary if the current one was interrupted with a
   ISC_R_CANCELED result code.

3. Change the xfrin.c:xfrin_shutdown() function to pass the
   ISC_R_SHUTTINGDOWN result code instead of ISC_R_CANCELED, as it makes
   more sense.
2024-11-27 10:37:13 +00:00
Aram Sargsyan
1c4a34a3ab Clean up dns_zonemgr_unreachabledel()
The results of isc_sockaddr_format() calls are not used, remove them
and the local variables.
2024-11-27 10:37:13 +00:00
Ondřej Surý
a6cce753e2
Move contributed DLZ modules into a separate repository
The DLZ modules are poorly maintained as we only ensure they can still
be compiled, the DLZ interface is blocking, so anything that blocks the
query to the database blocks the whole server and they should not be
used except in testing.  The DLZ interface itself should be scheduled
for removal.
2024-11-26 12:29:41 +01:00
JINMEI Tatuya
b0309ee631 use more generic log module name for 'logtoomanyrecords'
DNS_LOGMODULE_RBTDB was simply inappropriate, and this
log message is actually dependent on db implementation
details, so DNS_LOGMODULE_DB would be the best choice.
2024-11-26 04:06:58 +00:00
JINMEI Tatuya
4156995431 emit more helpful log for exceeding max-records-per-type
The new log message is emitted when adding or updating an RRset
fails due to exceeding the max-records-per-type limit. The log includes
the owner name and type, corresponding zone name, and the limit value.
It will be emitted on loading a zone file, inbound zone transfer
(both AXFR and IXFR), handling a DDNS update, or updating a cache DB.
It's especially helpful in the case of zone transfer, since the
secondary side doesn't have direct access to the offending zone data.

It could also be used for max-types-per-name, but this change
doesn't implement it yet as it's much less likely to happen
in practice.
2024-11-26 04:06:58 +00:00
Mark Andrews
af54ef9f5d Parse the URI template and check for a dns variable
The 'dns' variable in dohpath can be in various forms ({?dns},
{dns}, {&dns} etc.).  To check for a valid dohpath it ends up
being simpler to just parse the URI template rather than looking
for all the various forms if substring.
2024-11-26 12:38:49 +11:00
Remi Gacogne
e74052ea71 '{&dns}' is as valid as '{?dns}' in a SVCB's dohpath
See for example section 1.2. "Levels and Expression Types" of rfc6570.
2024-11-26 12:38:33 +11:00
alessio
99b4f01b33 Incrementally apply AXFR transfer
Reintroduce logic to apply diffs when the number of pending tuples is
above 128. The previous strategy of accumulating all the tuples and
pushing them at the end leads to excessive memory consumption during
transfer.

This effectively reverts half of e3892805d6
2024-11-22 15:00:55 +01:00
Ondřej Surý
0258850f20
Remove redundant parentheses from the return statement 2024-11-19 12:27:22 +01:00
Aram Sargsyan
53117b2ab3 Add REQUIREs to dns_xfrin_create()
Two REQUIRE assertions were accidentally deleted by the
dbf230650f commit earlier.
Bring them back.
2024-11-15 13:21:26 +00:00
Ondřej Surý
128e50e1ff
Revalidate the adbname when canceling the ADB find
When canceling the ADB find, the lock on the find gets released for
a brief period of time to be locked again inside adbname lock.  During
the brief period that the ADB find is unlocked, it can get canceled by
other means removing it from the adbname list which in turn causes
assertion failure due to a double removal from the adbname list.

Recheck if the find->adbname is still valid after acquiring the lock
again and if not just skip the double removal.  Additionally, attach to
the adbname as in the worst case, the adbname might also cease to exist
if the scheduler would block this particular thread for a longer period
of time invalidating the lock we are going to acquire and release.
2024-11-13 08:18:39 +01:00
Ondřej Surý
34b3e7cb40
Remove RBTDB implementation
QPDB is now a default implementation for both cache and zone.  Remove
the venerable RBTDB database implementation, so we can fast-track the
changes to the database without having to implement the design changes
to both QPDB and RBTDB and this allows us to be more aggressive when
refactoring the database design.
2024-11-12 09:07:19 +01:00
Aram Sargsyan
dbf230650f Fix a data race between dns_zone_getxfr() and dns_xfrin_create()
There is a data race between the statistics channel, which uses
`dns_zone_getxfr()` to get a reference to `zone->xfr`, and the creation
of `zone->xfr`, because the latter happens outside of a zone lock.

Split the `dns_xfrin_create()` function into two parts to separate the
zone tranfer startring part from the zone transfer object creation part.
This allows us to attach the new object to a local variable first, then
attach it to `zone->xfr` under a lock, and only then start the transfer.
2024-11-07 08:47:52 +00:00
Ondřej Surý
8a38c17cca
Enforce type checking for dns_dbversiont_t
Originally, the dns_dbversion_t was typedef'ed to void type.  This
allowed some flexibility, but using (void *) just removes any
type-checking that C might have.  Instead of using:

    typedef void dns_dbversion_t;

use a trick to define the type to non-existing structure:

    typedef struct dns_dbversion dns_dbversion_t;

This allows the C compilers to employ the type-checking while the
structure itself doesn't have to be ever defined because the actual
'storage' is never accessed using dns_dbversion_t type.
2024-11-07 08:03:55 +01:00
Ondřej Surý
fbd5f614d7
Enforce type checking for dns_dbnode_t
Originally, the dns_dbnode_t was typedef'ed to void type.  This allowed
some flexibility, but using (void *) just removes any type-checking that
C might have.  Instead of using:

    typedef void dns_dbnode_t;

use a trick to define the type to non-existing structure:

    typedef struct dns_dbnode dns_dbnode_t;

This allows the C compilers to employ the type-checking while the
structure itself doesn't have to be ever defined because the actual
'storage' is never accessed using dns_dbnode_t type.
2024-11-06 17:08:04 +01:00
Mark Andrews
5253c75b7a Update zone transfer summary
Print the expire option in the zone transfer summary. This is
currently emitted in a DEBUG(1) message.
2024-11-04 17:53:16 +00:00
Matthijs Mekking
680aedb595 dnssec-ksr keygen -o to create KSKs
Add an option to dnssec-ksr keygen, -o, to create KSKs instead of ZSKs.
This way, we can create a set of KSKS for a given period too.

For KSKs we also need to set timing metadata, including "SyncPublish"
and "SyncDelete". This functionality already exists in keymgr.c so
let's make the function accessible.

Replace dnssec-keygen calls with dnssec-ksr keygen for KSK in the
ksr system test and check keys for created KSKs as well. This requires
a slight modification of the check_keys function to take into account
KSK timings and metadata.
2024-11-01 15:50:16 +01:00
Evan Hunt
e2393ba27b refactor, add missing EDNS options, and fix option names
some EDNS option names, including DAU, DHU, N3U, and CHAIN,
were not printed in dns_message_pseudosectiontotext() or
_psuedosectiontoyaml(); they were displayed as unknown options.
this has been corrected.

that code was also refactored to use switch instead of if/else,
and to look up the option code names in a table to prevent
inconsistencies between the two formats. one such inconsistency
was corrected: the "TCP-KEEPALIVE" option is now always printed
with a hyphen, instead of being "TCP KEEPALIVE" when not using
YAML. the keepalive system test has been updated to expect this.

EDNS options that print DNS names (i.e., CHAIN and Report-Channel)
now enclose them in quotation marks to ensure YAML correctness.
the auth system test has been updated to expect this when grepping
for Report-Channel options.
2024-10-29 20:05:27 +00:00
Timo Eisenmann
e9d54d798f Use TLS for notifies if configured to do so 2024-10-24 12:55:01 +11:00
Mark Andrews
baab8a5d75 Fix TCP dispatches and transport
Dispatch needs to know the transport that is being used over the
TCP connection to correctly allow for it to be reused.  Add a
transport parameter to dns_dispatch_createtcp and dns_dispatch_gettcp
and use it when selecting a TCP socket for reuse.
2024-10-24 11:41:18 +11:00
Evan Hunt
c6698322c6 suppress report-channel for zones above the agent-domain
RFC 9567 section 8.1 specifies that the agent domain cannot
be a subdomain of the domain it is reporting on. therefore,
in addition to making it illegal to configure that at the
zone level, we also need to disable send-report-channel for
any zone for which the global send-report-channel value is
a subdomain.

we also now warn if send-report-channel is configured
globally to a zone that we host, but that zone doesn't
have log-report-channel set.
2024-10-23 21:29:32 +00:00
Evan Hunt
1cd0d291d3 enforce '*._er' requirement for error-reporting zones
if "log-report-channel" is set to "yes", then the zone must
contain a wildcard name matching '*._er' with a TXT record.
2024-10-23 21:29:32 +00:00
Evan Hunt
5519dd2669 add log-report-channel zone option
add a boolean "log-report-channel" option for primary and
secondary zones, which sets the DNS_ZONEOPT_LOGREPORTS zone
flag. this option is not yet functional.
2024-10-23 21:29:32 +00:00
Mark Andrews
c676fd2566 Allow send-report-channel to be set at the zone level
If send-report-channel is set at the zone level, it will
be stored in the zone object and used instead of the
view-level agent-domain when constructing the EDNS
Report-Channel option.
2024-10-23 21:29:32 +00:00
Mark Andrews
ac1c60d87e Add send-report-channel option
This commit adds support for the EDNS Report-Channel option,
which is returned in authoritative responses when EDNS is in use.

"send-report-channel" sets the Agent-Domain value that will be
included in EDNS Report-Channel options.  This is configurable at
the options/view level; the value is a DNS name. Setting the
Agent-Domain to the root zone (".") disables the option.

When this value has been set, incoming queries matchng the form
_er.<qtype>.<qname>.<extended-error-code>._er.<agent-domain>/TXT
will be logged to the dns-reporting-agent channel at INFO level.

(Note: error reporting queries will only be accepted if sent via
TCP or with a good server cookie.  If neither is present, named
returns BADCOOKIE to complete the DNS COOKIE handshake, or TC=1
to switch the client to TCP.)
2024-10-23 21:29:32 +00:00
Mark Andrews
b7a13cf2c1 Add per rule logging of dns_ssutable_checkrules processing
These are logged to the update category at debug level 99 and
have the following form.

    update-policy: using: signer=ddns-key.example.nil, name=updated.example.nil, addr=10.53.0.1, tcp=0, type=A, target=
    update-policy: trying: grant zonesub-key.example.nil zonesub TXT
    update-policy: next rule: signer does not match identity
    update-policy: trying: grant ddns-key.example.nil zonesub ANY
    update-policy: matched: grant ddns-key.example.nil zonesub ANY

or

    update-policy: using: signer=restricted.example.nil, name=example.nil, addr=10.53.0.1, tcp=0, type=TXT, target=
    update-policy: trying: grant zonesub-key.example.nil zonesub TXT
    update-policy: next rule: signer does not match identity
    update-policy: trying: grant ddns-key.example.nil zonesub ANY
    update-policy: next rule: signer does not match identity
    update-policy: trying: grant restricted.example.nil zonesub ANY
    update-policy: next rule: name/subdomain mismatch
    update-policy: no match found

where 'using:' is the calling parameters of dns_ssutable_checkrules,
'trying:' in the rule bing evaluated, "next rule:" is the reason
the rule does not match, "matched:" repeats the matched rule, and
no match found is reported when te set of rules is exhausted.
2024-10-23 08:35:08 +11:00
Evan Hunt
5ea1f6390d corrected code style errors
- add missing brackets around one-line statements
- add paretheses around return values
2024-10-18 19:31:27 +00:00
Aydın Mercan
05798b31ff
unify libcrypto and evp_md handling
Unify libcrypto initialization and explicit digest fetching in a single
place and move relevant code to the isc__crypto namespace instead of
isc__tls.

It will remove the remaining implicit fetching and deduplicate explicit
fetching inside the codebase.
2024-10-16 14:03:14 +03:00
Evan Hunt
8104ffda0e report client transport in 'rndc recursing'
when dumping the list of recursing clients, indicate whether
a given query was sent over UDP, TCP, TLS, or HTTP.
2024-10-14 12:59:52 -07:00
Matthijs Mekking
af54e3dadc Small keymgr improvement
When a key is to be purged, don't run the key state machinery for it.
2024-10-11 17:42:01 +02:00
Matthijs Mekking
5fdad05a8a Verify new key files before running keymgr
Prior to running the keymgr, first make sure that existing keys
are present in the new keylist. If not, treat this as an operational
error where the keys are made offline (temporarily), possibly unwanted.
2024-10-11 17:42:00 +02:00
Matthijs Mekking
0396bf98ee Revert "fix: chg: Improve performance when looking for the closest encloser when returning NSEC3 proofs"
This reverts merge request !9436
2024-10-10 06:59:28 +00:00
Aram Sargsyan
ab07803465 Fix a data race in dns_zone_getxfrintime()
The dns_zone_getxfrintime() function fails to lock the zone before
accessing its 'xfrintime' structure member, which can cause a data
race between soa_query() and the statistics channel. Add the missing
locking/unlocking pair, like it's done in numerous other similar
functions.
2024-10-09 09:13:04 +00:00
Ondřej Surý
4ef316e21e Skip TCP dispatch responses that are not ours
When matching the TCP dispatch responses, we should skip the responses
that do not belong to our TCP connection.  This can happen with faulty
upstream server that sends invalid QID back to us.
2024-10-02 10:41:04 +00:00
Aram Sargsyan
d49a8f518a Don't ignore the local port number in dns_dispatch_add() for TCP
The dns_dispatch_add() function registers the 'resp' entry in
'disp->mgr->qids' hash table with 'resp->port' being 0, but in
tcp_recv_success(), when looking up an entry in the hash table
after a successfully received data the port is used, so if the
local port was set (i.e. it was not 0) it fails to find the
entry and results in an unexpected error.

Set the 'resp->port' to the given local port value extracted from
'disp->local'.
2024-10-02 08:53:44 +00:00
Mark Andrews
b3a2c790f3 Store static-stub addresses seperately in the adb
Static-stub address and addresses from other sources where being
mixed together resulting in static-stub queries going to addresses
not specified in the configuration or alternatively static-stub
addresses being used instead of the real addresses.
2024-10-01 00:19:13 +00:00
Petr Špaček
a0f3b0c5de Remove unused function dns_zonemgr_resumexfrs() 2024-09-30 12:42:08 +00:00
Aram Sargsyan
4123d59fbc Add a missing rcu_read_unlock() call on exit path
An exit path in the dns_dispatch_add() function fails to get out of
the RCU critical section when returning early. Add the missing
rcu_read_unlock() call.
2024-09-27 13:48:33 +00:00
Mark Andrews
b919b9b4f3 Add the new record type WALLET (262)
This provides a mapping from a domain name to a cryptographic
currency wallet and is a clone of TXT.
2024-09-25 10:32:38 +00:00
Ondřej Surý
96ef98558c
Don't enable timeouts in dns_dispatch for incoming transfers
The dns_dispatch_add() call in the dns_xfrin unit had hardcoded 30
second limit.  This meant that any incoming transfer would be stopped in
it didn't finish within 30 seconds limit.  Additionally, dns_xfrin
callback was ignoring the return value from dns_dispatch_getnext() when
restarting the reading from the TCP stream; this could cause transfers
to get stuck waiting for a callback that would never come due to the
dns_dispatch having already been shut down.

Call the dns_dispatch_add() without a timeout and properly handle the
result code from the dns_dispatch_getnext().
2024-09-21 10:15:47 +02:00
Ondřej Surý
0f810b3144
Modify dns_dispatch API to accept zero timeout
The dns_dispatch_add() has timeout parameter that could not be 0 (for
not timeout).  Modify the dns_dispatch implementation to accept a zero
timeout for cases where the timeouts are undesirable because they are
managed externally.
2024-09-21 10:15:37 +02:00
Nicki Křížek
ebb5bd9c0f Update code formatting
clang 19 was updated in the base image.
2024-09-20 17:26:33 +02:00
Evan Hunt
5a444838db rename 'rbtiterator' and similar names in qpcache
when the QP cache was adapted from the RBT database, some names
weren't changed. this could be confusing, so let's change them now.
also, we no longer need to include rbt.h.
2024-09-19 19:32:27 +00:00
Nicki Křížek
377831a290 Merge tag 'v9.21.1' 2024-09-18 18:02:41 +02:00
Ondřej Surý
62d59766d6
Remove DNSRPS implementation
DNSRPS was the API for a commercial implementation of Response-Policy
Zones that was supposedly better.  However, it was never open-sourced
and has only ever been available from a single vendor.  This goes against
the principle that the open-source edition of BIND 9 should contain only
features that are generally available and universal.

This commit removes the DNSRPS implementation from BIND 9.  It may be
reinstated in the subscription edition if there's enough interest from
customers, but it would have to be rewritten as a plugin (hook) instead
of hard-wiring it again in so many places.
2024-09-18 17:39:14 +02:00
Evan Hunt
98ae5dfc7e
fix DNSRPS errors
silence some reported snprintf() overrun warnings that prevented
DNSRPS from building on some platforms.
2024-09-18 17:24:13 +02:00
Evan Hunt
dc13333957
use uv_dlopen() instead of dlopen() when linking DNSRPZ
take advantage of libuv's shared library handling capability
when linking to a DNSRPS library.  (see b396f55586 and 37b9511ce1
for prior related work.)
2024-09-18 17:24:13 +02:00
Ondřej Surý
d7bff3c0f9
Remove old cruft from dnsrps code
There was some old cruft for ancient compilers checking for attributes
that we regularly use, etc.  Just remove the cruft.
2024-09-18 17:24:13 +02:00
Aram Sargsyan
7c45caa8a5 Set logging category for notify/xfer related messages
Some notify/xfer related log messages are logged at the general
category. Set a more suitable caterogry for those messages.
2024-09-17 15:08:40 +00:00
Aram Sargsyan
a018b4e36f Implement the ForwardOnlyFail statistics channel counter
The new ForwardOnlyFail statistics channel counter indicates the
number of queries failed due to bad forwarders for 'forward only'
zones.
2024-09-16 09:31:14 +00:00