Commit graph

16094 commits

Author SHA1 Message Date
Matthijs Mekking
a7021a3a51 Rename dns_qp_lookup2 back to dns_qp_lookup
Now that we have to code working, rename 'dns_qp_lookup2' back to
'dns_qp_lookup' and adjust all remaining 'dns_qp_lookup' occurrences
to take a space=0 parameter.
2025-07-10 13:52:59 +00:00
Matthijs Mekking
e052e14b40 Change denial type to enum
For now we only allow DNS_DB_NSEC_* values so it makes sense to change
the type to an enum.

Rename 'denial' to the more intuitive 'space', indicating the namespace
of the keyvalue pair.
2025-07-10 13:52:59 +00:00
Matthijs Mekking
61f8886fc3 Fix the dbiterator to assume only one qp-trie
The dbiterator can take three modes: full, nsec3only and nonsec3.
Previously, in full mode the dbiterator requires special logic to jump
from one qp-trie to the other. Now everything is in one trie, other
special logic is needed.

The qp-trie is now sorted in such a way that all the normal nodes come
first, followed by NSEC nodes, and finally the NSEC3 nodes. NSEC nodes
are empty nodes and need to be skipped when iterating.

We add an additional auxiliary node to the trie, an NSEC origin, so
we can easily find the point in the trie where we need to continue
iterating.
2025-07-10 13:52:59 +00:00
Matthijs Mekking
16a1c5a623 Prepend qpkey with denial byte
In preparation to merge the three qp tries (tree, nsec, nsec3) into
one, add the piece of information into the qpkey. This is the most
significant bit of information, so prepend the denial type to the qpkey.

This means we need to pass on the denial type when constructing the
qpkey from a name, or doing a lookup.

Reuse the the DNS_DB_NSEC_* values. Most qp tries in the code we just
pass on 0 (nta, rpz, zt, etc.), because there is no need for denial of
existence, but for qpzone and qpcache we must pass the right value.

Change the code, so that node->nsec no longer can have the value
DNS_DB_NSEC_HAS_NSEC, instead track this in a new attribute 'havensec'.

Since we use node->nsec to convert names to keys, the value MUST be set
before inserting the node into the qp-trie.

Update the fuzzing and unit tests accordingly. This only adds a few
extra test cases, more are needed.

In the qp_test.c we can remove test code for empty keys as this is
no longer possible.
2025-07-10 13:52:59 +00:00
Petr Špaček
0a5a25729c Remove unused DNS_RDATASET_COUNT
Albeit technically not unused, it was always defined as 0 and thus did
nothing.

Related: #4666
2025-07-10 11:17:19 +02:00
Petr Špaček
ba861f23f2 Remove unused DNS_RDATASET_ORDER
Related: #4666
2025-07-10 11:17:19 +02:00
Petr Špaček
ae600b0a95 Remove unused DNS_RDATASET_FIXED
There was no way to define this in the build system.

Related: #4666
2025-07-10 11:17:19 +02:00
Petr Špaček
750d8a61b6 Convert DNS_RDATASETATTR_ bitfield manipulation to struct of bools
RRset ordering is now an enum inside struct rdataset attributes. This
was done to keep size to of the structure to its original value before
this MR.

I expect zero performance impact but it should be easier to deal with
attributes in debuggers and language servers.
2025-07-10 11:17:19 +02:00
Aram Sargsyan
27e7961479 Log dropped or slipped responses in the query-errors category
As mentioned in the comments block before the changed code block,
the dropped or slipped responses should be logged in the query
category (or rather query-errors category as done in lib/ns/client.c),
so that requests are not silently lost.

Also fix a couple of errors/typos in the code comments.
2025-07-10 08:20:17 +00:00
Alessio Podda
e84704bd55 Improve efficiency of ns_client_t reset
The ns_client_t struct is reset and zero-ed out on every query,
but some fields (query, message, manager) are preserved.

We observe two things:
 - The sendbuf field is going to be overwritten anyway, there's
   no need to zero it out.
 - The fields are copied out when the struct is zero-ed out, and
   then copied back in. For the query field (which is 896 bytes)
   this is very inefficient.

This commit makes the reset more efficient avoiding to unnecessary
zero-ing and copy.
2025-07-10 07:19:47 +02:00
Ondřej Surý
cdeb8d1c14
Use cds_lfht for lock-free hashtables in dns_adb
Replace the read-write locked isc_hashmap with lock-free cds_lfht
hashtable and replace the singular LRU tables for ADB names and entries
with a per-thread LRU tables.  These changes allowed to remove all the
read-write locking on the names and entries tables.
2025-07-09 21:22:48 +02:00
Ondřej Surý
cca4b26d31
Use regular reference counting macro for isc_nm_t structure
Instead of having hand crafted attach/detach/destroy functions, replace
them with the standard ISC_REFCOUNT macro.  This also have advantage
that delayed netmgr detach (from dns_dispatch) now doesn't cause
assertion failure.  This can happen with delayed (call_rcu) shutdown of
dns_adb.
2025-07-09 21:22:48 +02:00
Ondřej Surý
51d7efbfb4
Print the memory context when printing overmem limits
When printing the memory context going into or out of the overmem
condition, also print the memory context name for easier debugging.
2025-07-09 21:22:48 +02:00
Ondřej Surý
7682bc21a9
Rewrite dns_adb LRU to SIEVE
The dns_adb cleaning is little bit muddled as it mixes the "TTL"
based cleaning (.expire_v4 and .expire_v6 for adbname, .expires for
adbentry) with overmem cleaning.

Rewrite the LRU based cleaning to use SIEVE algorithm and to be overmem
cleaning only with a requirement to always cleanup at least 2-times the
size of the newly added entry.
2025-07-09 21:22:47 +02:00
Alessio Podda
25daa047d4 Replace per-zone lock buckets with global buckets
Qpzone employs a locking strategy where rwlocks are grouped into
buckets, and each zone gets 17 buckets.
This strategy is suboptimal in two ways:
 - If named is serving a single zone or a zone is the majority of the
   traffic, this strategy pretty much guarantees contention when using
   more than a dozen threads.
 - If named is serving many small zones, it causes substantial memory
   usage.

This commit switches the locking to a global table initialized at start
time. This should have three effects:
 - Performance should improve in the single zone case, since now we are
   selecting from a bigger pool of locks.
 - Memory consumption should go down significantly in the many zone
   cases.
 - Performance should not degrade substantially in the many zone cases.
   The reason for this is that, while we could have substantially more
   zones than locks, we can query/edit only O(num threads) at the same
   time. So by making the global table much bigger than the expected
   number of threads, we can limit contention.
2025-07-09 15:27:38 +02:00
Alessio Podda
0b1785ec10 Extract the resigning heap into a separate struct
In the current implementation, the resigning heap is part of the zone
database. This leads to a cycle, as the database has a reference to its
nodes, but each node needs a reference to the database.

This MR splits the resigning heap into its own separate struct, in order
to help breaking the cycle.
2025-07-09 12:33:18 +02:00
Alessio Podda
c2a84bb17a Abstract bucket lock selection logic
Recovering the node lock from a pointer to the header and a pointer to
the db is a common operation. This commit abstracts it away into a
function, so that the node lock selection logic may be modified more
easily.
2025-07-09 12:33:18 +02:00
Petr Menšík
d2c6966232 Add few extra WANT_QUERYTRACE logs into resume_qmin
Print optionally a bit more details not passed to event in case
dns_view_findzonecut returns unexpected result. Result would be
visible later in foundevent, but found fname would be lost. Print it
into the log.
2025-07-09 10:13:29 +10:00
Petr Mensik
2fd3da54f9 Handle CNAME and DNAME in resume_min in a special way
When authoritative zone is loaded when query minimization query for the
same zone is already pending, it might receive unexpected result codes.

