Commit graph

3002 commits

Author SHA1 Message Date
Aram Sargsyan
5e718dd220 Implement '-T slowrpz' named testing option
When used, named processes RPZ zones slowly. Useful for system tests.
2025-08-22 16:31:17 +00:00
Aram Sargsyan
41387b8d30 Add a new 'servfail-until-ready' configuration option for RPZ
By default, when named is started it may start answering to
queries before the response policy zones are completely loaded
and processed. This new feature gives an option to the users to
tell named that incoming requests should result in SERVFAIL anwser
until all the response policy zones are procesed and ready.
2025-08-22 16:31:17 +00:00
Aram Sargsyan
88ed81e12d Add 'first_time' member to 'dns_rpz_zones_t'
During the initial configuration of named after startup, 'first_time'
is true. This is needed for implementing the new 'servfail-until-ready'
configuration option, which should take into effect only during the
initial configuration.
2025-08-22 16:31:17 +00:00
Matthijs Mekking
aa49850b5e Implement manual-mode for kasp
When a key retire, key generation/introduction, or a state transition
to RUMOURED/UNRETENTIVE should happen, instead they are logged.
When those logs look good, you can run 'rndc dnssec -step' to run the
keymgr and apply those steps.
2025-08-21 16:08:16 +02:00
Matthijs Mekking
63c5b453e0 Add manual-mode config option
Add a new option 'manual-mode' to 'dnssec-policy'. The intended
use is that if it is enabled, it will not automatically move to the
next state transition (RUMOURED, UNRETENTIVE), only after manual
confirmation. The intended state transition should be logged.
2025-08-21 16:00:19 +02:00
Colin Vidal
fd8624354b remove unused warning if DNS_TYPEPAIR_CHECK is off
The compile-time DNS__TYPEPAIR_CHECK macro (wrapping an INSIST) is a
no-op if DNS_TYPEPAIR_CHECK is off, making at least one unused variable
in DNS_TYPEPAIR_TYPE and DNS_TYPEPAIR_COVERS scopes (as in such case,
only one member of the pair is effectively needed).

In such case, having an unused variable (the other member of the pair)
is expected, this silence the warning by adding a (void) cast on the
no-op version of DNS__TYPEPAIR_CHECK.
2025-08-18 13:26:50 +02:00
Evan Hunt
727fb9a011
replace dns_slabheader_raw() with a flexible array member
we can use header->raw instead of dns_slabheader_raw().
2025-08-18 12:36:47 +02:00
Ondřej Surý
d7801aec71
Move SIEVE-LRU to dns_slabtop_t structure
As the qpcache has only one active header at the time, we can move the
SIEVE-LRU members from dns_slabheader_t to dns_slabtop_t structure thus
saving a little bit of memory in each slabheader and using it only once
per type.
2025-08-18 12:36:47 +02:00
Ondřej Surý
f4d8841f0d
Split the top level slab header hierarchy and the headers
The code that combines the top-level hierarchy (per-typepair) and
individual slab headers (per-version) saves a little bit of memory, but
makes the code convoluted, hard to read and hard to modify.  Change the
top level hierarchy to be of different type with individual slabheaders
"hanging" from the per-typepair dns_slabtop_t structure.

This change makes the future enhancements (changing the top level data
structure for faster lookups; coupling type + sig(type) into single
slabtop) much easier.
2025-08-18 12:36:47 +02:00
Ondřej Surý
2f81952658 Pass 'mctx' instead of 'db' to dns_slabheader_new()
The slabheader doesn't directly attach or link to 'db' anymore.  Pass
only the memory context needed to create the slab header to make the
lack of relation ship more prominent.

Also don't call dns_slabheader_reset() from dns_slabheader_new(), it has
no added value.
2025-08-17 21:56:25 -07:00
Ondřej Surý
74fe3db37c
Rename DNS_SIGTYPE() to DNS_SIGTYPEPAIR()
The DNS_SIGTYPE() macro "returns" dns_typepair_t, rename it to make this
fact more obvious and also to match DNS_TYPEPAIR() macro naming.
2025-08-15 07:22:52 +02:00
Ondřej Surý
6e2ca5e0d7
Remove the negative type logic from qpcache
Previously, when a negative header was stored in the cache, it would be
stored in the dns_typepair_t as .type = 0, .covers = <negative type>.
When searching the cache internally, we would have to look for both
positive and negative typepair and the slabheader .down list could be a
mix of positive and negative types.

Remove the extra representation of the negative type and simply use the
negative attribute on the slabheader.  Other units (namely dns_ncache)
can still insert the (0, type) negative rdatasets into the cache, but
internally, those will be converted into (type, 0) slabheaders, and vice
versa - when binding the rdatasets, the negative (type, 0) slabheader
will be converted to (0, type) rdataset.  Simple DNS_TYPEPAIR() helper
macro was added to simplify converting single rdatatype to typepair
value.

