Commit graph

9948 commits

Author SHA1 Message Date
Mark Andrews
e968d0fb8e The last argument to cache_rrset is wrong
The last argument to cache_rrset should be a bool (false)
not a pointer (NULL).
2025-09-10 10:51:21 +10:00
Colin Vidal
5893770cd9 add zone-specific plugin instance
The zone object now has its own hooktable and plugins, which are
initialized during zone initialization.
2025-09-09 09:42:34 +02:00
Ondřej Surý
2963d1aaf1
Refactor the cyclic ordering to use query ID as offset
Mimic the Unbound behaviour where the cyclic offset is taken from query
ID, and remove recording of the current state.  As the incoming query ID
should have random distribution, the cyclic ordering should also have
uniform distribution of the starting record.
2025-09-08 14:04:13 +02:00
Ondřej Surý
b3f5c3b0fc
Refactor the cyclic ordering to be more efficient
With random ordering removed, the cyclic ordering can be rewritten in a
that it uses thread_local static array to keep the cyclic order.

This could be further improved by keeping the current position inside
the slabheader and adding a function to start directly there instead at
dns_rdataset_first().
2025-09-08 14:04:13 +02:00
Ondřej Surý
7dc6048f93
Remove the random ordering of resource records in RRset
The rrset-order random doesn't offer uniform distribution of all
permutations and it isn't superior to cyclic order in any way.  Make the
random ordering an alias to the cyclic ordering.
2025-09-08 14:04:13 +02:00
Colin Vidal
0e1f13e05c add extra tokens to the zone file name template
Extend the `$name`, `$view` and `$type` tokens (expanding into the zone
name, zone's view name and type); the new following tokens are now also
accepted:

- $name or %s is replaced with the zone name in lower case;
- $type or %t is replaced with the zone type -- i.e., primary,
  secondary, etc);
- $view or %v is replaced with the view name;
- $char1 or %1 is replaced with the first character of the zone name;
- $char2 or %2 is replaced with the second character of the zone name
  (or a dot if there is no second character);
- $char3 or %3 is replaced with the third character of the zone name (or
  a dot if there is no third character);
- $label1 or %z is replaced with the toplevel domain of the zone (or a
  dot if it is the root zone);
- $label2 or %y is replaced with the next label under the toplevel
  domain (or a dot if there is no next label);
- $label3 or %x is replaced with the next-next label under the toplevel
  domain (or a dot if there is no next-next label).
2025-09-08 12:10:09 +02:00
Mark Andrews
6b29da55fc Add support for parsing and displaying BRID rdata type 2025-09-03 10:05:13 +10:00
Mark Andrews
37041c3ec3 Add support for parsing and displaying HHIT rdata type 2025-09-03 10:05:13 +10:00
Mark Andrews
283da99f02 RPZ canonical warning displays zone entry incorrectly
Do not insert a NUL into ip_str too early as the full value
is needed later.  Only insert the NUL immediately before
displaying just the prefix string.
2025-09-03 09:01:54 +10:00
Ondřej Surý
5b025d6e43
Remove qname/qtype from dns_adb_createfind() call
Both qname and qtype arguments to dns_adb_createfind() were unused.
Remove both these arguments from the function prototype.
2025-09-02 20:16:58 +02:00
Michał Kępień
805f1c0f65
Obsolete the "tkey-domain" statement
The "tkey-domain" statement has effectively been a no-op since commit
bd4576b3ce, which removed the only bit of
code using it: the logic implementing TKEY Mode 2 (Diffie-Hellman).

A subsequent cleanup commit, 885c132f4a,
also missed the opportunity to remove the "tkey-domain" statement
altogether.

Mark the "tkey-domain" statement as obsolete and remove all code and
documentation related to it.
2025-09-01 21:35:33 +02:00
Ondřej Surý
8dd99876b8
Always scan all the slab headers when adding new entry
The existing logic would always scan the headers if:
- adding negative cache entry that's NXDOMAIN or negative RRSIG
- adding positive cache entry
- the type doesn't exist in the node

As the rest is relatively minor - we only delete rrset from resolver
on broken chain and most negative entries don't exist in the case
anyway, it feels like the extra logic to decide whether we should do
full scan or not is just complicating things.