Normally DNS_R_CNAME would follow to query_cname after processing sent
events, but dns_view_findzonecut does not fill CNAME target into
event->foundevent. Usual lookup via query_lookup would always have that
filled.

Ideally we would restart the query with unmodified search name, if
unexpected change from recursing to local zone cut were detected. Until
dns_view_findzonecut is modified to export zone/cache source of the cut,
at least fail queries which went into unexpected state.
2025-07-09 10:13:29 +10:00
Ondřej Surý
eb0ffa0d5f
When overmem, clean enough memory when adding new ADB names/entries
The purge_stale_names()/purge_stale_entries() is opportunistic even when
we are under memory pressure (overmem).  Split the opportunistic LRU
cleaning and overmem cleaning.  This makes the stale purging much
simpler as we don't have to try that hard and makes the overmem cleaning
always cleanup double the amount of the newly allocated ADB name/entry.
2025-07-08 05:56:19 +02:00
Mark Andrews
9158e63218 Separate out adbname flags that are hashed
There are three adbname flags that are used to identify different
types of adbname lookups when hashing rather than using multiple
hash tables.  Separate these to their own structure element as these
need to be able to be read without locking the adbname structure.
2025-07-06 22:33:27 +10:00
Aram Sargsyan
3d8bd8bbf1 Reset DNS_DBFIND_STALETIMEOUT in query_lookup()
If ns__query_start() is called because of a chained query (e.g.
after encountering a CNAME), a previously set DNS_DBFIND_STALETIMEOUT
flag on the query's 'dboptions' field can cause an assertion
failure if the new query's 'stalefirst' value is not true (e.g. if the
target qname is an authoritative zone for the server). Reset the
DNS_DBFIND_STALETIMEOUT flag in the query_lookup() function before
evaluating the 'stalefirst' value, and make sure to assign a fresh
value to the `stalefirst' flag instead of conditionally assigning it
only if the value is 'true'.
2025-07-03 11:03:34 +02:00
Ondřej Surý
5eec9a2ebb
Change the .inuse member of isc_mem to be per-thread/per-loop
The .inuse member was causing a lot of contention between threads using
the same memory context.  Scather the .inuse and .overmem members of
isc_mem_t structure to be an per-tid array of variables to reduce the
contention as the writes are now independent of each other.

The array uses one tad bit nasty trick, as ISC_TID_UNKNOWN is now -1,
the array has been sized to fit the unknown tid with [-1] index into the
array accomplished with `ctx->stat = &ctx->stat_s[1];`.  It will not win
a beauty contest, but it works seamlessly by just passing `isc_tid()` as
an index into the array.

The caveat here is that gathering the real inuse value requires walking
the whole array for all registered tid values (isc_tid_count()).  The
gather part happens only when statistics are being gathered or when
isc_mem_isovermem() is called.  As the isc_mem_isovermem() call happens
only when new data is being added to cache or ADB, it doesn't happen on
the hottest (read-only) path and according to the measurements, it
doesn't slow down neither the cold cache nor the hot cache latency.
2025-06-30 13:23:17 +02:00
Ondřej Surý
f689dc2297
Don't use ssize_t for storing difference between sizes
As POSIX guarantees only that the type ssize_t shall be capable of
storing values at least in the range [-1, {SSIZE_MAX}], it can't be used
to calculate the difference between two memory sizes.  Change the logic
for junk filling to test whether the new size is larger than old size
and then use size_t as the result will be always positive.
2025-06-30 13:22:39 +02:00
Ondřej Surý
560047307d
Remove .hi_called member of isc_mem_t structure
The .hi_called member was dead structure member and it hasn't been used
since the overmem callback has been removed in commit
14bdd21e0a.
2025-06-30 13:22:39 +02:00
Ondřej Surý
d1427e9fa8
Add and use MALLOCX_ZERO_GET() macro to jemalloc_shim.h
Pull MALLOCX_ZERO_GET() macro to align the usage with the jemalloc
jemalloc/internal/jemalloc_internal_types.h header.
2025-06-30 13:22:39 +02:00
Ondřej Surý
c6828bcf8f
Delete jemalloc arena support from isc_mem
The jemalloc arena in isc_mem was added to solve runaway memory problem
for outgoing TCP connections.  In the end, this was a red herring and
the jemalloc arena code is now unused (via e28266bf).  Remove the
support for jemalloc memory arenas as we can restore this at any time if
we need it ever again, but right now it's just a dead code.
2025-06-30 13:22:39 +02:00
Ondřej Surý
74e5f5c6cf
Fix implicit headers when using isc/overflow.h header
In jemalloc_shim.h, we relied on including <isc/overflow.h> implicitly
instead of explicitly and same was happening inside isc/overflow.h - the
stdbool.h (for bool type) was being included implicitly instead of
explicitly.
2025-06-30 13:22:38 +02:00
Ondřej Surý
dd37fd6a49 Add ISC_TID_MAX with default being 512 threads
The ISC_TID_MAX variable allows other units to declare static arrays
with this as size for per-thread/per-loop variables.
2025-06-28 13:32:12 +02:00
Ondřej Surý
1032681af0 Convert the isc/tid.h to use own signed integer isc_tid_t type
Change the internal type used for isc_tid unit to isc_tid_t to hide the
specific integer type being used for the 'tid'.  Internally, the signed
integer type is being used.  This allows us to have negatively indexed
arrays that works both for threads with assigned tid and the threads
with unassigned tid.  This should be used only in specific situations.
2025-06-28 13:32:12 +02:00
Alessio Podda
ef95806e05 Change QP and qpcache logging from DEBUG(1) to DEBUG(3)
Per pspacek, currently qp and qpcache logs are too verbose and enabled at a
level too low compared to how often the logging is useful.

This commit increases the logging level, while keeping it configurable
via a define.
2025-06-25 14:37:01 +02:00
Alessio Podda
19818aebf7 Use RCU for rad name
The RAD/agent domain is a functionality from RFC 9567 that provides
a suffix for reporting error messages. On every query context reset,
we need to check if a RAD is configured and, if so, copy it.

Since we allow the RAD to be changed by reconfiguring the zone,
this access is currently protected by a mutex, which causes contention.

This commit replaces the mutex with RCU to reduce contention. The
change results in a 3% performance improvement in the 1M delegation
test.
2025-06-25 09:55:02 +02:00
Mark Andrews
422b9118e8 Use clang-format-20 to update formatting 2025-06-25 12:44:22 +10:00
Mark Andrews
3620db5ea6 Preserve brackets in DNS_SLABHEADER_GETATTR macro
We need to turn off clang-format to preserve the brackets as
'attribute' can be an expression and we need it to be evaluated
first.

Similarly we need the entire result to be evaluated independent of
the adjoining code.
2025-06-25 12:44:22 +10:00
Matthijs Mekking
d494698852 Fix spurious missing key files log messages
This happens because old key is purged by one zone view, then the other
is freaking out about it.

Keys that are unused or being purged should not be taken into account
when verifying key files are available.

The keyring is maintained per zone. So in one zone, a key in the
keyring is being purged. The corresponding key file is removed.

The key maintenance is done for the other zone view. The key in that
keyring is not yet set to purge, but its corresponding key file is
removed. This leads to "some keys are missing" log errors.

We should not check the purge variable at this point, but the
current time and purge-keys duration.

This commit fixes this erroneous logic.
2025-06-19 08:13:07 +02:00
Mark Andrews
92393f3c97 Add example PRIVATEDNS algorithm identifiers to DS 2025-06-19 07:15:20 +10:00
Mark Andrews
e687710dc7 Add PRIVATEOIDs for RSASHA256 and RSASHA512
Use the existing RSASHA256 and RSASHA512 implementation to provide
working PRIVATEOID example implementations.  We are using the OID
values normally associated with RSASHA256 (1.2.840.113549.1.1.11)
and RSASHA512 (1.2.840.113549.1.1.13).
2025-06-19 07:15:20 +10:00
Mark Andrews
10d094a289 Future: DS private algorithm support
Add support for proposed DS digest types that encode the private
algorithm identifier at the start of the DS digest as is done for
DNSKEY and RRSIG.  This allows a DS record to identify the specific
DNSSEC algorithm, rather than a set of algorithms, when the algorithm
field is set to PRIVATEDNS or PRIVATEOID.
2025-06-19 07:15:20 +10:00
Mark Andrews
c428af5e7a Support PRIVATEOID/PRIVATEDNS in zone.c
- dns_zone_cdscheck() has been extended to extract the key algorithms
  from DNSKEY data when the CDS algorithm is PRIVATEOID or PRIVATEDNS.

- dns_zone_signwithkey() has been extended to support signing with
  PRIVATEDNS and PRIVATEOID algorithms.  The signing record (type 65534)
  added at the zone apex to indicate the current state of automatic zone
  signing can now contain an additional two-byte field for the DST
  algorithm value, when the DNS secalg value isn't enough information.
2025-06-19 07:15:20 +10:00
Mark Andrews
05c5f79d58 Support PRIVATEOID/PRIVATEDNS in the validator
DS records need to checked against the DNSKEY RRset to find
the private algorithm they correspond to.
2025-06-19 07:00:53 +10:00
Mark Andrews
eb184b864c Support PRIVATEOID/PRIVATEDNS in the resolver
dns_resolver_algorithm_supported() has been extended so in addition to
an algorithm number, it can also take a pointer to an RRSIG signature
field in which key information is encoded.
2025-06-19 07:00:53 +10:00
Mark Andrews
71801ab123 Use DST algorithm values instead of dns_secalg where needed
DST algorithm and DNSSEC algorithm values are not necessarily the same
anymore: if the DNSSEC algorithm value is PRIVATEOID or PRIVATEDNS, then
the DST algorithm will be mapped to something else. The conversion is
now done correctly where necessary.
2025-06-19 07:00:53 +10:00
Mark Andrews
6fe09d85ab Support for DST_ALG_PRIVATEDNS and DST_ALG_PRIVATEOID
The algorithm values PRIVATEDNS and PRIVATEOID are placeholders,
signifying that the actual algorithm identifier is encoded into the
key data. Keys using this mechanism are now supported.

- The algorithm values PRIVATEDNS and PRIVATEOID cannot be used to
  build a key file name; dst_key_buildfilename() will assert if
  they are used.

- The DST key values for private algorithms are higher than 255.
  Since DST_ALG_MAXALG now exceeds 256, algorithm arrays that were
  previously hardcoded to size 256 have been resized.

- New mnemonic/text conversion functions have been added.
  dst_algorithm_{fromtext,totext,format} can handle algorithm
  identifiers encoded in PRIVATEDNS and PRIVATEOID keys, as well
  as the traditional algorithm identifiers. (Note: The existing
  dns_secalg_{fromtext,totext,format} functions are similar, but
  do *not* support PRIVATEDNS and PRIVATEOID. In most cases, the
  new functions have taken the place of the old ones, but in a few
  cases the old version is still appropriate.)

- dns_private{oid,dns}_{fromtext,totext,format} converts between
  DST algorithm values and the mnemonic strings for algorithms
  implemented using PRIVATEDNS or PRIVATEOID. (E.g., "RSASHA256OID").

- dst_algorithm_tosecalg() returns the DNSSEC algorithm identifier
  that applies for a given DST algorithm.  For PRIVATEDNS- or
  PRIVATEOID- based algorithms, the result will be PRIVATEDNS or
  PRIVATEOID, respectively.

- dst_algorithm_fromprivatedns() and dst_algorithm_fromprivateoid()
  return the DST algorithm identifier for an encoded algorithm in
  wire format, represented as in DNS name or an object identifier,
  respectively.

- dst_algorithm_fromdata() is a front-end for the above; it extracts
  the private algorithm identifier encoded at the begining of a
  block of key or signature data, and returns the matching DST
  algorithm number.

- dst_key_fromdns() and dst_key_frombuffer() now work with keys
  that have PRIVATEDNS and PRIVATEOID algorithm identifiers at the
  beginning.
2025-06-19 07:00:53 +10:00
Mark Andrews
9ab4160be6 Add DS digest type code points SM3 and GOST-2012
Provide mapping between mnemonic and value.
2025-06-19 07:00:53 +10:00
Mark Andrews
cf968a1a58 Add rdata type header files to dns_header_depfiles macro
The header file dns/rdatastruct.h was not being rebuilt when the
rdata type header files where modified.

Removed proforma.c from the list.  It is a starting point for new
types.
2025-06-13 12:49:36 +00:00
Mark Andrews
6c28411c55 Add CO support to dig
Dig now support setting the EDNS CO as flag using "+coflag" /
"+nocoflag" rather than as part of +ednsflags.
2025-06-13 07:50:16 +00:00
Evan Hunt
d586c29069 Remove zone keyopts field
The "keyopts" field of the dns_zone object was added to support
"auto-dnssec"; at that time the "options" field already had most of
its 32 bits in use by other flags, so it made sense to add a new
field.

Since then, "options" has been widened to 64 bits, and "auto-dnssec"
has been obsoleted and removed. Most of the DNS_ZONEKEY flags are no
longer needed. The one that still seems useful (_FULLSIGN) has been
moved into DNS_ZONEOPT and the rest have been removed, along with
"keyopts" and its setter/getter functions.
2025-06-12 18:29:29 -07:00
Evan Hunt
1a24dfcddf Clean up CFG_ZONE_DELEGATION
"type delegation-only" has been obsolete for some time
(see #3953) but the zone type flag for it was still defined
in libisccfg. It has now been removed.
2025-06-12 17:46:14 -07:00
Aydın Mercan
5cd6c173ff
replace the build system with meson
Meson is a modern build system that has seen a rise in adoption and some
version of it is available in almost every platform supported.

Compared to automake, meson has the following advantages:

* Meson provides a significant boost to the build and configuration time
  by better exploiting parallelism.

* Meson is subjectively considered to be better in readability.

These merits alone justify experimenting with meson as a way of
improving development time and ergonomics. However, there are some
compromises to ensure the transition goes relatively smooth:

* The system tests currently rely on various files within the source
  directory. Changing this requirement is a non-trivial task that can't
  be currently justified. Currently the last compiled build directory
  writes into the source tree which is in turn used by pytest.

* The minimum version supported has been fixed at 0.61. Increasing this
  value will require choosing a baseline of distributions that can
  package with meson. On the contrary, there will likely be an attempt
  to decrease this value to ensure almost universal support for building
  BIND 9 with meson.
2025-06-11 10:30:12 +03:00
Alessio Podda
4a6d7eb4f3 Try to skip lock on fully lower names
If the name is fully lowercase, we don't need to access the case bitmap
in order to set the case. Therefore, we can check for the FULLYLOWERCASE
flag using only atomic operations, and skip a lock in the hot path,
provided we clear the FULLYLOWERCASE flag before changing the case
bitmap.
2025-06-04 10:48:08 +00:00
Aram Sargsyan
14915b0241 Redesign the unreachable primaries cache
The cache for unreachable primaries was added to BIND 9 in 2006 via
1372e172d0. It features a 10-slot LRU
array with 600 seconds (10 minutes) fixed delay. During this time, any
primary with a hiccup would be blocked for the whole block duration
(unless overwritten by a different entry).

As this design is not very flexible (i.e. the fixed delay and the fixed
amount of the slots), redesign it based on the badcache.c module, which
was implemented earlier for a similar mechanism.

The differences between the new code and the badcache module were large
enough to create a new module instead of trying to make the badcache
module universal, which could complicate the implementation.

The new design implements an exponential backoff for entries which are
added again soon after expiring, i.e. the next expiration happens in
double the amount of time of the previous expiration, but in no more
time than the defined maximum value.

The initial and the maximum expiration values are hard-coded, but, if
required, it should be trivial to implement configurable knobs.
2025-06-04 09:16:35 +00:00
Evan Hunt
b8f325ae01 Add support for zone templates
A "template" statement can contain the same configuration clauses
as a "zone" statement.  A "zone" statement can now reference a
template, and all the clauses in that template will be used as
default values for the zone. For example:

    template primary {
        type primary;
        file "$name.db";
        initial-file "primary.db";
    };

    zone example.com {
        template primary;
        file "different-name.db"; // overrides the template
    };
2025-06-03 12:03:07 -07:00
Evan Hunt
598ae3f63c Allow zone names to be generated parametrically
Special tokens can now be specified in a zone "file" option
in order to generate the filename parametrically. The first
instead of "$name" in the "file" option is replaced with the
zone origin, the first instance of "$type" is replaced with the
zone type (i.e., primary, secondary, etc), and the first instance
of "$view" is replaced with the view name..

This simplifies the creation of zones using initial-file templates.
For example:

   $ rndc addzone <zonename> \
     { type primary; file "$name.db"; initial-file "template.db"
2025-06-03 12:03:07 -07:00
Evan Hunt
60b129da25 Add zone "initial-file" option
When loading a primary zone for the first time, if the zonefile
does not exist but an "initial-file" option has been set, then a
new file will be copied into place from the path specified by
"initial-file".

This can be used to simplify the process of adding new zones. For
instance, a template zonefile could be used by running:

    $ rndc addzone example.com \
        '{ type primary; file "example.db"; initial-file "template.db"; };'
2025-06-03 12:03:07 -07:00
Evan Hunt
0b8f943a6a normalize syntax checks between named and libisccfg
there were some duplicated syntax checks in named_zone_configure()
that are no longer needed, now that we perform those same checks
using isccfg_check_zoneconf().

there were also some syntax checks that were *only* in
named_zone_configure(), which have now been moved to
isccfg_check_zoneconf(). test cases for them have been
added to the checkconf system test.
2025-06-03 11:15:54 -07:00
Evan Hunt
2d57c1e737 call zone syntax checks when running rndc addzone/modzone
the function that checks zone syntax in libisccfg was previously
only called when loading named.conf, not when parsing an an
"rndc addzone" or "rndc modzone" command. this has been corrected.

note that some checks are still skipped: those that check for
duplication of filenames, key directories, etc.  to fix this, we'd need
to export the symbol tables that are set up when loading named.conf and
preserve them so they could be reused later.
2025-06-03 11:15:40 -07:00
Miltos Allamanis
c04b840260
Fix builds for the OSS-Fuzz project
Since 70b1777d8a was commited the OSS-Fuzz
build was broken because the `chunk_get_raw()` was not updated in the
`FUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION`-enabled area.  Add the `size`
argument to the fuzzing version of the `chunk_get_raw()` function.
2025-06-03 18:41:45 +02:00
Michal Nowak
b5e7d96f0a Allow commandline.c to compile on Solaris
commandline.c failed to compile on Solaris because NAME_MAX was
undefined.  Include 'isc/dir.h' which defines NAME_MAX for platforms
that don't define it.

    In file included from commandline.c:54:
    ./include/isc/commandline.h:31:38: error: 'NAME_MAX' undeclared here (not in a function)
       31 | extern char isc_commandline_progname[NAME_MAX];
          |                                      ^~~~~~~~
2025-06-02 09:00:48 +00:00
Aydın Mercan
408190fd3b
use proper flexible arrays in rrl
The single-element array hack can trip newer sanitizers or fortification
levels.
2025-05-30 10:44:49 +00:00
Aydın Mercan
23d70bde6c
add attribute macro for counted_by
Using C23 attributes for `counted_by` is broken with clang.

`__has_attribute` is used since `__has_c_attribute` only works with C23
attributes, (`gnu::counted_by`/`clang::counted_by`)
2025-05-30 08:04:49 +00:00
Mark Andrews
521bf1d50f Allow keystore.c to compile on Solaris
keystore.c failed to compile on Solaris because NAME_MAX was
undefined.  Include 'isc/dir.h' which defines NAME_MAX for platforms
that don't define it.
2025-05-30 15:14:38 +10:00
Mark Andrews
72cd6e8591 Silence tainted scalar in client.c
Coverity detected that 'optlen' was not being checked in 'process_opt'.
This is actually already done when the OPT record was initially
parsed.  Add an INSIST to silence Coverity as is done in message.c.
2025-05-29 06:26:37 +00:00
Ondřej Surý
15ddacbf17
Remove spurious zconf.h include
The #include <zconf.h> got spuriously included into isc_commandline
unit.  The #include <limits.h> needs to be used instead.
2025-05-29 06:34:08 +02:00
Ondřej Surý
a676551395
Unify handling of the program name in all the utilities
There were several methods how we used 'argv[0]'.  Some programs had a
static value, some programs did use isc_file_progname(), some programs
stripped 'lt-' from the beginning of the name.  And some used argv[0]
directly.

Unify the handling and all the variables into isc_commandline_progname
that gets populated by the new isc_commandline_init(argc, argv) call.
2025-05-29 06:17:32 +02:00
Ondřej Surý
7f498cc60d
Give every memory pool a name
Instead of giving the memory pools names with an explicit call to
isc_mempool_setname(), add the name to isc_mempool_create() call to have
all the memory pools an unconditional name.
2025-05-29 05:46:46 +02:00
Ondřej Surý
4e79e9baae
Give every memory context a name
Instead of giving the memory context names with an explicit call to
isc_mem_setname(), add the name to isc_mem_create() call to have all the
memory contexts an unconditional name.
2025-05-29 05:46:46 +02:00
Evan Hunt
dd9a685f4a simplify code around isc_mem_put() and isc_mem_free()
it isn't necessary to set a pointer to NULL after calling
isc_mem_put() or isc_mem_free(), because those macros take
care of it automatically.
2025-05-28 17:22:32 -07:00
Ondřej Surý
5d264b3329
Set name for all the isc_mem context
The memory context for isc_managers and dst_api units had no name and
that was causing trouble with the statistics channel output.  Set the
name for the two memory context that were missing a proper name.
2025-05-28 21:27:13 +02:00
Aram Sargsyan
874ca5ca2f Prepare a zone for shutting down when deleting it from a view
After b171cacf4f, a zone object can
remain in the memory for a while, until garbage collection is run.
Setting the DNS_ZONEFLG_EXITING flag should prevent the zone
maintenance function from running while it's in that state.
Otherwise, a secondary zone could initiate a zone transfer after
it had been deleted.
2025-05-28 16:59:05 +00:00
Aram Sargsyan
f4cd307c6b Emit a ISC_R_CANCELED result instead of ISC_R_SHUTTINGDOWN
When request manager shuts down, it also shuts down all its ongoing
requests. Currently it calls their callback functions with a
ISC_R_SHUTTINGDOWN result code for the request. Since a request
manager can shutdown not only during named shutdown but also during
named reconfiguration, instead of sending ISC_R_SHUTTINGDOWN result
code send a ISC_R_CANCELED code to avoid confusion and errors with
the expectation that a ISC_R_SHUTTINGDOWN result code can only be
received during actual shutdown of named.

All the callback functions which are passed to either the
dns_request_create() or the dns_request_createraw() functions have
been analyzed to confirm that they can process both the
ISC_R_SHUTTINGDOWN and ISC_R_CANCELED result codes. Changes were
made where it was necessary.
2025-05-28 16:20:13 +00:00
Aram Sargsyan
b07ec4f0b3 Add a debug log in zone.c:refresh_callback()
The new debug message logs the request result in the SOA request
callback function.
2025-05-28 16:20:13 +00:00
Aram Sargsyan
228e441328 Fix a zone refresh bug in zone.c:refresh_callback()
When the zone.c:refresh_callback() callback function is called during
a SOA request before a zone transfer, it can receive a
ISC_R_SHUTTINGDOWN result for the sent request when named is shutting
down, and in that case it just destroys the request and finishes the
ongoing transfer, without clearing the DNS_ZONEFLG_REFRESH flag of the
zone. This is alright when named is going to shutdown, but currently
the callback can get a ISC_R_SHUTTINGDOWN result also when named is
reconfigured during the ongoibg SOA request. In that case, leaving the
DNS_ZONEFLG_REFRESH flag set results in the zone never being able
to refresh again, because any new attempts will be caneled while
the flag is set. Clear the DNS_ZONEFLG_REFRESH flag on the 'exiting'
error path of the callback function.
2025-05-28 16:20:13 +00:00
Evan Hunt
8d065fd3e1 add DNS_DBITERATOR_FOREACH and DNS_RDATASETITER_FOREACH
when iterating databases, use DNS_DBITERATOR_FOREACH and
DNS_DNSRDATASETITER_FOREACH macros where possible.
2025-05-27 21:08:09 -07:00
Evan Hunt
24d077afb0 add CFG_LIST_FOREACH macro
replace the pattern `for (elt = cfg_list_first(x); elt != NULL;
elt = cfg_list_next(elt))` with a new `CFG_LIST_FOREACH` macro.
2025-05-27 21:08:09 -07:00
Evan Hunt
f10f5572ac add DNS_RDATASET_FOREACH macro
replace the pattern `for (result = dns_rdataset_first(x); result ==
ISC_R_SUCCES; result = dns_rdataset_next(x)` with a new
`DNS_RDATASET_FOREACH` macro throughout BIND.
2025-05-27 21:08:09 -07:00
Evan Hunt
6a6ef103dd import_rdataset() can't fail
the import_rdataset() function can't return any value other
than ISC_R_SUCCESS, so it's been changed to void and its callers
don't rely on its return value any longer.
2025-05-27 20:56:54 -07:00
Evan Hunt
c437da59ee correct the DbC assertions in message.c
the comments for some calls in the dns_message API specified
requirements which were not actually enforced in the functions.

in most cases, this has now been corrected by adding the missing
REQUIREs. in one case, the comment was incorrect and has been
revised.
2025-05-27 23:11:04 +00:00
Evan Hunt
8487e43ad9 make all ISC_LIST_FOREACH calls safe
previously, ISC_LIST_FOREACH and ISC_LIST_FOREACH_SAFE were
two separate macros, with the _SAFE version allowing entries
to be unlinked during the loop. ISC_LIST_FOREACH is now also
safe, and the separate _SAFE macro has been removed.

similarly, the ISC_LIST_FOREACH_REV macro is now safe, and
ISC_LIST_FOREACH_REV_SAFE has also been removed.
2025-05-23 13:09:10 -07:00
Alessio Podda
d7064c9b88 Tune min and max chunk size
Before implementing adaptive chunk sizing, it was necessary to ensure
that a chunk could hold up to 48 twigs, but the new logic will size-up
new chunks to ensure that the current allocation can succeed.

We exploit the new logic in two ways:
 - We make the minimum chunk size smaller than the old limit of 2^6,
   reducing memory consumption.
 - We make the maximum chunk size larger, as it has been observed that
   it improves resolver performance.
2025-05-22 15:19:48 -07:00
alessio
70b1777d8a Adaptive memory allocation strategy for qp-tries
qp-tries allocate their nodes (twigs) in chunks to reduce allocator
pressure and improve memory locality. The choice of chunk size presents
a tradeoff: larger chunks benefit qp-tries with many values (as seen
in large zones and resolvers) but waste memory in smaller use cases.

Previously, our fixed chunk size of 2^10 twigs meant that even an
empty qp-trie would consume 12KB of memory, while reducing this size
would negatively impact resolver performance.

This commit implements an adaptive chunking strategy that:
 - Tracks the size of the most recently allocated chunk.
 - Doubles the chunk size for each new allocation until reaching a
   predefined maximum.

This approach effectively balances memory efficiency for small tries
while maintaining the performance benefits of larger chunk sizes for
bigger data structures.

This commit also splits the callback freeing qpmultis into two
phases, one that frees the underlying qptree, and one that reclaims
the qpmulti memory. In order to prevent races between the qpmulti
destructor and chunk garbage collection jobs, the second phase is
protected by reference counting.
2025-05-22 15:19:27 -07:00
Michał Kępień
c9bf5df999 Merge tag 'v9.21.8' 2025-05-21 21:23:09 +02:00
Ondřej Surý
8171bf01ed
Deprecate max-rsa-exponent-size, always use 4096 instead
The `max-rsa-exponent-size` could limit the exponents of the RSA
public keys during the DNSSEC verification.  Instead of providing
a cryptic (not cryptographic) knob, hardcode the max exponent to
be 4096 (the theoretical maximum for DNSSEC).
2025-05-21 00:50:08 +02:00
Ondřej Surý
841b25fb62
Cleanup the DST cryptographic API
The DST API has been cleaned up, duplicate functions has been squashed
into single call (verify and verify2 functions), and couple of unused
functions have been completely removed (createctx2, computesecret,
paramcompare, and cleanup).
2025-05-20 09:52:35 +02:00
Aram Sargsyan
e42d6b4810 Implement a new 'notify-defer' configuration option
This new option sets the delay, in seconds, to wait before sending
a set of NOTIFY messages for a zone. Whenever a NOTIFY message is
ready to be sent, sending will be deferred for this duration.
2025-05-15 12:24:13 +00:00
Aram Sargsyan
d79b14ff5d Update the dns_zone_setnotifydelay() function's documentation
Add a note that the delay is in seconds.
2025-05-15 12:21:30 +00:00
Aram Sargsyan
62f66c0be0 Delete the unused dns_zone_getnotifydelete() function
The function is unused, delete it.
2025-05-15 12:21:30 +00:00
Evan Hunt
a1e9b885d2
Prevent assertion when processing TSIG algorithm
In a previous change, the "algorithm" value passed to
dns_tsigkey_create() was changed from a DNS name to an integer;
the name was then chosen from a table of known algorithms. A
side effect of this change was that a query using an unknown TSIG
algorithm was no longer handled correctly, and could trigger an
assertion failure.  This has been corrected.

The dns_tsigkey struct now stores the signing algorithm
as dst_algorithm_t value 'alg' instead of as a dns_name,
but retains an 'algname' field, which is used only when the
algorithm is DST_ALG_UNKNOWN.  This allows the name of the
unrecognized algorithm name to be returned in a BADKEY
response.
2025-05-08 22:45:48 +02:00
Mark Andrews
9bb93520f1
Wrong NSEC3 chosen for NO QNAME proof
When we optimised the closest encloser NSEC3 discovery the maxlabels
variable was used in the binary search. The updated value was later
used to add the NO QNAME NSEC3 but that block of code needed the
original value. This resulted in the wrong NSEC3 sometimes being
chosen to perform this role.
2025-05-08 21:48:11 +02:00
Mark Andrews
c0fcb9fd0e Fix the error handling of put_yamlstr calls
The return value was sometimes being ignored when it shouldn't
have been.
2025-04-30 15:39:52 +10:00
Your Name
59086c33e2 Call rcu_barrier earlier in the destructor
If a call_rcu thread is running, there is a possible race condition
where the destructors run before all call_rcu callbacks have finished
running. This can happen, for example, if the call_rcu callback tries to
log something after the logging context has been torn down.

In !10394, we tried to counter this by explicitely creating a call_rcu
thread an shutting it down before running the destructors, but it is
possible for things to "slip" and end up on the default call_rcu thread.

As a quickfix, this commit moves an rcu_barrier() that was in the mem
context destructor earlier, so that it "protects" all libisc
destructors.
2025-04-25 13:13:44 +02:00
Aram Sargsyan
74a8acdc8d Separate the single setter/getter functions for TCP timeouts
Previously all kinds of TCP timeouts had a single getter and setter
functions. Separate each timeout to its own getter/setter functions,
because in majority of cases only one is required at a time, and it's
not optimal expanding those functions every time a new timeout value
is implemented.
2025-04-23 17:03:05 +00:00
Aram Sargsyan
b9e9b98d55 Use the configured TCP connect timeout in checkds_send_toaddr()
The checkds_send_toaddr() function uses hardcoded timeout values
for both UDP and TCP, however, with TCP named has configurable
timeout values. Slightly refactor the timeouts calculation part
and use the configured 'tcp-initial-timeout' value as the connect
timeout.
2025-04-23 17:03:05 +00:00
Aram Sargsyan
daede6876b Use the configured TCP connect timeout in notify_send_toaddr()
The notify_send_toaddr() function uses hardcoded timeout values
for both UDP and TCP, however, with TCP named has configurable
timeout values. Slightly refactor the timeouts calculation part
and use the configured 'tcp-initial-timeout' value as the connect
timeout.
2025-04-23 17:03:05 +00:00
Aram Sargsyan
70ad94257d Implement tcp-primaries-timeout
The new 'tcp-primaries-timeout' configuration option works the same way
as the existing 'tcp-initial-timeout' option, but applies only to the
TCP connections made to the primary servers, so that the timeout value
can be set separately for them. The default is 15 seconds.

Also, while accommodating zone.c's code to support the new option, make
a light refactoring with the way UDP timeouts are calculated by using
definitions instead of hardcoded values.
2025-04-23 17:03:05 +00:00
Aram Sargsyan
e1a415b412 Fix a date race in qpcache_addrdataset()
The 'qpnode->nsec' structure member isn't protected by a lock and
there's a data race between the reading and writing parts in the
qpcache_addrdataset() function. Use a node read lock for accessing
'qpnode->nsec' in qpcache_addrdataset(). Add an additional
'qpnode->nsec != DNS_DB_NSEC_HAS_NSEC' check under a write lock
to be sure that no other competing thread changed it in the time
when the read lock is unlocked and a write lock is not acquired
yet.
2025-04-23 13:02:43 +00:00
Aram Sargsyan
412aa881f2 Fix a serve-stale issue with a delegated zone
When 'stale-answer-client-timeout' is 0, named is allowed to return
a stale answer immediately, while also initiating a new query to get
the real answer. This mode is activated in ns__query_start() by setting
the 'qctx->options.stalefirst' optoin to 'true' before calling the
query_lookup() function, but not when the zone is known to be
authoritative to the server. When the zone is authoritative, and
query_looup() finds out that the requested name is a delegation,
then before proceeding with the query, named tries to look it up
in the cache first. Here comes the issue that it doesn't consider
enabling 'qctx->options.stalefirst' in this case, and so the
'stale-answer-client-timeout 0' setting doesn't work for those
delegated zones - instead of immediately returning the stale answer
(if it exists), named tries to resolve it.

Fix this issue by enabling 'qctx->options.stalefirst' in the
query_zone_delegation() function just before named looks up the name
in the cache using a new query_lookup() call. Also, if nothing was
found in the cache, don't initiate another query_lookup() from inside
query_notfound(), and let query_notfound() do its work, i.e. it will
call query_delegation() for further processing.
2025-04-23 11:46:16 +00:00
Mark Andrews
5eeb31f0b9 Split EDNS COOKIE YAML into separate parts
Split the YAML display of the EDNS COOKIE option into CLIENT and SERVER
parts.  The STATUS of the EDNS COOKIE in the reply is now a YAML element
rather than a comment.
2025-04-22 09:24:18 +10:00
Mark Andrews
07c28652a3 Fix EDNS TCP-KEEPALIVE option YAML output
There was missing white space between the option name and its value.
2025-04-22 09:24:18 +10:00
Mark Andrews
81334113c3 Fix EDNS LLQ option YAML output
The EDNS LLQ option was not being emitted as valid YAML. Correct
the output to be valid YAML with each field of the LLQ being
individually selectable.
2025-04-22 09:24:18 +10:00
Mark Andrews
27e8732c17 Change the EDNS KEY-TAG YAML output format
When using YAML, print the EDNS KEY-TAG as an array of integers
for easier machine parsing. Check the validity of the YAML output.
2025-04-22 09:24:18 +10:00
Mark Andrews
378bc7cfa6 Use YAML comments for durations rather than parentheses
This will allow the values to be parsed using standard yaml processing
tools, and still provide the value in a human friendly form.
2025-04-22 09:24:18 +10:00
Mark Andrews
68cdc4774c Change the name and YAML format of EDNS UL
The offical EDNS option name for "UL" is "UPDATE-LEASE".  We now
emit "UPDATE-LEASE" instead of "UL", when printing messages, but
"UL" has been retained as an alias on the command line.

Update leases consist of 1 or 2 values, LEASE and KEY-LEASE.  These
components are now emitted separately so they can be easily extracted
from YAML output.  Tests have been added to check YAML correctness.
2025-04-22 09:24:18 +10:00
Mark Andrews
280e9b7cf4 Add YAML escaping where needed
When rendering text, such as domain names or the EXTRA-TEXT
field of the EDE option, backslashes and quotation marks must
be escaped to ensure that the emitted message is valid YAML.
2025-04-22 09:24:18 +10:00
Mark Andrews
e7ef4e41eb Collapse common switch cases when emitting EDNS options
The CHAIN and REPORT-CHANNEL EDNS options are both domain names, so they
can be combined.  THE CLIENT-TAG and SERVER-TAG EDNS options are both 16
bit integers, so they can be combined.
2025-04-22 09:23:53 +10:00
Ondřej Surý
bf1b8824ac
Disable own memory context for libxml2 on macOS 15.4 Sequoia
The custom allocation API for libxml2 is deprecated starting in macOS
Sequoia 15.4, iOS 18.4, tvOS 18.4, visionOS 2.4, and tvOS 18.4.

Disable the memory function override for libxml2 when
LIBXML_HAS_DEPRECATED_MEMORY_ALLOCATION_FUNCTIONS is defined as Apple
broke the system-wide libxml2 starting with macOS Sequoia 15.4.
2025-04-18 20:16:13 +02:00
Nicki Křížek
c5707cb75a Merge tag 'v9.21.7' 2025-04-16 15:23:14 +02:00
Ondřej Surý
30d4939382
Move the call_rcu_thread explicit create and shutdown to isc_loop
When isc__thread_initialize() is called from a library constructor, it
could be called before we fork the main process.  This happens with
named, and then we have the call_rcu_thread attached to the pre-fork
process and not the post-fork process, which means that the initial
process will never shutdown, because there's noone to tell it so.

Move the isc__thread_initialize() and isc__thread_shutdown() to the
isc_loop unit where we call it before creating the extra thread and
after joining all the extra threads respectively.
2025-04-16 12:30:14 +02:00
Ondřej Surý
6ed821beb4
Reduce QPDB_VIRTUAL to 10 seconds
The *DB_VIRTUAL value was introduced to allow the clients (presumably
ns_clients) that has been running for some time to access the cached
data that was valid at the time of its inception.  The default value
of 5 minutes is way longer than longevity of the ns_client object as
the resolver will give up after 2 minutes.

Reduce the value to 10 seconds to accomodate to honour the original
more closely, but still allow some leeway for clients that started some
time in the past.

Our measurements show that even setting this value to 0 has no
statistically significant effect, thus the value of 10 seconds should be
on the safe side.
2025-04-16 11:21:38 +02:00
Mark Andrews
0d9cab1555 Process NSID and DNS COOKIE options when returning BADVERS
This will help identify the broken server if we happen to break
EDNS version negotiation.  It will also help protect the client
from spoofed BADVERSION responses.
2025-04-15 02:38:37 +00:00
Mark Andrews
ca7355b7d0 Fix OID check for PRIVATEOID keys and signatures
We were failing to account for the length byte before the OID.
See RFC 4034.

   Algorithm number 254 is reserved for private use and will never be
   assigned to a specific algorithm.  The public key area in the DNSKEY
   RR and the signature area in the RRSIG RR begin with an unsigned
   length byte followed by a BER encoded Object Identifier (ISO OID) of
   that length.  The OID indicates the private algorithm in use, and the
   remainder of the area is whatever is required by that algorithm.
   Entities should only use OIDs they control to designate their private
   algorithms.
2025-04-03 23:00:16 +11:00
Mark Andrews
90b2f94d9b Don't cache lack of EDNS based on received responses
Caching prevents server upgrades being detected in a timely manner
and it can also prevent DNSSEC responses being requested.
2025-04-03 10:53:35 +02:00
Ondřej Surý
2988ebae21
Don't copy EDE codes if source is same as destination
If the nested DNS validator ends up in the same fetch because of the
loops, the code could be copying the EDE codes from the same source EDE
context as the destination EDE context.  Skip copying the EDE codes if
the source and the destination is the same.
2025-04-02 18:06:52 +02:00
Ondřej Surý
fe48290140
Don't pass edectx from fetch_and_forget
Pass NULL as edectx for the fetch_and_forget() fetches as nobody
is reading the EDE contexts and it can mess the main client buffer.
2025-04-02 17:38:31 +02:00
Ondřej Surý
d7593196a1
Add static ede context into each validator layer
Instead of passing the edectx from the fetchctx into all subvalidators,
make the ede context ownership explict for dns_resolver_createfetch()
callers, and copy the ede result codes from the children validators to
the parent when finishing the validation process.
2025-04-02 17:32:50 +02:00
alessio
4017a40b1d Remove zero initialization of large buffers
Profiles show that an high amount of CPU time spent in memset.
By removing zero initalization of certain large buffers we improve
performance in certain authoritative workloads.
2025-04-02 16:24:31 +02:00
Evan Hunt
ad7f744115 use ISC_LIST_FOREACH in more places
use the ISC_LIST_FOREACH pattern in places where lists had
been iterated using a different pattern from the typical
`for` loop: for example, `while (!ISC_LIST_EMPTY(...))` or
`while ((e = ISC_LIST_HEAD(...)) != NULL)`.
2025-03-31 13:45:14 -07:00
Evan Hunt
522ca7bb54 switch to ISC_LIST_FOREACH everywhere
the pattern `for (x = ISC_LIST_HEAD(...); x != NULL; ISC_LIST_NEXT(...)`
has been changed to `ISC_LIST_FOREACH` throughout BIND, except in a few
cases where the change would be excessively complex.

in most cases this was a straightforward change. in some places,
however, the list element variable was referenced after the loop
ended, and the code was refactored to avoid this necessity.

also, because `ISC_LIST_FOREACH` uses typeof(list.head) to declare
the list elements, compilation failures can occur if the list object
has a `const` qualifier.  some `const` qualifiers have been removed
from function parameters to avoid this problem, and where that was not
possible, `UNCONST` was used.
2025-03-31 13:45:10 -07:00
Evan Hunt
5cff8f9017 implicitly declare list elements in ISC_LIST_FOREACH macros
ISC_LIST_FOREACH and related macros now use 'typeof(list.head)' to
declare the list elements automatically; the caller no longer needs
to do so.

ISC_LIST_FOREACH_SAFE also now implicitly declares its own 'next'
pointer, so it only needs three parameters instead of four.
2025-03-31 13:37:47 -07:00
Mark Andrews
31968a7534 Remove dead code in dns_message_sectiontotext
Following the merge of !10302 this code to reset the result code
on ISC_R_NOMORE is no longer needed.
2025-03-31 14:37:03 +00:00
Ondřej Surý
c27fce26e6
Drop readline alternatives in favor of libedit
The libedit is now ubiquitous and has a licences compatible with
MPL 2.0.  Drop readline (GPL 3.0) and editline (obsolete) support
in favor of libedit.
2025-03-31 15:20:40 +02:00
Artem Boldariev
2592e309c7 Dispatch: carefully check if the server name for SNI is a hostname
Previously the code would not check if the string intended to be used
for SNI is a hostname.
2025-03-31 14:23:19 +03:00
Artem Boldariev
1f199ee606 Add isc_tls_valid_sni_hostname()
Add a function that checks if a 'hostname' is not a valid IPv4 or IPv6
address. Returns 'true' if the hostname is likely a domain name, and
'false' if it represents an IP address.
2025-03-31 14:23:19 +03:00
Colin Vidal
4eb2cd364a copy __FILE__ when allocating memory
When allocating memory under -m trace|record, the __FILE__ pointer is
stored, so it can be printed out later in order to figure out in which
file an allocation leaked. (among others, like the line number).

However named crashes when called with -m record and using a plugin
leaking memory. The reason is that plugins are unloaded earlier than
when the leaked allocations are dumped (obviously, as it's done as late
as possible). In such circumstances, __FILE__ is dangling because the
dynamically loaded library (the plugin) is not in memory anymore.

Fix the crash by systematically copying the __FILE__ string
instead of copying the pointer. Of course, this make each allocation to
consume a bit more memory (and longer, as it needs to calculate the
length of __FILE__) but this occurs only under -m trace|record debugging
flags.

In term of unit test, because grepping in C is not fun, and because the
whole "syntax" of the dump output is tested in other tests, this simply
search for a substring in the whole buffer to make sure the expected
allocations are found.
2025-03-27 10:44:17 +01:00
alessio
2f27d66450 Refactor to use list-like macro for message sections
In the code base it is very common to iterate over all names in a message
section and all rdatasets for each name, but various idioms are used for
iteration.

This commit standardizes them as much as possible to a single idiom,
using the macro MSG_SECTION_FOREACH, similar to the existing
ISC_LIST_FOREACH.
2025-03-27 03:09:46 +01:00
Evan Hunt
3188b1c055 move application of dns64 to a separate function
the code in query_dns64() that applies the dns64 prefixes to
an A rdataset has been moved into the dns_dns64 module, and
dns_dns64_destroy() now unlinks the dns64 object from its
containing list. with these changes, we no longer need the
list-manipulation API calls dns_dns64_next() and
dns_dns64_unlink().
2025-03-26 23:30:38 +00:00
Evan Hunt
db8c11ea0b dns_message_gettemp*() resets objects
callers of dns_message_gettemprdata() and dns_message_getrdatalist()
initialize the objects after retrieving them. this is no longer
necessary.
2025-03-26 23:30:38 +00:00
Ondřej Surý
1233dc8a61 Add isc_sieve unit implementing SIEVE-LRU algorithm
This is the core implementation of the SIEVE algorithm described in the
following paper:

  Zhang, Yazhuo, Juncheng Yang, Yao Yue, Ymir Vigfusson, and K V
  Rashmi. “SIEVE Is Simpler than LRU: An Efficient Turn-Key Eviction
  Algorithm for Web Caches,” n.d.. available online from
  https://junchengyang.com/publication/nsdi24-SIEVE.pdf
2025-03-26 15:36:33 -07:00
Ondřej Surý
e8a1949566
Remove lock upgrading from the hot path in the cache
In QPcache, there were two places that tried to upgrade the lock.  In
clean_stale_header(), the code would try to upgrade the lock and cleanup
the header, and in qpzonode_release(), the tree lock would be optionally
upgraded, so we can cleanup the node directly if empty.  These
optimizations are not needed and they have no effect on the performance.
2025-03-25 10:57:19 +01:00
Ondřej Surý
3ef9b09620
Fix invalid cache-line padding for qpcache buckets
The isc_queue_t was missing in the calculation of the required
padding size inside the qpcache bucket structure.
2025-03-25 10:56:21 +01:00
Aram Sargsyan
fb16080280 Don't call dst_key_free(keyp) on an invalid 'keyp'
After a refactoring in 2e6107008d the
dst_key_free() call is invalid and can cause an assertion. Remove the
dst_key_free() call.
2025-03-25 08:19:45 +00:00
Evan Hunt
5c21576f82 Don't check DNS_KEYFLAG_NOAUTH
All DNSKEY keys are able to authenticate. The DNS_KEYTYPE_NOAUTH
(and DNS_KEYTYPE_NOCONF) flags were defined for the KEY rdata type,
and are not applicable to DNSKEY.

Previously, because the DNSKEY implementation was built on top of
KEY, the NOAUTH flag prevented authentication in DNSKEYs as well.
This has been corrected.
2025-03-25 06:38:25 +00:00
Evan Hunt
fee1ba40df Tidy up keyvalue.h definitions
Use enums for DNS_KEYFLAG_, DNS_KEYTYPE_, DNS_KEYOWNER_, DNS_KEYALG_,
and DNS_KEYPROTO_ values.

Remove values that are never used.

Eliminate the obsolete DNS_KEYFLAG_SIGNATORYMASK. Instead, add three
more RESERVED bits for the key flag values that it covered but which
were never used.
2025-03-25 06:38:25 +00:00
Matthijs Mekking
2c52aea3dc Remove dns_qpmulti_lockedread declaration
This function was removed in 6217e434b5
but not from the header file.
2025-03-25 05:58:31 +00:00
Evan Hunt
36cf1c6a5b when forwarding, try with CD=0 first
when sending a query to a forwarder for a name within a secure domain,
the first query is now sent with CD=0. when the forwarder itself
is validating, this will give it a chance to detect bogus data and
replace it with valid data before answering. this reduces our chances
of being stuck with data that can't be validated.

if the forwarder returns SERVFAIL to the initial query, the query
will be repeated with CD=1, to allow for the possibility that the
forwarder's validator is faulty or that the bogus answer is covered
by an NTA.

note: previously, CD=1 was only sent when the query name was in a
secure domain. today, validating servers have a trust anchor at the
root by default, so virtually all queries are in a secure domain.
therefore, the code has been simplified.  as long as validation is
enabled, any forward query that receives a SERVFAIL response will be
retried with CD=1.
2025-03-24 17:33:11 -07:00
Mark Andrews
78de8afd47 Return raw zone serial for inline zones 2025-03-24 22:16:09 +00:00
Mark Andrews
9428e32b13 Add an option to disable ZONEVERSION responses
The option provide-zoneversion controls whether ZONEVERSION is
returned.  This applies to primary, secondary and mirror zones.
2025-03-24 22:16:09 +00:00
Mark Andrews
a4f5c1d5f3 Add option request-zoneversion
This can be set at the option, view and server levels and causes
named to add an EDNS ZONEVERSION option to requests.  Replies are
logged to the 'zoneversion' category.
2025-03-24 22:16:09 +00:00
Mark Andrews
e9a87f0389 Return EDNS ZONEVERSION if requested
If there was an EDNS ZONEVERSION option in the DNS request and the
answer was from a zone, return the zone's serial and number of
labels excluding the root label with the type set to 0 (ZONE-SERIAL).
2025-03-24 22:16:09 +00:00
Mark Andrews
ebe751f88c Add dns_zone_getzoneversion
Returns the EDNS ZONEVERSION for the zone.  Return the database
specific version otherwise return a type 0 version (serial).
2025-03-24 22:16:09 +00:00
Mark Andrews
5c126a7e66 Add dns_db_getzoneversion
Provides a database method to return a database specific EDNS
ZONEVERSION option.  The default EDNS ZONEVERSION is serial.
2025-03-24 22:16:09 +00:00
Mark Andrews
998b93acca Add EDNS ZONEVERSION option counter 2025-03-24 22:16:09 +00:00
Mark Andrews
ec3cbc5468 Extend message code to display ZONEVERSION 2025-03-24 22:16:09 +00:00
Mark Andrews
b2c2b6755e Check EDNS ZONEVERSION when parsing OPT record 2025-03-24 22:16:09 +00:00
Mark Andrews
8e7229f641 Fix gaining adbname reference
Call dns_adbname_ref before calling dns_resolver_createfetch to
ensure adbname->name remains stable for the life of the fetch.
2025-03-20 23:25:29 +00:00
Evan Hunt
2e6107008d optimize key ID check when searching for matching keys
when searching a DNSKEY or KEY rrset for the key that matches
a particular algorithm and ID, it's a waste of time to convert
every key into a dst_key object; it's faster to compute the key
ID by checksumming the region, and then only do the full key
conversion once we know we've found the correct key.

this optimization was already in use in the validator, but it's
been refactored for code clarity, and is now also used in query.c
and message.c.
2025-03-20 18:22:58 +00:00
Evan Hunt
341b962665 move dns_zonekey_iszonekey() to dns_dnssec module
dns_zonekey_iszonekey() was the only function defined in the
dns_zonekey module, and was only called from one place. it
makes more sense to group this with dns_dnssec functions.
2025-03-20 18:22:58 +00:00
alessio
e1e10adc3a Switch symtab to use fxhash hashing
This merge request resolves some performance regressions introduced
with the change from isc_symtab_t to isc_hashmap_t.

The key improvements are:

1. Using a faster hash function than both isc_hashmap_t and
   isc_symtab_t. The previous implementation used SipHash, but the
   hashflood resistance properties of SipHash are unneeded for config
   parsing.
2. Shrinking the initial size of the isc_hashmap_t used inside
   isc_symtab_t. Symtab is mainly used for config parsing, and the
   when used that way it will have between 1 and ~50 keys, but the
   previous implementation initialized a map with 128 slots.
   By initializing a smaller map, we speed up mallocs and optimize for
   the typical case of few config keys.
3. Slight optimization of the string matching in the hashmap, so that
   the tail is handled in a single load + comparison, instead of byte
   by byte.
   Of the three improvements, this is the least important.
2025-03-20 11:26:09 +01:00
Matthijs Mekking
3e836a87e6 Update Retired and Removed if we update lifetime
If we are updating the lifetime, and it was not set before, also
set/update the Retired and Removed timing metadata.
2025-03-20 10:12:16 +00:00
Matthijs Mekking
6c6b8796d3 Fix keymgr bug wrt setting the next time
Only set the next time the keymgr should run if the value is non zero.
Otherwise we default back to one hour. This may happen if there is one
or more key with an unlimited lifetime.
2025-03-20 10:12:16 +00:00
Matthijs Mekking
8c9d2eb2bf keymgr: also set DeleteCDS when setting PublishCDS
The keymgr never set the expected timing metadata when CDS/CDNSKEY
records for the corresponding key will be removed from the zone. This
is not troublesome, as key states dictate when this happens, but with
the new pytest we use the timing metadata to determine if the CDS and/or
CDNSKEY for the given key needs to be published.
2025-03-20 10:12:16 +00:00