Commit graph

16048 commits

Author SHA1 Message Date
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
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ý
76c027e949
Disallow TYPE0 to be queried or inserted into the database
The RR type 0 is a reserved type for SIG[1] resource record.  It should
not be ever inserted into the database nor queried.  Add a special
handling to bail out quickly with DNS_R_DISALLOWED when inserting and
ISC_R_NOTFOUND when looking up TYPE0.  This is also prerequisite for
stricter checks in the follow-up commit.

1. https://www.rfc-editor.org/rfc/rfc2535#section-4.1.8.1
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
Ondřej Surý
c22f156404
Simplify the DNS_R_UNCHANGED handling in dns_resolver unit
Instead of catching the DNS_R_UNCHANGED from dns_db_addrdataset() (via
cache_rrset() and dns_ncache_add()) individually, mask it properly as
soon as possible, by moving the sigrdataset caching logic inside
cache_rrset() and returning ISC_R_SUCCESS from cache_rrset() and
dns_ncache_add() when the database was unchanged.
2025-08-15 06:28:01 +02:00
Ondřej Surý
2b269fd0a4 Always delete the cached results on broken chain
The logic to delete records from the cache was relying on the contents
of the validation answer.  Change the logic to always delete the
contents of the cache on the broken chain result.
2025-08-14 16:08:56 -07:00
Evan Hunt
70e99bb27a result could be set incorrectly in validated()
during a recent refactoring of validated(), a line was
removed, causing 'result' to be left unchanged. this
wasted time continuing to try to validate when a
non-recoverable error had occured, and caused the wrong
reason to be logged in add_bad().
2025-08-14 16:07:54 -07:00
Mark Andrews
841d1647d4 Use DNS_RDATACOMMON_INIT to hide branch differences
Initialization of the common members of rdata type structures varies
across branches.  Standardize it by using the DNS_RDATACOMMON_INIT
macro for all types, so that new types are more likely to use it,
and hence backport more cleanly.
2025-08-15 07:30:30 +10: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
Alessio Podda
4a8f77e483 Refactor sdlz to use name instead of pointer to name
Right now dns_sdlzlookup has a slight difference from other dbnode
implementations in that it stores a pointer to a dns name instead of
the dns name itself.

This commit harmonizes dns_sdlzlookup with other dbnode
implementations, facilitating further refactoring.
2025-08-07 11:44:18 +02:00
Evan Hunt
5a2938b452
refactor validated()
- there was special-case code in validated() to handle the results
  of a validator started by a CD=1 query. since that never happens,
  the code has been removed.
- the section of code that handles opportunistic caching of
  validated SOA, NS and NSEC data has been split out to a separate
  function.
- the number of goto statements has been reduced considerably.
2025-08-05 12:16:36 +02:00
Evan Hunt
9f674c43cf
split out helper functions
- fctx_setresult() sets the event result in a fetch response
  according to the rdataset being returned - DNS_R_NCACHENXDOMAIN or
  DNS_R_NXRRSET for negative responses, ISC_R_SUCCESS, DNS_R_CNAME,
  or DNS_R_DNAME for positive ones.
- cache_rrset() looks up a node and adds an rdataset.
- delete_rrset() looks up a node and removes rdatasets of a specified
  type and, optionally, the associated signatures.
- gettrust() returns the trust level of an rdataset, or dns_trust_none
  if the rdataset is NULL or not associated.
- getrrsig() scans the rdatasets associated with a name for the
  RRSIG covering a given type.
2025-08-05 12:16:36 +02:00
Evan Hunt
723d167f26
further subdivide caching functions
rctx_cacherdataset() has been split into two functions:
- rctx_cache_secure() starts validation for rdatasets
  that need it; they are then cached by the validator
  completion callback validated()
- rctx_cache_insecure() caches rdatasets immediately; it
  is called when validation is disabled or the data
  to be cached is glue.
2025-08-05 12:16:36 +02:00
Evan Hunt
ed56a91d7d
rename and refactor cache_name() and related functions
- renamed cache_message() to rctx_cachemessage()
- renamed cache_name() to rctx_cachename()
- merged ncache_message() into rctx_ncache()
- split out a new function, rctx_cacherdataset(), which is
  called by rctx_cachename() in a loop to process each of
  the rdatasets associated with the name.
2025-08-05 12:16:36 +02:00
Evan Hunt
83980d76b2
reduce code duplication around findnoqname()
every call to findnoqname() was followed by a call to
dns_rdataset_addnoqname(). we can move that call into
findnoqname() itself, and simplify the calling functions
a bit.
2025-08-05 12:16:36 +02:00
Evan Hunt
b940d40635
set ANSWERSIG flag when processing ANY responses
previously, rctx_answer_any() set the ANSWER flag for all
rdatasets in the answer section; it now sets ANSWERSIG for
RRSIG/SIG rdatasets and ANSWER for everything else.  this
error didn't cause any harm in the current code, but it
could have led to unexpected behavior in the future.
2025-08-05 12:16:36 +02:00
Evan Hunt
c23cc105a1
split out some functionality in cache_name()
there are now separate functions to check the cacheability of
an rdataset or to normalize TTLs, and the code to determine
whether validation is necessary has been simplified.
2025-08-05 12:16:36 +02: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
51a4e00d1d
reduce steps for negative caching
whenever ncache_adderesult() was called, some preparatory code
was run first; this has now been moved into a single function
negcache() to reduce code duplication.
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
5d56df23f2
split out cookie checks from resquery_response_continue()
split the code section that handles cookie issues into a
separate function for better readablity.
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
Ondřej Surý
f23bdc29ef
Document the current default stack sizes on different systems
The default stack sizes varies between operating systems and between
different system libc libraries from 128kB (Alpine Linux with MUSL) to
8M (Linux with glibc).  Document the different values used to justify
the value of THREAD_MINSTACKSIZE (currently set to 1MB).
2025-08-05 10:46:09 +02:00
Ondřej Surý
96dad96ae5
Add support for setting thread stack size
When running the isc_quota unit test with less than usual amount of
RAM (e.g. in a CI for architectures with 32 bits of address space),
the pthread_create() function fails with the "Resource temporarily
unavailable (11):" error code.