Remove the extra logic and always scan all the slabtop/slabheaders in
the node when adding new entry into the cache.
2025-08-28 19:28:56 +02:00
Ondřej Surý
37fa960bd5
Add few missing qpcache_hit() calls
There were couple of missing qpcache_hit() calls in qpcache.c:add()
function where existing data was better than the newly added header.
2025-08-28 19:28:56 +02:00
Ondřej Surý
7b7901494d
Refactoring in qpcache.c:add()
There were several consequtive foreach loops when adding new entry into
the cache.  Merge the multiple foreach loops into a single pass loop
with some effort and a lot of comments.
2025-08-28 19:28:55 +02:00
Ondřej Surý
e3c0a2a0fd
Add DNS_SLABTOP_FOREACH macros
Add foreach macros to iterate through the dns_slabtop_t
single-linked lists.
2025-08-28 19:28:55 +02:00
Ondřej Surý
c60bdbcf5c
Remove double non-NULL guard around bindrdataset()
The bindrdataset() already has a logic to skip the rest of the function
if the passed rdataset is NULL.  Remove the external guarding for
'addedrdataset' to simplify the code flow both from the zone and cache
databases.
2025-08-28 19:28:55 +02:00
Colin Vidal
26b397bd0f move handle to keystores from the view to zonemgr
This is a follow-up of !10895 where the keystore pointer was removed
from the zone (as not specific to the zone) and moved to the view. But
in order to avoid adding extra lifecycle dependencies from the zone to
the view, the keystore pointer is now moved to the zonemgr, which also
makes more sense as this is a global settings, and zonemgr wraps a bunch
of other global settings to be accessibles from the zones.

Because the zonemgr lifecycle is the same of the keystores (which are
both depending on named_g_server) this should be a safe change.
2025-08-28 16:52:28 +02:00
Colin Vidal
529fd913db move keystores handle from the zone to the view
The list of keystores is owned by the single server object
(named_g_server), but dns_zone_t has a pointer into it in order to
preserve encapsulation (lib/dns won't link to bin/named for good
reasons).

However, getting the keystores from the zone uses the zone lock whereas
this is not needed (as the pointer value doesn't depends on the zone,
and is initialized only with the same named_g_server->keystores value);
also storing an extra pointer per zone is not needed; also, there was a
logic based on the zone->secure property which was not needed (as there
is only one keystore).

The keystores pointer is now accessible and lock-free at view level,
it also simplifies a bit the various zone configuration APIs (server.c,
zoneconf.c).
2025-08-27 10:25:20 +02:00
Ondřej Surý
9f7ba584cf
Don't preserve cache entries if new TTL is smaller than existing
Under certain circumstances, cache entries with equivalent rdataset
might not get replaced.  Previously such entry would get preserved
regardless of the new TTL and expire time on the existing header would
get updated when the expire time was less than the expire time on the
existing header.  Change the logic to preserve the existing header only
if the new expire time is larger than the existing one and replace the
existing cache entry when the new expire time is less than the existing
one.

Co-authored-by: Jinmei Tatuya <jtatuya@infoblox.com>
2025-08-26 18:26:34 +02:00
Ondřej Surý
982ca161c2
Preserve ZEROTTL attribute when replacing NS RRset
Previously, BIND 9 would drop the ZEROTTL attribute when updating
previously cached NS entry with ZEROTTL attribute set.

Co-authored-by: Jinmei Tatuya <jtatuya@infoblox.com>
2025-08-26 18:26:34 +02:00
Ondřej Surý
443bbc6491
Use the <stdbit.h> names for bit manipulation shims
When <stdbit.h> is unavailable, use the stdc names like stdc_count_zeros
instead of ISC_COUNT_ZERO macros to simplify the code.
2025-08-26 15:32:53 +02:00
Ondřej Surý
38124cfcb2
Simplify add/sub/mul overflow checks
Use C23 stdckdint.h when available and define ckd_{mul,add,sub} shims to
__builtin_{mul,add,sub}_overflow().  Require the __builtin functions
unconditionally.
2025-08-26 15:32:53 +02:00
Ondřej Surý
91289eb1b0
Allow negative RRSIGs in the qpcache again
The previous refactoring added an assertion failure when negative RRSIG
would be added to the cache database.  As result, any query for RRSIG in
any unsigned zone would trigger that assertion failure.

Allow the negative RRSIG entries to be stored in the cache database
again as not caching these would trigger new remote fetch every time
such query would be received from a client.
2025-08-26 09:03:04 +02:00
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
a0dc0434e5 Detect if keymgr made changes
If so we also want to tickle the apex because DNSKEY/CDNSKEY/CDS
RRsets may need to be re-signed.

Note that this may be overzealous, because if state transitions
happen just because of timing events (RUMOURED -> OMNIPRESENT,
UNRETENTIVE -> HIDDEN) this would have to cause changes in the
zone DNSSEC records.
2025-08-21 16:09:49 +02: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
Alessio Podda
954b527383 Remove opportunistic node cleaning, clean up only on closeversion
Currently, when releasing a qpznode after a read operation, we will
check if the node is dirty due to a previous write, upgrade the lock to
a write lock and perform a cleanup.

An unintended side effect of this is that protecting a node by
increasing the reference count must also protect its parent database.
For the very common case where only one zone is configured, this is a
non-trivial source of contention, as the same refcount will be hit by
all threads.

