Commit graph

15876 commits

Author SHA1 Message Date
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ý
c18bb5f1f2
Remove unused definition of ISC_CMSG_IP_TOS
The #define was used before, but we forgot to clean it up when we
removed support for dscp.
2024-11-27 15:03:27 +01:00
Ondřej Surý
95a7419c2a
Remove the incomplete code for IPv6 pktinfo
The code that listens on individual interfaces is now stable and doesn't
require any changes.  The code that would bind to IPv6 wildcard address
and then use IPv6 pktinfo structure to get the source address is not
going to be completed, so it's better to just remove the dead cruft.
2024-11-27 15:03:27 +01:00
Ondřej Surý
34a9a9a6be
Assume universal availability of socklen_t
The SUSv2 defines accept(..., socklen_t), so we can safely require
socklen_t to be universally available.
2024-11-27 15:03:27 +01:00
Ondřej Surý
e85399b1c0
Assume that IPv4 and IPv6 is always available
In 2024, it is reasonable to assume that IPv4 and IPv6 is always
available on a socket() level.  We still keep the option to enable or
disable each IP version individually, as the routing might be broken or
undesirable for one of the versions.
2024-11-27 15:03:27 +01:00
Ondřej Surý
5b273b5726
Assume IPV6_V6ONLY is universally available
In 2024, IPV6_V6ONLY socket option is either available or the operating
system is just not going to be supported.
2024-11-27 15:03:27 +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
Petr Menšík
c5ebe5eb0a Remove ns_listenlist_default()
It is not used anywhere in named and is no longer necessary
there.  It was called in some unit tests, but was not actually
needed by them.
2024-11-26 15:22:30 -08: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
Ondřej Surý
a0a1769509
Add new logging category for logging crypto errors in libisc
The libisc now includes sizeable chunks of cryptography, but the crypto
log module was missing.  Add the new ISC_LOGMODULE_CRYPTO to libisc and
use it in the isc_tls error logging.
2024-11-26 11:22:33 +01:00
Colin Vidal
bcf24ca07e Add a none parameter to query-source[-v6]
This change adds a "none" parameter to the query-source[-v6]
options in named.conf, which forbid the usage of IPv4 or IPv6
addresses when doing upstream queries.
2024-11-26 08:45:50 +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
Mark Andrews
9006839ed7 Provide more visibility into configuration errors
by logging SSL_CTX_use_certificate_chain_file and
SSL_CTX_use_PrivateKey_file errors
2024-11-26 10:31:44 +11:00
Aydın Mercan
d987e2d745
add separate query counters for new protocols
Add query counters for DoT, DoH, unencrypted DoH and their proxied
counterparts. The protocols don't increment TCP/UDP counters anymore
since they aren't the same as plain DNS-over-53.
2024-11-25 13:07:29 +03:00
Colin Vidal
642776a976 Remove namedconf port/tls deprecated check on *-source[-v6] options
The usage of port and tls arguments in *-source and *-source-v6 named
configuration options has been previously removed. Remove
configuration check deprecating usage of those arguments.
2024-11-22 18:50:10 +01: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
Mark Andrews
a24d6e1654 Re-split format strings
Re-split format strings that had been poorly split by multiple
clang-format runs using different versions of clang-format.
2024-11-20 13:06:43 +11:00
Ondřej Surý
1a19ce39db
Remove redundant semicolons after the closing braces of functions 2024-11-19 12:27:22 +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
Alessio Podda
7a57200f38 Merge parse_querysource and parse_sockaddrsub
The query-source option has the slight quirk of allowing the address to
be specified in two ways, either as every other source option, or as an
"address" key-value pair.
For this reason, it had a separate parsing function from other X-source
options, but it is possible to extend the parsing of other X-sources to
be generic and also handle query-source.
This commit just does that.
2024-11-05 09:37:08 +01:00
Ondřej Surý
88103e72d5 Add OpenSSL includes as needed
The isc/crypto.h now directly includes the OpenSSL headers (evp.h) and
any application that includes that header also needs to have
OPENSSL_CFLAGS in the Makefile.am.  Adjust the required automake files
as needed.
2024-11-04 23:35:52 +00: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
5bcccf4754 expand validity checks for send-report-channel
when configured at the zone level, send-report-channel cannot be
a subdomain of the zone name.
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
d60324891c set up logging functionality using log-report-channel
the logging of error-report queries is no longer activated by
the view's "send-report-channel" option; that now only configures
the agent-domain value that is to be sent in authoritative
responses. the warning that was logged when "send-agent-domain"
was set to a value that is not a locally configured zone has
been removed.

error-report logging is now activated by the presence of an
authoritative zone with the "log-report-channel" option set to
"yes".  this is not permitted in the root zone.

NOTE: a zone with "log-report-channel yes;" should contain a
"*._er" wildcard, but that requirement is not yet enforced.
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
Mark Andrews
d282e5a66e Add log category update-policy 2024-10-23 08:30:59 +11:00
Mark Andrews
6c095f89f5 Fix parsing of hostnames in rndc.conf
When DSCP was removed the parsing of hostnames was accidentally
broken resulting in an assertion failure.  Call cfg_parse_tuple
rather than using custom code in parse_sockaddrnameport.
2024-10-22 10:30:07 +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
0b0f05215c
include missing definitions for fips builds 2024-10-17 15:28:31 +03:00
Mark Andrews
840eaa628d Fix recursive-clients 0
Setting recursive-clients 0 triggered an assertion in isc_quota_soft.
This has now been fixed.
2024-10-17 11:04:26 +11: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
Petr Menšík
9e55ffaf89 Remove unused <openssl/hmac.h> headers from OpenSSL shims
The <openssl/hmac.h> header was unused and including the
header might cause build failure when OpenSSL doesn't have
Engines support enabled.

See https://fedoraproject.org/wiki/Changes/OpensslDeprecateEngine

Removes unused hmac includes after Remove OpenSSL Engine support
(commit ef7aba7072) removed engine
support.
2024-10-16 04:19:16 +00:00
Mark Andrews
67f31c5046 Use a binary search to find the NSEC3 closest encloser
maxlabels is the suffix length that corresponds to the latest
NXDOMAIN response.  minlabels is the suffix length that corresponds
to longest found existing name.
2024-10-14 23:19:34 +00: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
7bd44a4182 Refactor the way check_recursionquota() is used
Rename check_recursionquota() to acquire_recursionquota(), and
implement a new function called release_recursionquota() to
reverse the action. It helps with decreasing code duplication.
2024-10-09 10:31:33 +00:00
Aram Sargsyan
36c4808903 Fix error path bugs in the "recursing-clients" list management
In two places, after linking the client to the manager's
"recursing-clients" list using the check_recursionquota()
function, the query.c module fails to unlink it on error
paths. Fix the bugs by unlinking the client from the list.

Also make sure that unlinking happens before detaching the
client's handle, as it is the logically correct order, e.g.
in case if it's the last handle and ns__client_reset_cb()
can be called because of the detachment.
2024-10-09 10:31:33 +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
Aram Sargsyan
b8c068835e Clean up 'nodetach' in ns_client
The 'nodetach' member is a leftover from the times when non-zero
'stale-answer-client-timeout' values were supported, and currently
is always 'false'. Clean up the member and its usage.
2024-10-09 08:03:13 +00:00
Ondřej Surý
eec30c33c2 Don't enable SO_REUSEADDR on outgoing UDP sockets
Currently, the outgoing UDP sockets have enabled
SO_REUSEADDR (SO_REUSEPORT on BSDs) which allows multiple UDP sockets to
bind to the same address+port.  There's one caveat though - only a
single (the last one) socket is going to receive all the incoming
traffic.  This in turn could lead to incoming DNS message matching to
invalid dns_dispatch and getting dropped.