Add functions to get and set the thread stack size (if requested),
and use these to set the thread stack size to smaller value in the
isc_quota unit test.
2025-08-05 10:46:09 +02:00
Mark Andrews
c47615094e Add support for parsing and displaying DSYNC rdata type 2025-08-05 17:27:44 +10: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
Matthijs Mekking
2f70a0ef12 Add ede for zone with rpz cname override policy
When the zone is configured with a CNAME override policy, also add the
configured EDE code.

When the zone is contains a wildcard CNAME, also add the configured
EDE code.
2025-08-05 08:35:51 +02:00
Ondřej Surý
3a06c24962
Silence "may be truncated" warnings
Use memccpy() instead of strncpy() for safe string manipulation.
2025-08-04 15:38:17 +02:00
Ondřej Surý
f2e107508a
Add rcu_barrier() to isc__log_shutdown()
There is a data race when QP is reclaiming chunks on the call_rcu
threads and it tries to log the number of reclaimed chunks while the
server is shuttingdown.  Workaround this by adding rcu_barrier() before
shuttingdown the global log context.
2025-08-04 11:29:54 +02:00
Ondřej Surý
f7e5c1db38
Change the 'isc_g_mctx' to be always available
This required couple of internal changes to the isc_mem_debugging.

The isc_mem_debugging is now internal to isc_mem unit and there are
three new functions:

1. isc_mem_setdebugging() can change the debugging setting for an
   individual memory context.  This is need for the memory contexts used
   for OpenSSL, libxml and libuv accounting as recording and tracing
   memory is broken there.

2. isc_mem_debugon() / isc_mem_debugoff() can be used to change default
   memory debugging flags as well as debugging flags for isc_g_mctx.

Additionally, the memory debugging is inconsistent across the code-base.
For now, we are keeping the existing flags, but three new environment
variables have been added 'ISC_MEM_DEBUGRECORD', 'ISC_MEM_DEBUGTRACE'
and 'ISC_MEM_DEBUGUSAGE' to set the global debugging flags at any
program using the memory contexts.
2025-08-04 11:29:50 +02:00
Ondřej Surý
74726b3313
Add and use global memory context called isc_g_mctx
Instead of having individual memory contexts scattered across different
files and called different names, add a single memory context called
isc_g_mctx that replaces named_g_mctx and various other global memory
contexts in various utilities and tests.
2025-08-04 11:29:26 +02:00
Mark Andrews
8aa130f253 validator.c:check_signer now clones val->sigrdataset
Spurious validation failures were traced back to check_signer looping
over val->sigrdataset directly.  Cloning val->sigrdataset prevents
check_signer from interacting with callers that are also looping
over val->sigrdataset.
2025-07-31 19:21:32 -07:00
Colin Vidal
7747ac8aed plugin expand path automatically adds extension
If a plugin is configured without the extension,
`ns_plugin_expandpath()` automatically take cares of appending the
suffix to the path. The way it works is by checking if a file exists at
the expanded path. If it doesn't, it assumes the plugin path (or name)
doesn't have the extension and append the extension (which is
platform-specific) to the actual path.
2025-07-28 23:08:04 +02: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
Ondřej Surý
933dcc18ee Reword the 'shut down hung fetch while resolving' message
The log message 'shut down hung fetch while resolving' may be confusing
because no detection of hung fetches actually takes place, but rather
the timer on the fetch context expires and the resolver gives up.

Change the log message to actually say that instead of the original
cryptic message about hung fetch.
2025-07-23 22:37:56 +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
Ondřej Surý
855960ce46
Rename 'free' variable to 'nfree' to not clash with free()
The beauty and horrors of the C - the compiler properly detects variable
shadowing, but you can freely shadow a standard function 'free()' with
variable called 'free'.  And if you reference 'free()' just as 'free'
you get the function pointer which means you can do also pointer
arithmetics, so 'free > 0' is always valid even when you delete the
local variable.

Replace the local variables 'free' with a name that doesn't shadow the
'free()' function to prevent future hard to detect bugs.
2025-07-22 09:32:56 +02:00
Mark Andrews
7de4207cb6 Fix find_coveringnsec in qpcache.c
dns_qp_lookup was returning ISC_R_NOTFOUND rather than DNS_R_PARTIALMATCH
when there wasn't a parent with a NSEC record in the cache.  This was
causing find_coveringnsec to fail rather than returing the covering NSEC.
2025-07-21 17:05:50 +02:00
Alessio Podda
fdbcdcfc06 Remove unused link field from rdatacommon
The field link in rdatacommon is unused. This change should save 16
bytes for each rdata we create.
2025-07-17 12:57:51 +02: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
Andoni Duarte Pintado
ffee986ae0 Merge tag 'v9.21.10' 2025-07-16 17:16:27 +02:00