As a side-effect, the search logic in all places can exit early if
there's a negative header for the type we are looking for, f.e. when
searching for the zone cut, we don't have to walk through all the
slabheaders, if there's a stored negative slabheader.
2025-08-15 07:22:52 +02:00
Ondřej Surý
3445362918
Add dns_rdatatype_isnsec() helper function
Replace the checks for both NSEC and NSEC3 with a single helper
function.
2025-08-15 07:22:52 +02:00
Ondřej Surý
59d1326175
Use dns_rdatatype_none more consistently
Use dns_rdatatype_none instead of plain '0' for dns_rdatatype_t and
dns_typepair_t manipulation.  While plain '0' is technically ok, it
doesn't carry the required semantic meaning, and using the named
dns_rdatatype_none constant makes the code more readable.
2025-08-15 07:22:52 +02:00
Ondřej Surý
8837491697
Add strict checks on typepair values in the developer's mode
When in developer's mode, make the DNS_TYPEPAIR_* macros be more
strict on the contents of the 'base' and 'covers', so we can catch
invalid use of the API.
2025-08-15 07:22:52 +02:00
Ondřej Surý
101b1e5a57
Unify the dns_typepair_t variable naming and usage
The dns_typepair_t and dns_rdatatype_t variables were both named 'type'
in multiple places.  Rename all dns_typepair_t variables to include word
'pair' in the variable name to make sure that the distinction between
the two types is more clear.
2025-08-15 07:22:51 +02:00
Alessio Podda
a05db4196f Remove unused dns_slabheader_reset argument
As a part of the previous refactor, the db argument of
dns_slabheader_reset is now unused, and can be removed.
2025-08-07 11:39:38 -07:00
Alessio Podda
ae6a34cbda Decouple database and node lifetimes by adding node-specific vtables
All databases in the codebase follow the same structure: a database is
an associative container from DNS names to nodes, and each node is an
associative container from RR types to RR data.

Each database implementation (qpzone, qpcache, sdlz, builtin, dyndb) has
its own corresponding node type (qpznode, qpcnode, etc). However, some
code needs to work with nodes generically regardless of their specific
type - for example, to acquire locks, manage references, or
register/unregister slabs from the heap.

Currently, these generic node operations are implemented as methods in
the database vtable, which creates problematic coupling between database
and node lifetimes. If a node outlives its parent database, the node
destructor will destroy all RR data, and each RR data destructor will
try to unregister from heaps by calling a virtual function from the
database vtable. Since the database was already freed, this causes a
crash.

This commit breaks the coupling by standardizing the layout of all
database nodes, adding a dedicated vtable for node operations, and
moving node-specific methods from the database vtable to the node
vtable.
2025-08-07 11:39:38 -07:00
Evan Hunt
7841de08af
add functions to match rdataset types
- dns_rdataset_issigtype() returns true if the rdataset is
  of type RRSIG and covers a specified type
- dns_rdataset_matchestype() returns true if the rdataset
  is of the specified type *or* the RRSIG covering it.
2025-08-05 12:16:36 +02:00
Evan Hunt
7371c4882a
change issecuredomain() functions to bool
dns_keytable_issecuredomain() and dns_view_issecuredomain()
previously returned a result code to inform the caller of
unexpected database failures when looking up names in the
keytable and/or NTA table. such failures are not actually
possible. both functions now return a simple bool.

also, dns_view_issecuredomain() now returns false if
view->enablevalidation is false, so the caller no longer
has to check for that.
2025-08-05 12:16:36 +02:00
Evan Hunt
5e1df53d05
simplify dns_ncache_add()
there's no longer any reason to have both dns_ncache_add() and
dns_ncache_addoptout().
2025-08-05 12:16:36 +02:00
Mark Andrews
6e1311c624 Add support for parsing DSYNC scheme mnemonics
Adds dns_dsyncscheme_fromtext, dns_dsyncscheme_totext and
dns_dsyncscheme_format.  Adds type dns_dsyncscheme_t.
2025-08-05 17:27:44 +10:00
Ondřej Surý
f6aed602f0
Refactor the network manager to be a singleton
There is only a single network manager running on top of the loop
manager (except for tests).  Refactor the network manager to be a
singleton (a single instance) and change the unit tests, so that the
shorter read timeouts apply only to a specific handle, not the whole
extra 'connect_nm' network manager instance.
2025-07-23 22:45:38 +02:00
Ondřej Surý
b8d00e2e18
Change the loopmgr to be singleton
All the applications built on top of the loop manager were required to
create just a single instance of the loop manager.  Refactor the loop
manager to not expose this instance to the callers and keep the loop
manager object internal to the isc_loop compilation unit.

This significantly simplifies a number of data structures and calls to
the isc_loop API.
2025-07-23 22:44:16 +02:00
Matthijs Mekking
7774f16ed5 Special case refresh stale ncache data
When refreshing stale ncache data, the qctx->rdataset is NULL and
requires special processing.
2025-07-23 07:18:48 +00:00
Matthijs Mekking
a66b04c8d4 Make serve-stale refresh behave as prefetch
A serve-stale refresh is similar to a prefetch, the only difference
is when it triggers. Where a prefetch is done when an RRset is about
to expire, a serve-stale refresh is done when the RRset is already
stale.

This means that the check for the stale-refresh window needs to
move into query_stale_refresh(). We need to clear the
DNS_DBFIND_STALEENABLED option at the same places as where we clear
DNS_DBFIND_STALETIMEOUT.

Now that serve-stale refresh acts the same as prefetch, there is no
worry that the same rdataset is added to the message twice. This makes
some code obsolete, specifically where we need to clear rdatasets from
the message.
2025-07-23 07:18:48 +00:00
Michał Kępień
a951ab1872 Update broken reference to dlz_minimal.h
Commit a6cce753e2 missed a spot in
lib/dns/include/dns/clientinfo.h.  Replace the outdated file reference
with the URL used in all similar cases.
2025-07-17 07:17:12 +02:00
Mark Andrews
cb6903c55e Warn about deprecated DNSKEY and DS algorithms / digest types
DNSKEY algorithms RSASHA1 and RSASHA-NSEC3-SHA1 and DS digest type
SHA1 are deprecated.  Log when these are present in primary zone
files and when generating new DNSKEYs, DS and CDS records.
2025-07-15 23:53:57 +10:00
Matthijs Mekking
df6763fd2a Rename DNS_DB_NSEC_ constants to DNS_DBNAMESPACE_
Naming is hard exercise.
2025-07-10 13:52:59 +00:00
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
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
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ý
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
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
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
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