Disable setting the SO_REUSEADDR on the outgoing UDP sockets.  This
needs to be done explicitly because `uv_udp_open()` silently enables the
option on the socket.
2024-10-02 12:15:53 +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
Alessio Podda
cc167266aa Support ISO timestamps with timezone information
This commit adds support for timestamps in iso8601 format with timezone
when logging. This is exposed through the iso8601-tzinfo printtime
suboption.
It also makes the new logging format the default for -g output,
hopefully removing the need for custom timestamp parsing in scripts.
2024-10-01 15:09:43 +00:00
alessio
bc63758d70 Null clausedefs for ancient options
This commit nulls all type fields for the clausedef lists that are
declared ancient, and removes the corresponding cfg_type_t and parsing
functions when they are found to be unused after the change.
2024-10-01 10:17:04 +02: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
Ondřej Surý
88227ea665
Use release memory ordering when incrementing reference counter
As the relaxed memory ordering doesn't ensure any memory
synchronization, it is possible that the increment will succeed even
in the case when it should not - there is a race between
atomic_fetch_sub(..., acq_rel) and atomic_fetch_add(..., relaxed).
Only the result is consistent, but the previous value for both calls
could be same when both calls are executed at the same time.
2024-09-30 11:03:01 +02: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ý
06e5ada4be
Use libuv functions to get memory available to BIND 9
This change uses uv_get_total_memory() to get the memory available to
BIND 9 with possible modification by uv_get_constrained_memory() if the
libuv version is recent enough to honour constraints created by
f.e. cgroups.
2024-09-24 15:51:14 +02:00
Ondřej Surý
31458d405a
Add support to read number of online CPUs on OpenBSD
The OpenBSD doesn't have sysctlbyname(), but sysctl() can be used to
read the number of online/available CPUs by reading following MIB(s):
[CTL_HW, HW_NCPUONLINE] with fallback to [CTL_HW, HW_NCPU].
2024-09-21 12:38:33 +02:00
Ondřej Surý
3a91c0a4e3
Cleanup the sysctlbyname and friends configure checks and ifdefs
Cleanup various checks and cleanups that are available on the all
platforms like sysctlbyname() and various related <sys/*.h> headers
that are either defined in POSIX or available on Linux and all BSDs.
2024-09-21 12:38:33 +02:00
Ondřej Surý
26e7358b16
Use uv_available_parallelism() if available
Instead of cooking up our own code for getting the number of available
CPUs for named to use, make use of uv_available_parallelism() from
libuv >= 1.44.0.
2024-09-21 12:38:33 +02: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
Nicki Křížek
842abe9fbf Revert "Double the number of threadpool threads"
This reverts commit 6857df20a4.
2024-09-20 14:31:25 +02:00
Petr Menšík
e6b19af2dd Move common flags logging to shared functions
Query and response log shares the same flags. Move flags logging out of
log_query to share it with log_response. Use buffer instead of snprintf
to fill flags a bit faster.

Signed-off-by: Petr Menšík <pemensik@redhat.com>
2024-09-19 21:44:06 +00:00
Petr Menšík
6f879aba65 Make responselog flags similar to querylog
Remove answer flag from log, log instead count of records for each
message section. Include EDNS version and few flags of response. Add
also status of result.

Still does not include body of responses rrset.
2024-09-19 21:44:06 +00:00
Mark Andrews
5fad79c92f Log the rcode returned to for a query
Log to the querylog the rcode of a previous query using
the identifier 'response:' to diffenciate queries from
responses.
2024-09-19 21:44:06 +00: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
Ondřej Surý
b576c4c977 Limit the outgoing UDP send queue size
If the operating system UDP queue gets full and the outgoing UDP sending
starts to be delayed, BIND 9 could exhibit memory spikes as it tries to
enqueue all the outgoing UDP messages.  As those are not going to be
delivered anyway (as we argued when we stopped enlarging the operating
system send and receive buffers), try to send the UDP messages directly
using `uv_udp_try_send()` and if that fails, drop the outgoing UDP
message.
2024-09-17 14:02:03 +00:00
alessio
8b8149cdd2 Do not set SO_INCOMING_CPU
We currently set SO_INCOMING_CPU incorrectly, and testing by Ondrej
shows that fixing the issue and setting affinities is worse than letting
the kernel schedule threads without constraints. So we should not set
SO_INCOMING_CPU anymore.
2024-09-16 12:18:22 +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
Aram Sargsyan
e430ce7039 Fix a 'serverquota' counter calculation bug
The 'all_spilled' local variable in resolver.c:fctx_getaddresses()
is 'true' by default, and only becomes false when there is at least
one successfully found NS address. However, when a 'forward only;'
configuration is used, the code jumps over the part where it looks
for NS addresses and doesn't reset the 'all_spilled' to false, which
results in incorretly increased 'serverquota' statistics variable,
and also in invalid return error code from the function. The result
code error didn't make any differences, because all codes other than
'ISC_R_SUCCESS' or 'DNS_R_WAIT' were treated in the same way, and
the result code was never logged anywhere.

Set the default value of 'all_spilled' to 'false', and only make it
'true' before actually starting to look up NS addresses.
2024-09-16 08:23:12 +00:00
Ondřej Surý
8a96a3af6a Move offloaded DNSSEC operations to different helper threads
Currently, the isc_work API is overloaded.  It runs both the
CPU-intensive operations like DNSSEC validations and long-term tasks
like RPZ processing, CATZ processing, zone file loading/dumping and few
others.

Under specific circumstances, when many large zones are being loaded, or
RPZ zones processed, this stops the CPU-intensive tasks and the DNSSEC
validation is practically stopped until the long-running tasks are
finished.

As this is undesireable, this commit moves the CPU-intensive operations
from the isc_work API to the isc_helper API that only runs fast memory
cleanups now.
2024-09-12 12:09:45 +00:00
Ondřej Surý
6370e9b311 Add isc_helper API that adds 1:1 thread for each loop
Add an extra thread that can be used to offload operations that would
affect latency, but are not long-running tasks; those are handled by
isc_work API.

Each isc_loop now has matching isc_helper thread that also built on top
of uv_loop.  In fact, it matches most of the isc_loop functionality, but
only the `isc_helper_run()` asynchronous call is exposed.
2024-09-12 12:09:45 +00:00
Aram Sargsyan
35ef25e5ea Fix data race in offloaded dns_message_checksig()
When verifying a message in an offloaded thread there is a race with
the worker thread which writes to the same buffer. Clone the message
buffer before offloading.
2024-09-12 09:08:35 +00:00
alessio
da0e48b611 Remove "port" from source address options
Remove the use of "port" when configuring query-source(-v6),
transfer-source(-v6), notify-source(-v6), parental-source(-v6),
etc. Remove the use of source ports for parental-agents.

Also remove the deprecated options use-{v4,v6}-udp-ports and
avoid-{v4,v6}udp-ports.
2024-09-12 08:15:58 +02:00
Mark Andrews
b9246418e8 Fix named-checkconf and statistics-channels
If neither libxml2 nor libjson_c are available have named-checkconf
fail if a statistics-channels block is specified.
2024-09-12 09:21:44 +10:00
Michal Nowak
ff69d07fed
Update code formatting
clang 19 was updated in the base image.
2024-09-10 17:31:32 +02:00
JINMEI Tatuya
7289090683 allow IXFR-to-AXFR fallback on DNS_R_TOOMANYRECORDS
This change allows fallback from an IXFR failure to AXFR when the
reason is DNS_R_TOOMANYRECORDS. This is because this error condition
could be temporary only in an intermediate version of IXFR
transactions and it's possible that the latest version of the zone
doesn't have that condition. In such a case, the secondary would never
be able to update the zone (even if it could) without this fallback.

This fallback behavior is particularly useful with the recently
introduced max-records-per-type and max-types-per-name options:
the primary may not have these limitations and may temporarily
introduce "too many" records, breaking IXFR. If the primary side
subsequently deletes these records, this fallback will help recover
the zone transfer failure automatically; without it, the secondary
side would first need to increase the limit, which requires more
operational overhead and has its own adverse effect.

This change also fixes a minor glitch that DNS_R_TOOMANYRECORDS wasn't
logged in xfrin_fail.
2024-09-10 14:02:38 +02:00
Aram Sargsyan
0367c60759 Fix RCU API usage in acl.c
The rcu_xchg_pointer() function can be used outside of a critical
section, and usually must be followed by a synchronize_rcu() or
call_rcu() call to detach from the resource, unless if there are
some guarantees in place because of our own reference counting.
2024-09-10 09:54:20 +00:00
Mark Andrews
61faffd06f Add flag to named-checkconf to ignore "not configured" errors
named-checkconf now takes "-n" to ignore "not configured" errors.
This allows named-checkconf to check the syntax of configurations
from other builds which have support for more options.
2024-09-09 23:32:16 +00:00
Nicki Křížek
6857df20a4 Double the number of threadpool threads
Introduce this temporary workaround to reduce the impact of long-running
tasks in offload threads which can block the resolution of queries.
2024-09-06 14:15:21 +02:00
Matthijs Mekking
911daeb306 Nit logging change
Fix wrong function name (dns_dnssec_keymgr -> dns_keymgr_run).

Add error log if dns_keymgr_offline() fails.
2024-09-03 12:01:21 +02:00
Matthijs Mekking
5af53a329f Fix bug in dns_keymgr_offline
If the ZSK has lifetime unlimited, the timing metadata "Inactive" and
"Delete" cannot be found and is treated as an error. Fix by allowing
these metadata to not exist.
2024-09-03 11:57:56 +02:00
Aram Sargsyan
d85918aebf Process canceled/shut down results in validate_dnskey_dsset_done()
When a validator is already shut down, val->name becomes NULL. We
need to process and keep the ISC_R_CANCELED or ISC_R_SHUTTINGDOWN
result code before calling validate_async_done(), otherwise, when it
is called with the hardcoded DNS_R_NOVALIDSIG result code, it can
cause an assetion failure when val->name (being NULL) is used in
proveunsecure().
2024-09-02 15:40:30 +00:00
Ondřej Surý
5a2df8caf5 Follow the number of CPU set by taskset/cpuset
Administrators may wish to constrain the set of cores that BIND 9 runs
on via the 'taskset', 'cpuset' or 'numactl' programs (or equivalent on
other O/S), for example to achieve higher (or more stable) performance
by more closely associating threads with individual NIC rx queues. If
the admin has used taskset, it follows that BIND ought to
automatically use the given number of CPUs rather than the system wide
count.

Co-Authored-By: Ray Bellis <ray@isc.org>
2024-08-29 14:43:18 +00:00
Mark Andrews
d42ea08f16 Return partial match when requested
Return partial match from dns_db_find/dns_db_find when requested
to short circuit the closest encloser discover process.  Most of the
time this will be the actual closest encloser but may not be when
there yet to be committed / cleaned up versions of the zone with
names below the actual closest encloser.
2024-08-29 12:48:20 +00:00
Mark Andrews
43f0b0e8eb Move lock earlier in the call sequence
fctx->state should be read with the lock held.

    1559        /*
    1560         * Caller must be holding the fctx lock.
    1561         */

    CID 468796: (#1 of 1): Data race condition (MISSING_LOCK)
    1. missing_lock: Accessing fctx->state without holding lock fetchctx.lock.
       Elsewhere, fetchctx.state is written to with fetchctx.lock held 2 out of 2 times.
    1562        REQUIRE(fctx->state == fetchstate_done);
    1563
    1564        FCTXTRACE("sendevents");
    1565
    1566        LOCK(&fctx->lock);
    1567
2024-08-29 04:33:56 +00:00
Mark Andrews
a45e39d114 Use atomics to access find->status 2024-08-28 22:42:16 +00:00
Mark Andrews
c900300f21 Use an accessor fuction to access find->status
find->status is marked as private and access is controlled
by find->lock.
2024-08-28 22:42:16 +00:00
Aram Sargsyan
c7e8b7cf63 Exempt prefetches from the fetches-per-server quota
Give prefetches a free pass through the quota so that the cache
entries for popular zones could be updated successfully even if the
quota for is already reached.
2024-08-26 15:50:21 +00:00
Aram Sargsyan
cada2de31f Exempt prefetches from the fetches-per-zone quota
Give prefetches a free pass through the quota so that the cache entry
for a popular zone could be updated successfully even if the quota for
it is already reached.
2024-08-26 15:50:21 +00:00
Ondřej Surý
d61712d14e Stop using malloc_usable_size and malloc_size
Although the nanual page of malloc_usable_size says:

    Although the excess bytes can be over‐written by the application
    without ill effects, this is not good programming practice: the
    number of excess bytes in an allocation depends on the underlying
    implementation.

it looks like the premise is broken with _FORTIFY_SOURCE=3 on newer
systems and it might return a value that causes program to stop with
"buffer overflow" detected from the _FORTIFY_SOURCE.  As we do have own
implementation that tracks the allocation size that we can use to track
the allocation size, we can stop relying on this introspection function.

Also the newer manual page for malloc_usable_size changed the NOTES to:

    The value returned by malloc_usable_size() may be greater than the
    requested size of the allocation because of various internal
    implementation details, none of which the programmer should rely on.
    This function is intended to only be used for diagnostics and
    statistics; writing to the excess memory without first calling
    realloc(3) to resize the allocation is not supported.  The returned
    value is only valid at the time of the call.

Remove usage of both malloc_usable_size() and malloc_size() to be on the
safe size and only use the internal size tracking mechanism when
jemalloc is not available.
2024-08-26 15:00:44 +00:00
Evan Hunt
642a1b985d remove the "dialup" and "heartbeat-interval" options
mark "dialup" and "heartbeat-interval" options as ancient and
remove the documentation and the code implementing them.
2024-08-22 11:11:10 -07:00
Aram Sargsyan
c05a823e8b Implement the 'request-ixfr-max-diffs' configuration option
This limits the maximum number of received incremental zone
transfer differences for a secondary server. Upon reaching the
confgiured limit, the secondary aborts IXFR and initiates a full
zone transfer (AXFR).
2024-08-22 13:42:27 +00:00
Mark Andrews
035289be71 Check key tag range when matching dnssec keys to kasp keys 2024-08-22 12:12:02 +00:00
Mark Andrews
c5bc0a1805 Add optional range directive to keys in dnssec-policy 2024-08-22 12:12:02 +00:00
Mark Andrews
25bf77fac6 Add the concept of allowed key tag ranges to kasp 2024-08-22 12:12:02 +00:00
Matthijs Mekking
f37eb33f29 Fix algorithm rollover bug wrt keytag conflicts
If there is an algorithm rollover and two keys of different algorithm
share the same keytags, then there is a possibility that if we check
that a key matches a specific state, we are checking against the wrong
key.

Fix this by not only checking for matching key id but also key
algorithm.
2024-08-22 11:29:43 +02:00
Ondřej Surý
7b756350f5
Use clang-format-19 to update formatting
This is purely result of running:

    git-clang-format-19 --binary clang-format-19 origin/main
2024-08-22 09:21:55 +02:00
Matthijs Mekking
2e3068ed60 Disable some behavior in offline-ksk mode
Some things we no longer want to do when we are in offline-ksk mode.

1. Don't check for inactive and private keys if the key is a KSK.
2. Don't update the TTL of DNSKEY, CDS and CDNSKEY RRset, these come
   from the SKR.
2024-08-22 08:21:52 +02:00
Matthijs Mekking
61cf599fbf Retrieve RRSIG from SKR
When it is time to generate a new signature (dns_dnssec_sign), rather
than create a new one, retrieve it from the SKR.
2024-08-22 08:21:52 +02:00
Matthijs Mekking
30d20b110e Don't read private key files for offline KSKs
When we are appending contents of a DNSKEY rdataset to a keylist,
don't attempt to read the private key file of a KSK when we are in
offline-ksk mode.
2024-08-22 08:21:52 +02:00
Matthijs Mekking
2190aa904f Update key states in offline-ksk mode
With offline-ksk enabled, we don't run the keymgr because the key
timings are determined by the SKR. We do update the key states but
we derive them from the timing metadata.

Then, we can skip a other tasks in offline-ksk mode, like DS checking
at the parent and CDS synchronization, because the CDS and CDNSKEY
RRsets also come from the SKR.
2024-08-22 08:21:52 +02:00
Matthijs Mekking
63e058c29e Apply SKR bundle on rekey
When a zone has a skr structure, lookup the currently active bundle
that contains the right key and signature material.
2024-08-22 08:21:52 +02:00
Matthijs Mekking
037382c4a5 Implement SKR import
When 'rndc skr import' is called, read the file contents and store the
data in the zone's skr structure.
2024-08-22 08:21:52 +02:00
Matthijs Mekking
445722d2bf Add code to store SKR
This added source code stores SKR data. It is loosely based on:
https://www.iana.org/dnssec/archive/files/draft-icann-dnssec-keymgmt-01.txt

A SKR contains a list of signed DNSKEY RRsets. Each change in data
should be stored in a separate bundle. So if the RRSIG is refreshed that
means it is stored in the next bundle. Likewise, if there is a new ZSK
pre-published, it is in the next bundle.

In addition (not mentioned in the draft), each bundle may contain
signed CDS and CDNSKEY RRsets.

Each bundle has an inception time. These will determine when we need
to re-sign or re-key the zone.
2024-08-22 08:21:52 +02:00
Matthijs Mekking
0598381236 Add offline-ksk option
Add a new configuration option to enable Offline KSK key management.

Offline KSK cannot work with CSK because it splits how keys with the
KSK and ZSK role operate. Therefore, one key cannot have both roles.
Add a configuration check to ensure this.
2024-08-22 08:21:52 +02:00
Nicki Křížek
779de4ec34
Merge tag 'v9.21.0' 2024-08-21 16:23:09 +02:00
Ondřej Surý
3bca3cb5cf
Destroy the dns_xfrin isc_timers on the correct loop
There are few places where we attach/detach from the dns_xfrin object
while running on a different thread than the zone's assigned thread -
xfrin_xmlrender() in the statschannel and dns_zone_stopxfr() to name the
two places where it happens now.  In the rare case, when the incoming
transfer completes (or shuts down) in the brief period between the other
thread attaches and detaches from the dns_xfrin, the isc_timer_destroy()
calls would be called by the last thread calling the xfrin_detach().
In the worst case, it would be this other thread causing assertion
failure.  Move the isc_timer_destroy() call to xfrin_end() function
which is always called on the right thread and to match this move
isc_timer_create() to xfrin_start() - although this other change makes
no difference.
2024-08-21 13:54:40 +02:00
Ondřej Surý
679e90a57d Add isc_log_createandusechannel() function to simplify usage
The new
isc_log_createandusechannel() function combines following calls:

    isc_log_createchannel()
    isc_log_usechannel()

calls into a single call that cannot fail and therefore can be used in
places where we know this cannot fail thus simplifying the error
handling.
2024-08-20 12:50:39 +00:00
Ondřej Surý
091d738c72 Convert all categories and modules into static lists
Remove the complicated mechanism that could be (in theory) used by
external libraries to register new categories and modules with
statically defined lists in <isc/log.h>.  This is similar to what we
have done for <isc/result.h> result codes.  All the libraries are now
internal to BIND 9, so we don't need to provide a mechanism to register
extra categories and modules.
2024-08-20 12:50:39 +00:00
Ondřej Surý
8506102216 Remove logging context (isc_log_t) from the public namespace
Now that the logging uses single global context, remove the isc_log_t
from the public namespace.
2024-08-20 12:50:39 +00:00
Ondřej Surý
043f11de3f Remove isc_log_write1() and isc_log_vwrite1() functions
The isc_log_write1() and isc_log_vwrite1() functions were meant to
de-duplicate the messages sent to the isc_log subsystem.  However, they
were never used in an entire code base and the whole mechanism around it
was complicated and very inefficient.  Just remove those, there are
better ways to deduplicate syslog messages inside syslog daemons now.
2024-08-20 12:50:39 +00:00
Ondřej Surý
b2dda86254 Replace isc_log_create/destroy with isc_logconfig_get()
Add isc_logconfig_get() function to get the current logconfig and use
the getter to replace most of the little dancing around setting up
logging in the tools. Thus:

    isc_log_create(mctx, &lctx, &logconfig);
    isc_log_setcontext(lctx);
    dns_log_setcontext(lctx);
    ...
    ...use lcfg...
    ...
    isc_log_destroy();

is now only:

    logconfig = isc_logconfig_get(lctx);
    ...use lcfg...

For thread-safety, isc_logconfig_get() should be surrounded by RCU read
lock, but since we never use isc_logconfig_get() in threaded context,
the only place where it is actually used (but not really needed) is
named_log_init().
2024-08-20 12:50:39 +00:00
Ondřej Surý
a8a689531f Use single logging context for everything
Instead of juggling different logging context, use one single logging
context that gets initialized in the libisc constructor and destroyed in
the libisc destructor.

The application is still responsible for creating the logging
configuration before using the isc_log API.

This patch is first in the series in a way that it is transparent for
the users of the isc_log API as the isc_log_create() and
isc_log_destroy() are now thin shims that emulate the previous
functionality, but it isc_log_create() will always return internal
isc__lctx pointer and isc_log_destroy() will actually not destroy the
internal isc__lctx context.

Signed-off-by: Ondřej Surý <ondrej@isc.org>
2024-08-20 12:50:39 +00:00
Aram Sargsyan
8bb9568467 Process also the ISC_R_CANCELED result code in rpz_rewrite()
Log  canceled queries (e.g. when shutting down a hung fetch)
in DEBUG3 level instead of DEBUG1 which is used for the
"unrecognized" result codes.
2024-08-19 10:15:01 +00:00
Ondřej Surý
59f4fdebc0 Check the result of dirfd() before calling unlinkat()
Instead of directly using the result of dirfd() in the unlinkat() call,
check whether the returned file descriptor is actually valid.  That
doesn't really change the logic as the unlinkat() would fail with
invalid descriptor anyway, but this is cleaner and will report the right
error returned directly by dirfd() instead of EBADF from unlinkat().
2024-08-19 09:57:28 +00:00
Ondřej Surý
2fbf9757b8 Remove code to read and parse /proc/net/if_inet6 on Linux
The getifaddr() works fine for years, so we don't have to
keep the callback to parse /proc/net/if_inet6 anymore.
2024-08-19 09:42:55 +00:00
Ondřej Surý
dda5ba53df Ignore errno returned from rewind() in the interface iterator
The clang-scan 19 has reported that we are ignoring errno after the call
to rewind().  As we don't really care about the result, just silence the
error, the whole code will be removed in the development version anyway
as it is not needed.
2024-08-19 09:42:55 +00:00
Ondřej Surý
122a142241 Use constexpr for NS_PER_SEC and friends constants
The contexpr introduced in C23 standard makes perfect sense to be used
instead of preprocessor macros - the symbols are kept, etc.  Define
ISC_CONSTEXPR to be `constexpr` for C23 and `static const` for the older
C standards.  Use the newly introduced macro for the NS_PER_SEC and
friends time constants.
2024-08-19 09:08:55 +00:00
Ondřej Surý
b03e90e0d4 Change the NS_PER_SEC (and friends) from enum to static const
New version of clang (19) has introduced a stricter checks when mixing
integer (and float types) with enums.  In this case, we used enum {}
as C17 doesn't have constexpr yet.  Change the time conversion constants
to be static const unsigned int instead of enum values.
2024-08-19 09:08:55 +00:00
Aram Sargsyan
656e04f48a Check if logconfig is NULL before using it in isc_log_doit()
Check if 'lctx->logconfig' is NULL before using it in isc_log_doit(),
because it's possible that isc_log_destroy() was already called, e.g.
when a 'call_rcu' function wants to log a message during shutdown.
2024-08-15 12:54:37 +00:00
Aydın Mercan
b330eb0af8 do not include config.h
The build system ensures it is always included for every source file.
2024-08-15 12:11:48 +00:00
Ondřej Surý
d00ff78a3e Change the placement of ctor/dtor attributes in the dst_api
Change the placement of the attributes to match the existing usage in
other places (after the declaration).
2024-08-14 15:30:18 +00:00
Ondřej Surý
3e4d153453 Skip already rehashed positions in the old hashmap table
When iterating through the old internal hashmap table, skip all the
nodes that have been already migrated to the new table.  We know that
all positions with index less than .hiter are NULL.
2024-08-14 15:19:04 +00:00
Ondřej Surý
acdc57259f Fix the assertion failure in the isc_hashmap iterator
When the round robin hashing reorders the map entries on deletion, we
were adjusting the iterator table size only when the reordering was
happening at the internal table boundary.  The iterator table size had
to be reduced by one to prevent seeing the entry that resized on
position [0] twice because it migrated to [iter->size - 1] position.

However, the same thing could happen when the same entry migrates a
second time from [iter->size - 1] to [iter->size - 2] position (and so
on) because the check that we are manipulating the entry just in the [0]
position was insufficient.  Instead of checking the position [pos == 0],
we now check that the [pos % iter->size == 0], thus ignoring all the
entries that might have moved back to the end of the internal table.
2024-08-14 15:19:04 +00:00
Ondřej Surý
86f1ec34dc Silence all warnings that stem from the default config
As we now setup the logging very early, parsing the default config would
always print warnings about experimental (and possibly deprecated)
options in the default config.  This would even mess with commands like
`named -V` and it is also wrong to warn users about using experimental
options in the default config, because they can't do anything about
this.  Add CFG_PCTX_NODEPRECATED and CFG_PCTX_NOEXPERIMENTAL options
that we can pass to cfg parser and silence the early warnings caused by
using experimental options in the default config.
2024-08-14 12:50:31 +00:00
Aydın Mercan
596903a6b7
use deterministic ecdsa for openssl >= 3.2
OpenSSL has added support for deterministic ECDSA (RFC 6979) with
version 3.2.

Use it by default as derandomization doesn't pose a risk for DNS
usecases and is allowed by FIPS 186-5.
2024-08-14 14:34:44 +03:00
Aram Sargsyan
730fd32ee6 Reconfigure catz member zones during named reconfiguration
During a reconfiguration named doesn't reconfigure catalog zones
member zones. Implement the necessary code to reconfigure catz
member zones.
2024-08-13 16:22:58 +02:00
Ondřej Surý
8e86e55af1
Don't skip the counting if fcount_incr() is called with force==true (v2)
The fcount_incr() was not increasing counter->count when force was set
to true, but fcount_decr() would try to decrease the counter leading to
underflow and assertion failure.  Swap the order of the arguments in the
condition, so the !force is evaluated after incrementing the .count.
2024-08-13 12:51:22 +02:00
Ondřej Surý
39aef50b9b
Move the dst__openssl_toresult to isc_tls unit
Since the enable_fips_mode() now resides inside the isc_tls unit, BIND 9
would fail to compile when FIPS mode was enabled as the DST subsystem
logging functions were missing.

Move the crypto library logging functions from the openssl_link unit to
isc_tls unit and enhance it, so it can now be used from both places
keeping the old dst__openssl_toresult* macros alive.
2024-08-08 11:59:41 +02:00
Evan Hunt
104f3b82fb implement 'max-query-restarts'
implement, document, and test the 'max-query-restarts' option
which specifies the query restart limit - the number of times
we can follow CNAMEs before terminating resolution.
2024-08-07 13:20:05 -07:00
Evan Hunt
7e3b425dc2 reduce the max-recursion-queries default to 32
the number of iterative queries that can be sent to resolve a
name now defaults to 32 rather than 100.
2024-08-07 13:19:57 -07:00
Evan Hunt
c5588babaf make "max_restarts" a configurable value
MAX_RESTARTS is no longer hard-coded; ns_server_setmaxrestarts()
and dns_client_setmaxrestarts() can now be used to modify the
max-restarts value at runtime. in both cases, the default is 11.
2024-08-07 13:03:08 -07:00
Evan Hunt
05d78671bb reduce MAX_RESTARTS to 11
the number of steps that can be followed in a CNAME chain
before terminating the lookup has been reduced from 16 to 11.
(this is a hard-coded value, but will be made configurable later.)
2024-08-07 13:00:42 -07:00
Evan Hunt
825f3d68c5 add debug logging when creating or attaching to a query counter
fctx_create() now logs at debug level 9 when the fctx attaches
to an existing counter or creates a new one.
2024-08-07 11:21:44 -07:00
Evan Hunt
af7db89513 apply max-recursion-queries quota to validator queries
previously, validator queries for DNSKEY and DS records were
not counted toward the quota for max-recursion-queries; they
are now.
2024-08-07 11:21:44 -07:00
Evan Hunt
d3b7e92783 attach query counter to NS fetches
there were cases in resolver.c when queries for NS records were
started without passing a pointer to the parent fetch's query counter;
as a result, the max-recursion-queries quota for those queries started
counting from zero, instead of sharing the limit for the parent fetch,
making the quota ineffective in some cases.
2024-08-07 11:21:44 -07:00
Aydın Mercan
f58ed932d8
use only c23 or c11 noreturn specifiers
Since we require C11 or greater, we can depend on using either _Noreturn
or [[noreturn]].
2024-08-07 18:27:40 +03:00
Ondřej Surý
e6f2f2a5e6
Initialize the DST subsystem implicitly
Instead of calling dst_lib_init() and dst_lib_destroy() explicitly by
all the programs, create a separate memory context for the DST subsystem
and use the library constructor and destructor to initialize the DST
internals.
2024-08-07 17:03:27 +02:00
Ondřej Surý
c11b736e44 Disassociate the SSL object from the cached SSL_SESSION
When the SSL object was destroyed, it would invalidate all SSL_SESSION
objects including the cached, but not yet used, TLS session objects.

Properly disassociate the SSL object from the SSL_SESSION before we
store it in the TLS session cache, so we can later destroy it without
invalidating the cached TLS sessions.

Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
Co-authored-by: Aram Sargsyan <aram@isc.org>
2024-08-07 14:25:11 +00:00
Ondřej Surý
684f3eb8e6 Attach/detach to the listening child socket when accepting TLS
When TLS connection (TLSstream) connection was accepted, the children
listening socket was not attached to sock->server and thus it could have
been freed before all the accepted connections were actually closed.

In turn, this would cause us to call isc_tls_free() too soon - causing
cascade errors in pending SSL_read_ex() in the accepted connections.

Properly attach and detach the children listening socket when accepting
and closing the server connections.
2024-08-07 14:17:43 +00:00
Ondřej Surý
495cf18c75
Remove checks for OPENSSL_API_LEVEL define
Since the support for OpenSSL Engines has been removed, we can now also
remove the checks for OPENSSL_API_LEVEL; The OpenSSL 3.x APIs will be
used when compiling with OpenSSL 3.x, and OpenSSL 1.1.xx APIs will be
used only when OpenSSL 1.1.x is used.
2024-08-06 15:17:48 +02:00
Ondřej Surý
ef7aba7072
Remove OpenSSL Engine support
The OpenSSL 1.x Engines support has been deprecated in the OpenSSL 3.x
and is going to be removed.  Remove the OpenSSL Engine support in favor
of OpenSSL Providers.
2024-08-06 15:17:48 +02:00
Ondřej Surý
5beae5faf9
Fix the glue table in the QP and RBT zone databases
When adding glue to the header, we add header to the wait-free stack to
be cleaned up later which sets wfc_node->next to non-NULL value.  When
the actual cleaning happens we would only cleanup the .glue_list, but
since the database isn't locked for the time being, the headers could be
reused while cleaning the existing glue entries, which creates a data
race between database versions.

Revert the code back to use per-database-version hashtable where keys
are the node pointers.  This allows each database version to have
independent glue cache table that doesn't affect nodes or headers that
could already "belong" to the future database version.
2024-08-05 15:36:54 +02:00
Evan Hunt
6b720bfe1a minor findnode optimization
when searching the cache for a node so that we can delete an
rdataset, it is not necessary to set the 'create' flag. if the
node doesn't exist yet, we then we won't be able to delete
anything from it anyway.
2024-08-05 13:36:41 +00:00
Evan Hunt
a68a77ca86 dns_difftuple_create() cannot fail
dns_difftuple_create() could only return success, so change
its type to void and clean up all the calls to it.

other functions that only returned a result value because of it
have been cleaned up in the same way.
2024-08-05 13:31:38 +00:00
Evan Hunt
a84d54c6ff
raise the log level of priming failures
when a priming query is complete, it's currently logged at
level ISC_LOG_DEBUG(1), regardless of success or failure. we
are now raising it to ISC_LOG_NOTICE in the case of failure.
2024-08-05 13:56:13 +02:00
Aydın Mercan
2a76352b37 fix the rsa exponent to 65537
There isn't a realistic reason to ever use e = 4294967297. Fortunately
its codepath wasn't reachable to users and can be safetly removed.

Keep in mind the `dns_key_generate` header comment was outdated. e = 3
hasn't been used since 2006 so there isn't a reason to panic. The
toggle was the public exponents between 65537 and 4294967297.
2024-08-05 11:21:59 +00:00
Aydın Mercan
5dbb560747 remove the crc64 implementation
CRC-64 has been added for map files. Now that the map file format has
been removed, there isn't a reason to keep the implementation.
2024-08-05 11:21:25 +00:00
Ondřej Surý
13941c8ca7 Call rcu_barrier() in the isc_mem_destroy() just once
The previous work in this area was led by the belief that we might be
calling call_rcu() from within call_rcu() callbacks.  After carefully
checking all the current callback, it became evident that this is not
the case and the problem isn't enough rcu_barrier() calls, but something
entirely else.

Call the rcu_barrier() just once as that's enough and the multiple
rcu_barrier() calls will not hide the real problem anymore, so we can
find it.
2024-08-05 10:24:47 +00:00
Ondřej Surý
8ccfbcfe72 Remove no longer needed OpenSSL shims and checks
Since the minimal OpenSSL version is now OpenSSL 1.1.1, remove all kind
of OpenSSL shims and checks for functions that are now always present in
the OpenSSL libraries.

Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Aydın Mercan <aydin@isc.org>
2024-08-05 10:23:59 +00:00
Ondřej Surý
37dbd57c16
Fix the assertion failure when putting 48-bit number to buffer
When putting the 48-bit number into a fixed-size buffer that's exactly 6
bytes, the assertion failure would occur as the 48-bit number is
internally represented as 64-bit number and the code was checking if
there is enough space for `sizeof(val)`.  This causes assertion failure
when otherwise valid TSIG signature has a bad timing information.

Specify the size of the argument explicitly, so the 48-bit number
doesn't require 8-byte long buffer.
2024-08-05 09:55:18 +02:00
Ondřej Surý
a513d4c07f Don't skip the counting if fcount_incr() is called with force==true
The fcount_incr() was incorrectly skipping the accounting for the
fetches-per-zone if the force argument was set to true.  We want to skip
the accounting only when the fetches-per-zone is completely disabled,
but for individual names we need to do the accounting even if we are
forcing the result to be success.
2024-08-05 07:33:20 +00:00
Ondřej Surý
827a153d99 Remove superfluous memset() in isc_nmsocket_init()
The tlsstream part of the isc_nmsocket_t gets initialized via designater
initializer and doesn't need the extra memset() later; just remove it.
2024-08-05 07:32:12 +00:00
Ondřej Surý
cc4f99bc6d Fix PTHREAD_MUTEX_ADAPTIVE_NP and PTHREAD_MUTEX_ERRORCHECK_NP usage
The PTHREAD_MUTEX_ADAPTIVE_NP and PTHREAD_MUTEX_ERRORCHECK_NP are
usually not defines, but enum values, so simple preprocessor check
doesn't work.

Check for PTHREAD_MUTEX_ADAPTIVE_NP from the autoconf AS_COMPILE_IFELSE
block and define HAVE_PTHREAD_MUTEX_ADAPTIVE_NP.  This should enable
adaptive mutex on Linux and FreeBSD.

As PTHREAD_MUTEX_ERRORCHECK actually comes from POSIX and Linux glibc
does define it when compatibility macros are being set, we can just use
PTHREAD_MUTEX_ERRORCHECK instead of PTHREAD_MUTEX_ERRORCHECK_NP.
2024-08-05 07:31:39 +00:00
Ondřej Surý
f158884344 Remove ISC_MUTEX_INITIALIZER
It's hard to get it right on different platforms and it's unused
in BIND 9 anyway.
2024-08-05 07:31:39 +00:00
Ondřej Surý
b26079fdaf Don't open route socket if we don't need it
When automatic-interface-scan is disabled, the route socket was still
being opened.  Add new API to connect / disconnect from the route socket
only as needed.

Additionally, move the block that disables periodic interface rescans to
a place where it actually have access to the configuration values.
Previously, the values were being checked before the configuration was
loaded.
2024-08-05 07:31:02 +00:00
Ondřej Surý
912eaf6cb9 Clarify that cds_wfcq_dequeue_blocking() doesn't block if empty 2024-08-05 07:30:10 +00:00
Mark Andrews
47338c2c87 Remove unnecessary operations
Decrementing optlen immediately before calling continue is unneccesary
and inconsistent with the rest of dns_message_pseudosectiontoyaml
and dns_message_pseudosectiontotext.  Coverity was also reporting
an impossible false positive overflow of optlen (CID 499061).

    4176                        } else if (optcode == DNS_OPT_CLIENT_TAG) {
    4177                                uint16_t id;
    4178                                ADD_STRING(target, "; CLIENT-TAG:");
    4179                                if (optlen == 2U) {
    4180                                        id = isc_buffer_getuint16(&optbuf);
    4181                                        snprintf(buf, sizeof(buf), " %u\n", id);
    4182                                        ADD_STRING(target, buf);

    CID 499061: (#1 of 1): Overflowed constant (INTEGER_OVERFLOW)
    overflow_const: Expression optlen, which is equal to 65534, underflows
    the type that receives it, an unsigned integer 16 bits wide.
    4183                                        optlen -= 2;
    4184                                        POST(optlen);
    4185                                        continue;
    4186                                }
    4187                        } else if (optcode == DNS_OPT_SERVER_TAG) {
2024-08-02 03:44:04 +00:00
Aram Sargsyan
5f47c2b567 Allow shorter resolver-query-timeout configuration
There are use cases for which shorter timeout values make sense.
For example if there is a load balancer which sets RD=1 and
forwards queries to a BIND resolver which is then configured to
talk to backend servers which are not visible in the public NS set.
WIth a shorter timeout value the frontend can give back SERVFAIL
early when backends are not available and the ultimate client will
not penalize the BIND-frontend for non-response.
2024-08-01 18:30:35 +00:00
Aram Sargsyan
63b8a75de9 Rename dns_zone_forcereload() to dns_zone_forcexfr()
The new name describes the function more accurately.
2024-08-01 11:01:17 +00:00
Aram Sargsyan
3d1179501a Make dns_xfrin_shutdown() safe to run from a different loop
If the current loop is different than the zone transfer's loop then
run the shutdown operation asynchronously.
2024-08-01 10:43:47 +00:00
Aram Sargsyan
402ca316ae Implement rndc retransfer -force
With this new optional argument if there is an ongoing zone
transfer it will be aborted before a new zone transfer is scheduled.
2024-08-01 10:43:47 +00:00
Aram Sargsyan
b156531b29 Do not automatically restart a canceled zone transfer
If a zone transfer is canceled there is no need to try the
next primary or retry with AXFR.
2024-08-01 10:43:47 +00:00
Mark Andrews
bca63437a1 Add missing period to generated IPv4 6to4 name
The period between the most significant nibble of the IPv4 address
and the 2.0.0.2.IP6.ARPA suffix was missing resulting in the wrong
name being checked.
2024-08-01 15:17:30 +10:00
Mark Andrews
6d1c7beb15 Cleanup old clang-format string splitting 2024-08-01 14:17:57 +10:00
Mark Andrews
f78beca942 Remove false positive qname minimisation error
Don't report qname minimisation NXDOMAIN errors when the result is
NXDOMAIN.
2024-08-01 14:17:57 +10:00
Mark Andrews
393d7fa78e Fix yaml output
In yaml mode we emit a string for each question and record.  Certain
names and data could result in invalid yaml being produced.  Use single
quote string for all questions and records.  This requires that single
quotes get converted to two quotes within the string.
2024-08-01 12:30:57 +10:00
Mark Andrews
b51c9eb797 Properly reject zero length ALPN in commatxt_fromtext
ALPN are defined as 1*255OCTET in RFC 9460.  commatxt_fromtext was not
rejecting invalid inputs produces by missing a level of escaping
which where later caught be dns_rdata_fromwire on reception.

These inputs should have been rejected

	svcb in svcb 1 1.svcb alpn=\,abc
	svcb1 in svcb 1 1.svcb alpn=a\,\,abc

and generated 00 03 61 62 63 and 01 61 00 02 61 62 63 respectively.

The correct inputs to include commas in the alpn requires double
escaping.

	svcb in svcb 1 1.svcb alpn=\\,abc
	svcb1 in svcb 1 1.svcb alpn=a\\,\\,abc

and generate 04 2C 61 62 63 and 06 61 2C 2C 61 62 63 respectively.
2024-08-01 10:20:55 +10:00
Aram Sargsyan
cb5238cc62 Replace #define DNS_GETDB_ with struct of bools
This makes it easier to pretty-print the attributes in a debugger.
2024-07-31 11:52:52 +00:00
Aram Sargsyan
b621f1d88e Return SERVFAIL for a too long CNAME chain
Due to the maximum query restart limitation a long CNAME chain
it is cut after 16 queries but named still returns NOERROR.

Return SERVFAIL instead and the partial answer.
2024-07-31 10:54:10 +00:00
Mark Andrews
48d39f7c30 Check that FILE_STREAM(channel) is not already closed
isc_log_closefilelogs can also close log files.  isc_log_doit failed
to check if the file handle was still valid before closing it.
2024-07-31 17:36:38 +10:00
Mark Andrews
e8dbc5db92 Properly compute the physical memory size
On a 32 bit machine casting to size_t can still lead to an overflow.
Cast to uint64_t.  Also detect all possible negative values for
pages and pagesize to silence warning about possible negative value.

    39#if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE)
    	1. tainted_data_return: Called function sysconf(_SC_PHYS_PAGES),
           and a possible return value may be less than zero.
    	2. assign: Assigning: pages = sysconf(_SC_PHYS_PAGES).
    40        long pages = sysconf(_SC_PHYS_PAGES);
    41        long pagesize = sysconf(_SC_PAGESIZE);
    42
    	3. Condition pages == -1, taking false branch.
    	4. Condition pagesize == -1, taking false branch.
    43        if (pages == -1 || pagesize == -1) {
    44                return (0);
    45        }
    46
    	5. overflow: The expression (size_t)pages * pagesize might be negative,
           but is used in a context that treats it as unsigned.

    CID 498034: (#1 of 1): Overflowed return value (INTEGER_OVERFLOW)
    6. return_overflow: (size_t)pages * pagesize, which might have underflowed,
       is returned from the function.
    47        return ((size_t)pages * pagesize);
    48#endif /* if defined(_SC_PHYS_PAGES) && defined(_SC_PAGESIZE) */
2024-07-31 05:55:30 +00:00
Mark Andrews
53a5f50e9d Do not update find.result_v4 and find.result_v6
These values are supposed to be static for the life of the find and
clean_finds_at_name was updating them resulting in TSAN error
reports.

    WARNING: ThreadSanitizer: data race
    Write of size 4 at 0x000000000001 by thread T1 (mutexes: write M1, write M2):
      #0 clean_finds_at_name lib/dns/adb.c:1537
      #1 fetch_callback lib/dns/adb.c:4009
      #2 task_run lib/isc/task.c:815
      #3 isc_task_run lib/isc/task.c:896
      #4 isc__nm_async_task netmgr/netmgr.c:848
      #5 process_netievent netmgr/netmgr.c:920
      #6 process_queue netmgr/netmgr.c:1013
      #7 process_all_queues netmgr/netmgr.c:767
      #8 async_cb netmgr/netmgr.c:796
      #9 uv__async_io /usr/src/libuv-v1.44.1/src/unix/async.c:163
      #10 isc__trampoline_run lib/isc/trampoline.c:189

    Previous read of size 4 at 0x000000000001 by thread T2:
      #0 findname lib/dns/resolver.c:3749
      #1 fctx_getaddresses lib/dns/resolver.c:3993
      #2 fctx_try lib/dns/resolver.c:4390
      #3 rctx_nextserver lib/dns/resolver.c:10356
      #4 rctx_done lib/dns/resolver.c:10503
      #5 resquery_response lib/dns/resolver.c:8511
      #6 udp_recv lib/dns/dispatch.c:638
      #7 isc__nm_async_readcb netmgr/netmgr.c:2885
      #8 isc__nm_readcb netmgr/netmgr.c:2858
      #9 udp_recv_cb netmgr/udp.c:650
      #10 isc__nm_udp_read_cb netmgr/udp.c:1057
      #11 uv__udp_recvmsg /usr/src/libuv-v1.44.1/src/unix/udp.c:303
      #12 isc__trampoline_run lib/isc/trampoline.c:189
2024-07-31 14:46:45 +10:00
Mark Andrews
14a76ae498 Log key calculation overflows 2024-07-30 10:58:54 +02:00
Mark Andrews
25845a866e Check for overflow when adding lifetime 2024-07-30 10:58:54 +02:00
Matthijs Mekking
129973ebb0 No longer update key lifetime if key is retired
The key lifetime should no longer be adjusted if the key is being
retired earlier, for example because a manual rollover was started.

This would falsely be seen as a dnssec-policy lifetime reconfiguration,
and would adjust the retire/removed time again.

This also means we should update the status output, and the next
rollover scheduled is now calculated using (retire-active) instead of
key lifetime.
2024-07-30 10:57:14 +02:00
Matthijs Mekking
1cec0b0448 Update key lifetime and metadata after reconfig
If dnssec-policy is reconfigured and the key lifetime has changed,
update existing keys with the new lifetime and adjust the retire
and removed timing metadata accordingly.

If the key has no lifetime yet, just initialize the lifetime. It
may be that the retire/removed timing metadata has already been set.

Skip keys which goal is not set to omnipresent. These keys are already
in the progress of retiring, or still unused.
2024-07-30 10:57:14 +02:00
Artem Boldariev
5781ff3a93 Drop expired but not accepted TCP connections
This commit ensures that we are not attempting to accept an expired
TCP connection as we are not interested in any data that could have
been accumulated in its internal buffers. Now we just drop them for
good.
2024-07-03 15:03:02 +03:00
Ondřej Surý
bf9fd2a6ff
Reset the TCP connection on a failed send
When sending fails, the ns__client_request() would not reset the
connection and continue as nothing is happening.  This comes from the
model that we don't care about failed UDP sends because datagrams are
unreliable anyway, but it greatly affects TCP connections with
keep-alive.

The worst case scenario is as follows:

1. the 3-way TCP handshake gets completed
2. the libuv calls the "uv_connection_cb" callback
3. the TCP connection gets queue because of the tcp-clients quota
4. the TCP client sends as many DNS messages as the buffers allow
5. the TCP connection gets dropped by the client due to the timeout
6. the TCP connection gets accepted by the server
7. the data already sent by the client gets read
8. all sending fails immediately because the TCP connection is dead
9. we consume all the data in the buffer in a very tight loop

As it doesn't make sense to trying to process more data on the TCP
connection when the sending is failing, drop the connection immediately
on the first sending error.
2024-07-03 09:07:20 +02:00
Ondřej Surý
1c0564d715
Remove ns_query_init() cannot fail, remove the error paths
As ns_query_init() cannot fail now, remove the error paths, especially
in ns__client_setup() where we now don't have to care what to do with
the connection if setting up the client could fail.  It couldn't fail
even before, but now it's formal.
2024-07-03 09:05:51 +02:00
Ondřej Surý
bc3e713317
Throttle the reading when writes are asynchronous
Be more aggressive when throttling the reading - when we can't send the
outgoing TCP synchronously with uv_try_write(), we start throttling the
reading immediately instead of waiting for the send buffers to fill up.

This should not affect behaved clients that read the data from the TCP
on the other end.
2024-07-03 08:45:39 +02:00
Ondřej Surý
57cd34441a
Be smarter about refusing to add many RR types to the database
Instead of outright refusing to add new RR types to the cache, be a bit
smarter:

1. If the new header type is in our priority list, we always add either
   positive or negative entry at the beginning of the list.

2. If the new header type is negative entry, and we are over the limit,
   we mark it as ancient immediately, so it gets evicted from the cache
   as soon as possible.

3. Otherwise add the new header after the priority headers (or at the
   head of the list).

4. If we are over the limit, evict the last entry on the normal header
   list.
2024-07-01 12:48:51 +02:00
Ondřej Surý
b27c6bcce8
Expand the list of the priority types and move it to db_p.h
Add HTTPS, SVCB, SRV, PTR, NAPTR, DNSKEY and TXT records to the list of
the priority types that are put at the beginning of the slabheader list
for faster access and to avoid eviction when there are more types than
the max-types-per-name limit.
2024-07-01 12:47:30 +02:00
Artem Boldariev
55b1a093ea
Do not un-throttle TCP connections on isc_nm_read()
Due to omission it was possible to un-throttle a TCP connection
previously throttled due to the peer not reading back data we are
sending.

In particular, that affected DoH code, but it could also affect other
transports (the current or future ones) that pause/resume reading
according to its internal state.
2024-06-12 13:44:37 +03:00
Mark Andrews
e52c2a654b
Clear qctx->zversion
Clear qctx->zversion when clearing qctx->zrdataset et al in
lib/ns/query.c:qctx_freedata.  The uncleared pointer could lead to
an assertion failure if zone data needed to be re-saved which could
happen with stale data support enabled.
2024-06-10 17:45:38 +02:00
Petr Špaček
9370acd3a7
Require local KEYs for SIG(0) verification
This is additional hardening. There is no known use-case for KEY RRs
from DNS cache and it potentially allows attackers to put weird keys
into cache.
2024-06-10 17:36:45 +02:00
Aram Sargsyan
d69fab1530
Mark SIG(0) quota settings as experimantal
A different solution in the future might be adopted depending
on feedback and other new information, so it makes sense to mark
these options as EXPERIMENTAL until we have more data.
2024-06-10 17:36:45 +02:00
Aram Sargsyan
54ddd848fe
Avoid running get_matching_view() asynchronously on an error path
Also create a new ns_client_async_reset() static function to decrease
code duplication.
2024-06-10 17:35:40 +02:00
Aram Sargsyan
7ca9bd6014
Limit the number of keys for SIG(0) message verification
Check at most two KEY RRs agains a SIG(0) signature. This should
limit potential abuse and at the same time allow key rollover.
2024-06-10 17:33:11 +02:00
Aram Sargsyan
70ff4a3f85
Run resolver message signature checking asynchronously 2024-06-10 17:33:11 +02:00
Aram Sargsyan
ad489c44df
Remove sig0checks-quota-maxwait-ms support
Waiting for a quota to appear complicates things and wastes
rosources on timer management. Just answer with REFUSE if
there is no quota.
2024-06-10 17:33:11 +02:00
Aram Sargsyan
f0cde05e06
Implement asynchronous view matching for SIG(0)-signed queries
View matching on an incoming query checks the query's signature,
which can be a CPU-heavy task for a SIG(0)-signed message. Implement
an asynchronous mode of the view matching function which uses the
offloaded signature checking facilities, and use it for the incoming
queries.
2024-06-10 17:33:10 +02:00
Aram Sargsyan
710bf9b938
Implement asynchronous message signature verification
Add support for using the offload threadpool to perform message
signature verifications. This should allow check SIG(0)-signed
messages without affecting the worker threads.
2024-06-10 17:33:10 +02:00
Aram Sargsyan
7f013ad05d
Remove dns_message_rechecksig()
This is a tiny helper function which is used only once and can be
replaced with two function calls instead. Removing this makes
supporting asynchronous signature checking less complicated.
2024-06-10 17:33:10 +02:00
Aram Sargsyan
c7f79a0353
Add a quota for SIG(0) signature checks
In order to protect from a malicious DNS client that sends many
queries with a SIG(0)-signed message, add a quota of simultaneously
running SIG(0) checks.

This protection can only help when named is using more than one worker
threads. For example, if named is running with the '-n 4' option, and
'sig0checks-quota 2;' is used, then named will make sure to not use
more than 2 workers for the SIG(0) signature checks in parallel, thus
leaving the other workers to serve the remaining clients which do not
use SIG(0)-signed messages.

That limitation is going to change when SIG(0) signature checks are
offloaded to "slow" threads in a future commit.

The 'sig0checks-quota-exempt' ACL option can be used to exempt certain
clients from the quota requirements using their IP or network addresses.

The 'sig0checks-quota-maxwait-ms' option is used to define a maximum
amount of time for named to wait for a quota to appear. If during that
time no new quota becomes available, named will answer to the client
with DNS_R_REFUSED.
2024-06-10 17:33:08 +02:00
Matthijs Mekking
c1ac8b6ad0
Log rekey failure as error if too many records
By default we log a rekey failure on debug level. We should probably
change the log level to error. We make an exception for when the zone
is not loaded yet, it often happens at startup that a rekey is
run before the zone is fully loaded.
2024-06-10 16:55:12 +02:00
Matthijs Mekking
82635e56d8
Log error when update fails
The new "too many records" error can make an update fail without the
error being logged. This commit fixes that.
2024-06-10 16:55:12 +02:00
Evan Hunt
7dd6b47ace
fix a memory leak that could occur when signing
when signatures were not added because of too many types already
existing at a node, the diff was not being cleaned up; this led to
a memory leak being reported at shutdown.
2024-06-10 16:55:12 +02:00
Ondřej Surý
52b3d86ef0
Add a limit to the number of RR types for single name
Previously, the number of RR types for a single owner name was limited
only by the maximum number of the types (64k).  As the data structure
that holds the RR types for the database node is just a linked list, and
there are places where we just walk through the whole list (again and
again), adding a large number of RR types for a single owner named with
would slow down processing of such name (database node).

Add a configurable limit to cap the number of the RR types for a single
owner.  This is enforced at the database (rbtdb, qpzone, qpcache) level
and configured with new max-types-per-name configuration option that
can be configured globally, per-view and per-zone.
2024-06-10 16:55:09 +02:00
Ondřej Surý
32af7299eb
Add a limit to the number of RRs in RRSets
Previously, the number of RRs in the RRSets were internally unlimited.
As the data structure that holds the RRs is just a linked list, and
there are places where we just walk through all of the RRs, adding an
RRSet with huge number of RRs inside would slow down processing of said
RRSets.

Add a configurable limit to cap the number of the RRs in a single RRSet.
This is enforced at the database (rbtdb, qpzone, qpcache) level and
configured with new max-records-per-type configuration option that can
be configured globally, per-view and per-zone.
2024-06-10 16:55:07 +02:00
Ondřej Surý
e28266bfbc
Remove the extra memory context with own arena for sending
The changes in this MR prevent the memory used for sending the outgoing
TCP requests to spike so much.  That strictly remove the extra need for
own memory context, and thus since we generally prefer simplicity,
remove the extra memory context with own jemalloc arenas just for the
outgoing send buffers.
2024-06-10 16:48:54 +02:00
Ondřej Surý
4c2ac25a95
Limit the number of DNS message processed from a single TCP read
The single TCP read can create as much as 64k divided by the minimum
size of the DNS message.  This can clog the processing thread and trash
the memory allocator because we need to do as much as ~20k allocations in
a single UV loop tick.

Limit the number of the DNS messages processed in a single UV loop tick
to just single DNS message and limit the number of the outstanding DNS
messages back to 23.  This effectively limits the number of pipelined
DNS messages to that number (this is the limit we already had before).
2024-06-10 16:48:54 +02:00
Ondřej Surý
452a2e6348
Replace the tcp_buffers memory pool with static per-loop buffer
As a single thread can process only one TCP send at the time, we don't
really need a memory pool for the TCP buffers, but it's enough to have
a single per-loop (client manager) static buffer that's being used to
assemble the DNS message and then it gets copied into own sending
buffer.

In the future, this should get optimized by exposing the uv_try API
from the network manager, and first try to send the message directly
and allocate the sending buffer only if we need to send the data
asynchronously.
2024-06-10 16:48:53 +02:00
Aram Sargsyan
982eab7de0
ns_client: reuse TCP send buffers
Constantly allocating, reallocating and deallocating 64K TCP send
buffers by 'ns_client' instances takes too much CPU time.

There is an existing mechanism to reuse the ns_clent_t structure
associated with the handle using 'isc_nmhandle_getdata/_setdata'
(see ns_client_request()), but it doesn't work with TCP, because
every time ns_client_request() is called it gets a new handle even
for the same TCP connection, see the comments in
streamdns_on_complete_dnsmessage().

To solve the problem, we introduce an array of available (unused)
TCP buffers stored in ns_clientmgr_t structure so that a 'client'
working via TCP can have a chance to reuse one (if there is one)
instead of allocating a new one every time.
2024-06-10 16:48:53 +02:00
Ondřej Surý
4e7c4af17f
Throttle reading from TCP if the sends are not getting through
When TCP client would not read the DNS message sent to them, the TCP
sends inside named would accumulate and cause degradation of the
service.  Throttle the reading from the TCP socket when we accumulate
enough DNS data to be sent.  Currently this is limited in a way that a
single largest possible DNS message can fit into the buffer.
2024-06-10 16:48:52 +02:00
Artem Boldariev
d80dfbf745
Keep the endpoints set reference within an HTTP/2 socket
This commit ensures that an HTTP endpoints set reference is stored in
a socket object associated with an HTTP/2 stream instead of
referencing the global set stored inside a listener.

This helps to prevent an issue like follows:

1. BIND is configured to serve DoH clients;
2. A client is connected and one or more HTTP/2 stream is
created. Internal pointers are now pointing to the data on the
associated HTTP endpoints set;
3. BIND is reconfigured - the new endpoints set object is created and
promoted to all listeners;
4. The old pointers to the HTTP endpoints set data are now invalid.

Instead referencing a global object that is updated on
re-configurations we now store a local reference which prevents the
endpoints set objects to go out of scope prematurely.
2024-06-10 16:40:12 +02:00
Artem Boldariev
c41fb499b9
DoH: avoid potential use after free for HTTP/2 session objects
It was reported that HTTP/2 session might get closed or even deleted
before all async. processing has been completed.

This commit addresses that: now we are avoiding using the object when
we do not need it or specifically check if the pointers used are not
'NULL' and by ensuring that there is at least one reference to the
session object while we are doing incoming data processing.

This commit makes the code more resilient to such issues in the
future.
2024-06-10 16:40:10 +02:00
Ondřej Surý
086b63f56d Use isc_queue to implement wait-free deadnodes queue
Replace the ISC_LIST based deadnodes implementation with isc_queue which
is wait-free and we don't have to acquire neither the tree nor node lock
to append nodes to the queue and the cleaning process can also
copy (splice) the list into a local copy without acquiring the list.

Currently, there's little benefit to this as we need to hold those
locks anyway, but in the future as we move to RCU based implementation,
this will be ready.

To align the cleaning with our event loop based model, remove the
hardcoded count for the node locks and use the number of the event loops
instead.  This way, each event loop can have its own cleaning as part of
the process.  Use uniform random numbers to spread the nodes evenly
between the buckets (instead of hashing the domain name).
2024-06-05 09:19:56 +02:00
Ondřej Surý
a9b4d42346 Add isc_queue implementation on top of cds_wfcq
Add an isc_queue implementation that hides the gory details of cds_wfcq
into more neat API.  The same caveats as with cds_wfcq.

TODO: Add documentation to the API.
2024-06-05 09:19:56 +02:00
Mark Andrews
56c3dcc5d7 Update resquery_senddone handling of ISC_R_TIMEDOUT
Treat timed out as an address specific error.
2024-06-04 00:15:48 +10:00
Mark Andrews
4e3dd85b8d Update resquery_senddone handling of ISC_R_CONNECTIONRESET
Treat connection reset as an address specific error.
2024-06-04 00:15:48 +10:00
Mark Andrews
180b1e7939 Handle ISC_R_HOSTDOWN and ISC_R_NETDOWN in resolver.c
These error codes should be treated like other unreachable error
codes.
2024-06-04 00:15:48 +10:00
Mark Andrews
05472e63e8 Don't do DS checks over disabled address families 2024-06-03 18:34:31 +10:00
Mark Andrews
d026dbe536 Don't forward UPDATE messages over disabled address families 2024-06-03 18:34:31 +10:00
Mark Andrews
5d99625515 Don't send NOTIFY over disabled address families 2024-06-03 18:34:31 +10:00
Mark Andrews
2cd4303249 Report non-effective primaries
When named is started with -4 or -6 and the primaries for a zone
do not have an IPv4 or IPv6 address respectively issue a log message.
2024-06-03 18:34:31 +10:00
Mark Andrews
ecdde04e63 Zone transfers should honour -4 and -6 options
Check if the address family has been disabled when transferring
zones.
2024-06-03 18:34:31 +10:00
Mark Andrews
9be1873ef3 Add helper function isc_sockaddr_disabled 2024-06-03 18:34:31 +10:00
Matthijs Mekking
c40e5c8653 Call reset_shutdown if uv_tcp_close_reset failed
If uv_tcp_close_reset() returns an error code, this means the
reset_shutdown callback has not been issued, so do it now.
2024-06-03 10:14:47 +02:00
Matthijs Mekking
5b94bb2129 Do not runtime check uv_tcp_close_reset
When we reset a TCP connection by sending a RST packet, do not bother
requiring the result is a success code.
2024-06-03 10:14:47 +02:00
Mark Andrews
87e3b9dbf3 Pass a memory context in to dns_cache_create 2024-05-31 15:40:32 +10:00
Mark Andrews
5e77edd074 Use a new memory context when flushing the cache
When the cache's memory context was in over memory state when the
cache was flushed it resulted in LRU cleaning removing newly entered
data in the new cache straight away until the old cache had been
destroyed enough to take it out of over memory state.  When flushing
the cache create a new memory context for the new db to prevent this.
2024-05-31 15:40:32 +10:00
Ondřej Surý
3310cac2b0
Create the new database for AXFR from the dns_zone API
The `axfr_makedb()` didn't set the loop on the newly created database,
effectively killing delayed cleaning on such database.  Move the
database creation into dns_zone API that knows all the gory details of
creating new database suitable for the zone.
2024-05-29 08:30:19 +02:00
Aram Sargsyan
4d3c31b928
fixup! Merge branch 'ondrej/light-cleanup-of-rdataslab' into 'main' 2024-05-25 11:47:33 +02:00
Ondřej Surý
3feabc8a22
Cleanup the dns_cache unit
Remove duplicate code and use ISC_REFCOUNT_{DECL,IMPL} macros.
2024-05-25 11:47:33 +02:00
Ondřej Surý
03ed19cf71
Refactor the common buffer manipulation in rdataslab.c in macros
The rdataslab.c was full of code like this:

        length = raw[0] * 256 + raw[1];

and

        count2 = *current2++ * 256;
        count2 += *current2++;

Refactor code like this into peek_uint16() and get_uint16 macros
to prevent code repetition and possible mistakes when copy and
pasting the same code over and over.

As a side note for an entertainment of a careful reader of the commit
messages: The byte manipulation was changed from multiplication and
addition to shift with or.

The difference in the assembly looks like this:

MUL and ADD:

	movzx   eax, BYTE PTR [rdi]
        movzx   edi, BYTE PTR [rdi+1]
        sal     eax, 8
        or      edi, eax

SHIFT and OR:

        movzx   edi, WORD PTR [rdi]
        rol     di, 8
        movzx   edi, di

If the result and/or buffer is then being used after the macro call,
there's more differences in favor of the SHIFT+OR solution.
2024-05-24 09:52:45 +02:00
Aydın Mercan
03a59cbb04 reinsert accidentally removed + in db trace
It only affects development when using `DNS_DB_TRACE`.
2024-05-17 18:11:23 -07:00
Aydın Mercan
49e62ee186 fix typing mistakes in trace macros
The detach function declaration in `ISC__REFCOUNT_TRACE_DECL` had an
returned an accidental implicit int. While not allowed since C99, it
became an error by default in GCC 14.

`ISC_REFCOUNT_TRACE_IMPL` and `ISC_REFCOUNT_STATIC_TRACE_IMPL` expanded
into the wrong macros, trying to declare it again with the wrong number
of parameters.
2024-05-17 18:11:23 -07:00
Mark Andrews
b7de2c7cb9 Clang-format header file changes 2024-05-17 16:03:21 -07:00
Mark Andrews
6e9ed4983e add test cases for several FORMERR code paths:
- duplicated question
  - duplicated answer
  - qtype as an answer
  - two question types
  - question names
  - nsec3 bad owner name
  - short record
  - short question
  - mismatching question class
  - bad record owner name
  - mismatched class in record
  - mismatched KEY class
  - OPT wrong owner name
  - invalid RRSIG "covers" type
  - UPDATE malformed delete type
  - TSIG wrong class
  - TSIG not the last record
2024-05-17 13:39:22 +10:00
Evan Hunt
9c882f1e69 replace qpzone node attriutes with atomics
there were TSAN error reports because of conflicting uses of
node->dirty and node->nsec, which were in the same qword.

this could be resolved by separating them, but we could also
make them into atomic values and remove some node locking.
2024-05-17 00:33:35 +00:00
Matthijs Mekking
f882101265 Rewrite qp fix_iterator()
The fix_iterator() function had a lot of bugs in it and while fixing
them, the number of corner cases and the complexity of the function
got out of hand. Rewrite the function with the following modifications:

The function now requires that the iterator is pointing to a leaf node.
This removes the cases we have to deal when the iterator was left on a
dead branch.

From the leaf node, pop up the iterator stack until we encounter the
branch where the offset point is before the point where the search key
differs. This will bring us to the right branch, or at the first
unmatched node, in which case we pop up to the parent branch. From
there it is easier to retrieve the predecessor.

Once we are at the right branch, all we have to do is find the right
twig (which is either the twig for the character at the position where
the search key differs, or the previous twig) and walk down from there
to the greatest leaf or, in case there is no good twig, get the
previous twig from the successor and get the greatest leaf from there.

If there is no previous twig to select in this branch, because every
leaf from this branch node is greater than the one we wanted, we need
to pop up the stack again and resume at the parent branch. This is
achieved by calling prevleaf().
2024-05-16 09:49:41 +00:00
Matthijs Mekking
8b8c16d7a4 Get anyleaf when qp lookup is on a dead end branch
Move the fix_iterator out of the loop and only call it when we found
a leaf node. This leaf node may be the wrong leaf node, but fix_iterator
should correct that.

Also, when we don't need to set the iterator, just get any leaf. We
only need to have a leaf for the qpkey_compare and the end result does
not matter if compare was against an ancestor leaf or any leaf below
that point.
2024-05-16 09:49:41 +00:00
Mark Andrews
ec3c624814 Properly build the NSEC/NSEC3 type bit map
DNSKEY was incorrectly being added to the NESC/NSEC3 type bit map
when it was obscured by the delegation.  This lead to zone verification
failures.
2024-05-16 10:27:49 +10:00
Mark Andrews
e84615629f Properly update 'maxtype'
'maxtype' should be checked to see if it should be updated whenever
a type is added to the type map.
2024-05-16 10:20:49 +10:00
Ondřej Surý
eb862ce509
Properly attach/detach isc_httpd in case read ends earlier than send
An assertion failure would be triggered when sending the TCP data ends
after the TCP reading gets closed.  Implement proper reference counting
for the isc_httpd object.
2024-05-15 12:22:10 +02:00
Evan Hunt
b6815de316 Fix QP chain on partial match
When searching for a requested name in dns_qp_lookup(), we may add
a leaf node to the QP chain, then subsequently determine that the
branch we were on was a dead end. When that happens, the chain can be
left holding a pointer to a node that is *not* an ancestor of the
requested name.

We correct for this by unwinding any chain links with an offset
value greater or equal to that of the node we found.
2024-05-14 12:58:46 -07:00
Matthijs Mekking
91de4f6490 Refactor fix_iterator
The code below the if/else construction could only be run if the 'if'
code path was taken. Move the code into the 'if' code block so that
it is more easier to read.
2024-05-14 12:58:46 -07:00
Aydın Mercan
e037520b92
Keep track of the recursive clients highwater
The high-water allows administrators to better tune the recursive
clients limit without having to to poll the statistics channel in high
rates to get this number.
2024-05-10 12:08:52 +03:00
Aydın Mercan
09e4fb2ffa
Return the old counter value in isc_stats_increment
Returning the value allows for better high-water tracking without
running into edge cases like the following:

0. The counter is at value X
1. Increment the value (X+1)
2. The value is decreased multiple times in another threads (X+1-Y)
3. Get the value (X+1-Y)
4. Update-if-greater misses the X+1 value which should have been the
   high-water
2024-05-10 12:08:52 +03:00
Mark Andrews
88c48dde5e Stop processing catalog zone changes when shutting down
Abandon catz_addmodzone_cb  and catz_delzone_cb processing if the
loop is shutting down.
2024-05-09 08:17:44 +10:00
Mark Andrews
307e3ed9a6 catzs->view should maintain a view reference
Use dns_view_weakattach and dns_view_weakdetach to maintain a
reference to the view referenced through catzs->view.
2024-05-09 08:17:44 +10:00
Mark Andrews
799046929c Only check SVBC alias forms at higher levels
Allow SVBC (HTTPS) alias form with parameters to be accepted from
the wire and when transfered.  This is for possible future extensions.
2024-05-07 11:20:49 +10:00
Mark Andrews
efd27bb82d Remove infinite loop on ISC_R_NOFILE
When parsing a zonefile named-checkzone (and others) could loop
infinitely if a directory was $INCLUDED.  Record the error and treat
as EOF when looking for multiple errors.

This was found by Eric Sesterhenn from X41.
2024-05-07 10:01:12 +10:00
Mark Andrews
371824f078 Address infinite loop when processing $GENERATE
In nibble mode if the value to be converted was negative the parser
would loop forever.  Process the value as an unsigned int instead
of as an int to prevent sign extension when shifting.

This was found by Eric Sesterhenn from X41.
2024-05-07 09:19:43 +10:00
Matthijs Mekking
5d7e613e81 RPZ response's SOA record is incorrectly set to 1
An RPZ response's SOA record TTL is set to 1 instead of the SOA TTL,
a boolean value is passed on to query_addsoa, which is supposed to be
a TTL value. I don't see what value is appropriate to be used for
overriding, so we will pass UINT32_MAX.
2024-05-06 11:38:36 +02:00
Aram Sargsyan
8052848d50 Fix a bug in expireheader() call arguments order
The expireheader() call in the expire_ttl_headers() function
is erroneous as it passes the 'nlocktypep' and 'tlocktypep'
arguments in a wrong order, which then causes an assertion
failure.

Fix the order of the arguments so it corresponds to the function's
prototype.
2024-05-02 08:38:35 +00:00
Evan Hunt
f81bf6bafd handle QP lookups involving escaped characters better
in QP keys, characters that are not common in DNS names are
encoded as two-octet sequences. this caused a glitch in iterator
positioning when some lookups failed.

consider the case where we're searching for "\009" (represented
in a QP key as {0x03, 0x0c}) and a branch exists for "\000"
(represented as {0x03, 0x03}). we match on the 0x03, and continue
to search down. at the point where we find we have no match,
we need to pop back up to the branch before the 0x03 - which may
be multiple levels up the stack - before we position the iterator.
2024-05-01 00:36:51 -07:00
Evan Hunt
4b02246130 fix more ambiguous struct names
there were some structure names used in qpcache.c and qpzone.c that
were too similar to each other and could be confusing when debugging.
they have been changed as follows:

in qcache.c:
- changed_t was unused, and has been removed
- search_t -> qpc_search_t
- qpdb_rdatasetiter_t -> qpc_rditer_t
- qpdb_dbiterator_t -> qpc_dbiter_t

in qpzone.c:
- qpdb_changed_t -> qpz_changed_t
- qpdb_changedlist_t -> qpz_changedlist_t
- qpdb_version_t -> qpz_version_t
- qpdb_versionlist_t -> qpz_versionlist_t
- qpdb_search_t -> qpz_search_t
- qpdb_load_t -> qpz_search_t
2024-04-30 12:50:01 -07:00
Evan Hunt
e300dfce46 use dns_qp_getname() where possible
some calls to dns_qp_lookup() do not need partial matches, QP chains
or QP iterators. in these cases it's more efficient to use
dns_qp_getname().
2024-04-30 12:50:01 -07:00
Evan Hunt
2789e58473 get foundname from the node
when calling dns_qp_lookup() from qpcache, instead of passing
'foundname' so that a name would be constructed from the QP key,
we now just use the name field in the node data. this makes
dns_qp_lookup() run faster.

the same optimization has also been added to qpzone.

the documentation for dns_qp_lookup() has been updated to
discuss this performance consideration.
2024-04-30 12:50:01 -07:00
Evan Hunt
04d319afe4 include the nodenames when calculating memory to purge
when the cache is over memory, we purge from the LRU list until
we've freed the approximate amount of memory to be added. this
approximation could fail because the memory allocated for nodenames
wasn't being counted.

add a dns_name_size() function so we can look up the size of nodenames,
then add that to the purgesize calculation.
2024-04-30 12:50:01 -07:00
Evan Hunt
a8bda6ff1e simplify qpcache iterators
in a cache database, unlike zones, NSEC3 records are stored in
the main tree. it is not necessary to maintain a separate 'nsec3'
tree, nor to have code in the dbiterator implementation to traverse
from one tree to another.

(if we ever implement synth-from-dnssec using NSEC3 records, we'll
need to revert this change. in the meantime, simpler code is better.)
2024-04-30 12:50:01 -07:00
Evan Hunt
7ff43befb7 clean up unnecessary dbiterator code related to origin
the QP database doesn't support relative names as the RBTDB did, so
there's no need for a 'new_origin' flag or to handle `DNS_R_NEWORIGIN`
result codes.
2024-04-30 12:42:32 -07:00
Evan Hunt
85ab92b6e0 more cleanups in qpcache.c
- remove unneeded struct members and misleading comments.
- remove unused parameters for static functions.
- rename 'find_callback' to 'delegating' for consistency with qpzone;
  the find callback mechanism is not used in QP databases.
2024-04-30 12:42:31 -07:00
Evan Hunt
3acab71d46 rename QPDB_HEADERNODE to HEADERNODE
this makes the macro consistent between qpcache.c and qpzone.c.

also removed a redundant definition of HEADERNODE in qpzone.c.
2024-04-30 12:42:31 -07:00
Evan Hunt
46d40b3dca fix structure names in qpcache.c and qpzone.c
- change dns_qpdata_t to qpcnode_t (QP cache node), and dns_qpdb_t to
  qpcache_t, as these types are only accessed locally.
- also change qpdata_t in qpzone.c to qpznode_t (QP zone node), for
  consistency.
- make the refcount declarations for qpcnode_t and qpznode_t static,
  using the new ISC_REFCOUNT_STATIC macros.
2024-04-30 12:42:07 -07:00
Evan Hunt
20d32512ca clean up unnecessary requirements in qpcache.c
qpcache can only support cache semantics now, so there's
no longer any need to check for that internally.
2024-04-30 12:31:48 -07:00
Evan Hunt
a5d0e6c4ba add static macros for ISC_REFCOUNT_DECL/IMPL
this commit adds a mechanism to statically declare attach/detach
and ref/unref methods, for objects that are only accessed within
a single C file.
2024-04-30 12:31:48 -07:00
Ondřej Surý
c13a1d8b01
Improve the reference counting checks in newref()
In qpcache (and rbtdb), there are some functions that acquire
neither the tree lock nor the node lock when calling newref().
In theory, this could lead to a race in which a new reference
is added to a node that was about to be deleted.

We now detect this condition by passing the current tree and node
lock status to newref(). If the node was previously unreferenced
and we don't hold at least one read lock, we will assert.
2024-04-30 08:41:56 +02:00
Aydın Mercan
f30008a71c
Provide an early escape hatch for ns_client_transport_type
Because some tests don't have a legtimate handle, provide a temporary
return early that should be fixed and removed before squashing. This
short circuiting is still correct until DoQ/DoH3 support is introduced.
2024-04-26 16:12:29 +03:00
Aydın Mercan
b5478654a2
Add fallback to ns_client_get_type despite unreachable
GCC might fail to compile because it expects a return after UNREACHABLE.
It should ideally just work anyway since UNREACHABLE is either a
noreturn or UB (__builtin_unreachable / C23 unreachable).

Either way, it should be optimized almost always so the fallback is
free or basically free anyway when it isn't optimized out.
2024-04-26 16:12:29 +03:00
Aydın Mercan
4a3f7fe1ef
Emit and read correct DoT and DoH dnstap entries
Other protocols still pretend to be TCP/UDP.
This only causes a difference when using dnstap-read on a file with DoQ
or DNSCrypt entries
2024-04-26 16:12:29 +03:00
Aydın Mercan
9d1a8a98c6
Update the dnstap protobuf definition
The new definition includes the missing protocol definitions and
specifies the protobuf version.
2024-04-26 16:08:46 +03:00
Ondřej Surý
6c54337f52 avoid a race in the qpzone getsigningtime() implementation
the previous commit introduced a possible race in getsigningtime()
where the rdataset header could change between being found on the
heap and being bound.

getsigningtime() now looks at the first element of the heap, gathers the
locknum, locks the respective lock, and retrieves the header from the
heap again.  If the locknum has changed, it will rinse and repeat.
Theoretically, this could spin forever, but practically, it almost never
will as the heap changes on the zone are very rare.

we simplify matters further by changing the dns_db_getsigningtime()
API call. instead of passing back a bound rdataset, we pass back the
information the caller actually needed: the resigning time, owner name
and type of the rdataset that was first on the heap.
2024-04-25 15:48:43 -07:00
Evan Hunt
7e6be9f1b5 simplify qpzone database by using only one heap for resigning
in RBTDB, the heap was used by zone databases for resigning, and
by the cache for TTL-based cache cleaning. the cache use case required
very frequent updates, so there was a separate heap for each of the
node lock buckets.

qpzone is for zones only, so it doesn't need to support the cache
use case; the heap will only be touched when the zone is updated or
incrementally signed. we can simplify the code by using only a single
heap.
2024-04-25 15:41:39 -07:00
Evan Hunt
237123e500 simplify code by removing return values where possible
fix_iterator() and related functions are quite difficult to read.
perhaps it would be a little clearer if we didn't assign values
to variables that won't subsequently be used, or unnecessarily
pop the stack and then push the same value back onto it.

also, in dns_qp_lookup() we previously called fix_iterator(),
removed the leaf from the top of the iterator stack, and then
added it back on. this would be clearer if we just push the leaf
onto the stack when we need to, but leave the stack alone when
it's already complete.
2024-04-25 10:29:07 -07:00
Evan Hunt
66dbff596b clean up fix_iterator() arguments
the value passed as 'start' was redundant; it's always the same
as the current top of the iterator stack.
2024-04-25 10:29:07 -07:00
Evan Hunt
2dff926624 yet another fix_iterator() bug
under some circumstances it was possible for the iterator to
be set to the first leaf in a set of twigs, when it should have
been set to the last.

a unit test has been added to test this scenario. if there is a
a tree containing the following values: {".", "abb.", "abc."}, and
we query for "acb.", previously the iterator would be positioned at
"abb." instead of "abc.".

the tree structure is:
    branch (offset 1, ".")
      branch (offset 3, ".ab")
        leaf (".abb")
        leaf (".abc")

we find the branch with offset 3 (indicating that its twigs differ
from each other in the third position of the label, "abB" vs "abC").
but the search key differs from the found keys at position 2
("aC" vs "aB").  we look up the bit value in position 3 of the
search key ("B"), and incorrectly follow it onto the wrong twig
("abB").

to correct for this, we need to check for the case where the search
key is greater than the found key in a position earlier than the
branch offset. if it is, then we need to pop from the current leaf
to its parent, and get the greatest leaf from there.

a further change is needed to ensure that we don't do this twice;
when we've moved to a new leaf and the point of difference between
it and the search key even earlier than before, then we're definitely
at a predecessor node and there's no need to continue the loop.
2024-04-25 10:29:07 -07:00
Michal Nowak
f454fa6dea
Update sources to Clang 18 formatting 2024-04-23 13:11:52 +02:00
Ondřej Surý
141e4c9805
Change the ADB_ENTRY_WINDOW to 60 seconds
The previous value of 30 minutes used to cache the ADB names and entries
was quite long.  Change the value to 60 seconds for faster recovery
after cached intermittent failure of the remote nameservers.
2024-04-22 10:36:36 +02:00
Ondřej Surý
6708da3112
Unify the expiration time handling for all ADB expiration
The algorithm from the previous commit[1] is now used to calculate all
the expiration values through the code (ncache results, cname/dname
targets).

1. ISC_MIN(cur, ISC_MAX(now + ADB_ENTRY_WINDOW, now + rdataset->ttl))
2024-04-22 10:36:36 +02:00
Ondřej Surý
53cc00ee3f
Fix the expire_v4 and expire_v6 logic
Correct the logic to set the expiration period of expire_{v4,v6} as
follows:

1. If the trust is ultimate (local entry), immediately set the entry as
   expired, so the changes to the local zones have immediate effect.

3. If the expiration is already set and smaller than the new value, then
   leave the expiration value as it is.

2. Otherwise pick larger of `now + ADB_ENTRY_WINDOW` and `now + TTL` as
   the new expiration value.
2024-04-22 10:36:36 +02:00
Ondřej Surý
932665410d
Always set ADB entry expiration to now + ADB_ENTRY_WINDOW
When ADB entry was created it was set to never expire.  If we never
called any of the functions that adjust the expiration, it could linger
in the ADB forever.

Set the expiration (.expires) to now + ADB_ENTRY_WINDOW when creating
the new ADB entry to ensure the ADB entry will always expire.
2024-04-22 10:36:36 +02:00