This commit removes the opportunistic cleaning and the database
refcount, reducing contention. Cleaning will be done only on
closeversion.
2025-08-19 14:18:44 +02:00
Alessio Podda
3271f5fda4 Do not skip cleanup for origin nodes in qpzone
Per @each, skipping cleanup of (|nsec_|nsec3_)origin nodes in
qpznode_release in qpzone.c is a residual from RBTDB, but it is
unnecessary or at most a performance optimization with QP.

Remove it to make it further changes easier to qpznode_release easier.
2025-08-19 14:18:19 +02:00
Aydın Mercan
7d5928c3a2
add isc/bit.h and unify common bit operations
The `<isc/bit.h>` header is a GNU C11 compatible version of C23's
`<stdbit.h>`.

It currently uses either `<stdbit.h>` or the equivilent compiler
builtins. However, the generic `__builtin_ctzg` and `__builtin_ctlz`
builtins are not available in every compiler version and thus falls
back to manually selecting from type.

Furthermore, the ctz fallback has been removed since `__builtin_ctzll`
has been used for a while directly without any compilation issues from
users. Thus, we can also require `__builtin_ctz`.

Unlike the rest of C23's bit utilities, we avoid the stdc_rotate_*
functions since we don't need the rotation modulus precision. This adds
a couple (admittedly cheap) unwanted instructions on some architectures.
2025-08-19 11:52:12 +03:00
Ondřej Surý
42496f3f4a
Use ControlStatementsExceptControlMacros for SpaceBeforeParens
> Put a space before opening parentheses only after control statement
> keywords (for/if/while...) except this option doesn’t apply to ForEach
> and If macros. This is useful in projects where ForEach/If macros are
> treated as function calls instead of control statements.
2025-08-19 07:58:33 +02:00
Ondřej Surý
7f9647d16e
Disassociate added rdataset on error in cache_rrset()
When first dns_db_addrdataset() succeeds in cache_rrset(), but the
second one fails with error, the added rdataset was kept associated.
This caused assertion failure down the pipe in fctx_sendevents().
2025-08-18 17:11:03 +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
Ondřej Surý
80dac1bbae
Use ISC_UxxTOyy_BE macros for {peek,get,put}_uint16 macros
Reduce the duplication and use existing macros from isc/endian.h for
network to host and vice versa conversion.
2025-08-18 12:36:47 +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
Evan Hunt
712ef31a0c
use get_uint16() to read count and rdlen
use the same macro defned for rdataslab.c to get count and
length values from raw slabs in qpzone.c.
2025-08-18 12:36:47 +02:00
Evan Hunt
04d6412558
simplify iterator_active()
the if statements calling iterator_active() checked the EXISTS
flag on the header and then iterator_active() checked it again.
simplify so only the caller checks it.
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ý
7b88247464 Don't count failed additions into the cache
Previously, when the new header was NOT added into the cache, we would
increment and then decrement stat counters immediately.

Delay incrementing the stat counters until after the newheader has
been actually added into the database.

A little cleanup to accomodate the fact that qpdb->rrsetstats is always
available was also done here.
2025-08-17 14:38:25 -07:00
Ondřej Surý
aa3408235a Always return DNS_R_UNCHANGED when new slabheader was not added
Change the add() function in the dns_qpcache to properly return
DNS_R_UNCHANGED if the newheader was not actually consumed, and move
the dns_slabheader_destroy() call outside of the add() function.
2025-08-17 14:04:30 -07:00
Ondřej Surý
d0fef4d5e5
Remove locking from rdataslab_getownercase()
Under normal circumstances, the case bitfield in the slabheader should
be set only once.  By actually (soft-)enforcing this, the read locking
can be completely removed from the rdataslab_getownercase() as we can
check whether the case has been already set or not and making everything
immutable once the case has been set.
2025-08-15 07:35:14 +02:00
Ondřej Surý
eba76df247
Move the slabheader attribute helpers to private header
The slabheader.c, qpzone.c and qpcache.c had couple of shared macros
that were copied and paste between the units.  Move these common
attributes access macros into private header, so these can be shared
among the three compilation units.
2025-08-15 07:35:14 +02:00
Ondřej Surý
8c06d627b3
Unify the NONEXISTENT() macro in qpzone to EXISTS()
In the dns_qpcache unit, we use EXISTS() macro, but in the dns_qpzone
there's a NONEXISTENT() macro for the same slabheader attribute.  Unify
the macro to be also EXISTS() in dns_qpzone.
2025-08-15 07:35:14 +02:00
Ondřej Surý
d555cb9704
The nodefullname doesn't need a read lock to access .name
The qpznode->name is constant - assigned when the node is created
and it is immutable, so there's no reason to have it locked at all.
2025-08-15 07:29:02 +02: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