Commit graph

78 commits

Author SHA1 Message Date
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
Ondřej Surý
815c47f800
Fix one-definition-rule violation in the tests/ns
Locally, clang reported odr-violation:

    =================================================================
    ==588371==ERROR: AddressSanitizer: odr-violation (0x55555556a060):
      [1] size=256 'client_addrs' ../tests/ns/netmgr_wrap.c:36:18 in /home/ondrej/Projects/bind9/build/tests/ns/query
      [2] size=256 'client_addrs' ../tests/ns/netmgr_wrap.c:36:18 in /home/ondrej/Projects/bind9/build/tests/ns/../libbindtest.so
    These globals were registered at these points:
      [1]:
	#0 0x7ffff785306f in __asan_register_globals ../../../../src/libsanitizer/asan/asan_globals.cpp:350
	#1 0x7ffff6a2a303 in call_init ../csu/libc-start.c:145
	#2 0x7ffff6a2a303 in __libc_start_main_impl ../csu/libc-start.c:347
	#3 0x55555555a084 in _start (/home/ondrej/Projects/bind9/build/tests/ns/query+0x6084) (BuildId: fbe4a3fcf1a249c7d7da69ee8b255a1dbb610c7a)

      [2]:
	#0 0x7ffff785306f in __asan_register_globals ../../../../src/libsanitizer/asan/asan_globals.cpp:350
	#1 0x7ffff7fca71e in call_init elf/dl-init.c:74
	#2 0x7ffff7fca823 in call_init elf/dl-init.c:120
	#3 0x7ffff7fca823 in _dl_init elf/dl-init.c:121
	#4 0x7ffff7fe459f  (/lib64/ld-linux-x86-64.so.2+0x1f59f) (BuildId: 281ac1521b4102509b1c7ac7004db7c1efb81796)

    ==588371==HINT: if you don't care about these errors you may set ASAN_OPTIONS=detect_odr_violation=0
    SUMMARY: AddressSanitizer: odr-violation: global 'client_addrs' at ../tests/ns/netmgr_wrap.c:36:18 in /home/ondrej/Projects/bind9/build/tests/ns/query
    ==588371==ABORTING

Move the client_addrs and client_refs to libtest to prevent this.
2025-07-24 08:46:11 +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ý
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
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
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
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ý
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
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
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
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
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
Ondřej Surý
552cf64a70
Replace isc_mem_destroy() with isc_mem_detach()
Remove legacy isc_mem_destroy() and just use isc_mem_detach() as
isc_mem_destroy() doesn't play well with call_rcu API.
2025-03-05 11:17:17 +01:00
Evan Hunt
afb424c9b6 simplify dns_name_fromtext() interface
previously, dns_name_fromtext() took both a target name and an
optional target buffer parameter, which could override the name's
dedicated buffer. this interface is unnecessarily complex.

we now have two functions, dns_name_fromtext() to convert text
into a dns_name that has a dedicated buffer, and dns_name_wirefromtext()
to convert text into uncompressed DNS wire format and append it to a
target buffer.

in cases where it really is necessary to have both, we can use
dns_name_fromtext() to load the dns_name, then dns_name_towire()
to append the wire format to the target buffer.
2025-02-25 12:53:25 -08:00
Evan Hunt
10accd6260 clean up uses of ISC_R_NOMEMORY
the isc_mem allocation functions can no longer fail; as a result,
ISC_R_NOMEMORY is now rarely used: only when an external library
such as libjson-c or libfstrm could return NULL. (even in
these cases, arguably we should assert rather than returning
ISC_R_NOMEMORY.)

code and comments that mentioned ISC_R_NOMEMORY have been
cleaned up, and the following functions have been changed to
type void, since (in most cases) the only value they could
return was ISC_R_SUCCESS:

- dns_dns64_create()
- dns_dyndb_create()
- dns_ipkeylist_resize()
- dns_kasp_create()
- dns_kasp_key_create()
- dns_keystore_create()
- dns_order_create()
- dns_order_add()
- dns_peerlist_new()
- dns_tkeyctx_create()
- dns_view_create()
- dns_zone_setorigin()
- dns_zone_setfile()
- dns_zone_setstream()
- dns_zone_getdbtype()
- dns_zone_setjournal()
- dns_zone_setkeydirectory()
- isc_lex_openstream()
- isc_portset_create()
- isc_symtab_create()

(the exception is dns_view_create(), which could have returned
other error codes in the event of a crypto library failure when
calling isc_file_sanitize(), but that should be a RUNTIME_CHECK
anyway.)
2025-01-23 15:54:57 -08:00
Michal Nowak
cf76851c75
Drop superfluous isc_mem_get() NULL check
coccinelle v1.1 trips over a superfluous isc_mem_get() NULL check in
tests/libtest/ns.c and reports the following failure in CI:

    EXN: Failure("rule starting on line 26: already tagged token:\nC code context\nFile \"./tests/libtest/ns.c\", line 350, column 1, charpos = 7939\n  around = 'if',\n  whole content = \tif (qctx != NULL) {") in ./tests/libtest/ns.c
2024-12-13 13:52:52 +01:00
Ondřej Surý
2cb5a6210f
Improve the badcache cleaning by adding LRU and using RCU
Instead of cleaning the dns_badcache opportunistically, add per-loop
LRU, so each thread-loop can clean the expired entries.  This also
allows removal of the atomic operations as the badcache entries are now
immutable, instead of updating the badcache entry in place, the old
entry is now deleted from the hashtable and the LRU list, and the new
entry is inserted in the LRU.
2024-11-27 17:44:53 +01:00
Petr Menšík
4fa81253ea Load default listen-on[-v6] values from config.c
Stop using ns_listenlist_default() to set the default listen-on
and listen-on-v6 configuration.  Instead, configure these options
using the default values in config.c.
2024-11-26 15:22:12 -08:00
Ondřej Surý
0258850f20
Remove redundant parentheses from the return statement 2024-11-19 12:27:22 +01:00
Mark Andrews
d8a6ff5c3e Extend ISC_TEST_MAIN for debugging
ISC_TEST_MAIN now supports turning on/off debugging and
running individual tests.
2024-08-22 09:54:39 +10:00
Ondřej Surý
091d738c72 Convert all categories and modules into static lists
Remove the complicated mechanism that could be (in theory) used by
external libraries to register new categories and modules with
statically defined lists in <isc/log.h>.  This is similar to what we
have done for <isc/result.h> result codes.  All the libraries are now
internal to BIND 9, so we don't need to provide a mechanism to register
extra categories and modules.
2024-08-20 12:50:39 +00:00
Ondřej Surý
8506102216 Remove logging context (isc_log_t) from the public namespace
Now that the logging uses single global context, remove the isc_log_t
from the public namespace.
2024-08-20 12:50:39 +00:00
Ondřej Surý
b03e90e0d4 Change the NS_PER_SEC (and friends) from enum to static const
New version of clang (19) has introduced a stricter checks when mixing
integer (and float types) with enums.  In this case, we used enum {}
as C17 doesn't have constexpr yet.  Change the time conversion constants
to be static const unsigned int instead of enum values.
2024-08-19 09:08:55 +00:00
Evan Hunt
a68a77ca86 dns_difftuple_create() cannot fail
dns_difftuple_create() could only return success, so change
its type to void and clean up all the calls to it.

other functions that only returned a result value because of it
have been cleaned up in the same way.
2024-08-05 13:31:38 +00:00
Ondřej Surý
b26079fdaf Don't open route socket if we don't need it
When automatic-interface-scan is disabled, the route socket was still
being opened.  Add new API to connect / disconnect from the route socket
only as needed.

Additionally, move the block that disables periodic interface rescans to
a place where it actually have access to the configuration values.
Previously, the values were being checked before the configuration was
loaded.
2024-08-05 07:31:02 +00:00
Ondřej Surý
1c0564d715
Remove ns_query_init() cannot fail, remove the error paths
As ns_query_init() cannot fail now, remove the error paths, especially
in ns__client_setup() where we now don't have to care what to do with
the connection if setting up the client could fail.  It couldn't fail
even before, but now it's formal.
2024-07-03 09:05:51 +02:00
Aram Sargsyan
f0cde05e06
Implement asynchronous view matching for SIG(0)-signed queries
View matching on an incoming query checks the query's signature,
which can be a CPU-heavy task for a SIG(0)-signed message. Implement
an asynchronous mode of the view matching function which uses the
offloaded signature checking facilities, and use it for the incoming
queries.
2024-06-10 17:33:10 +02:00
Aram Sargsyan
c7f79a0353
Add a quota for SIG(0) signature checks
In order to protect from a malicious DNS client that sends many
queries with a SIG(0)-signed message, add a quota of simultaneously
running SIG(0) checks.

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

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

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

The 'sig0checks-quota-maxwait-ms' option is used to define a maximum
amount of time for named to wait for a quota to appear. If during that
time no new quota becomes available, named will answer to the client
with DNS_R_REFUSED.
2024-06-10 17:33:08 +02:00
Mark Andrews
87e3b9dbf3 Pass a memory context in to dns_cache_create 2024-05-31 15:40:32 +10:00
Evan Hunt
a0bd1e67cd add a test method to print QP keys
add a method qp_test_printkey() to print the name encoded in a QP key.
2024-04-30 15:58:17 -07:00
Evan Hunt
c47fa689d4
use a thread-local variable to get the current running loop
if we had a method to get the running loop, similar to how
isc_tid() gets the current thread ID, we can simplify loop
and loopmgr initialization.

remove most uses of isc_loop_current() in favor of isc_loop().
in some places where that was the only reason to pass loopmgr,
remove loopmgr from the function parameters.
2024-04-02 10:35:56 +02:00
Evan Hunt
92b305be4b add a compile-time option to select default zone and cache DB
by default, QPDB is the database used by named and all tools and
unit tests. the old default of RBTDB can now be restored by using
"configure --with-zonedb=rbt --with-cachedb=rbt".

some tests have been fixed so they will work correctly with either
database.

CHANGES and release notes have been updated to reflect this change.
2024-03-06 10:49:02 +01:00
Evan Hunt
bb4464181a switch database defaults from "rbt" to "qp"
replace the string "rbt" throughout BIND with "qp" so that
qpdb databases will be used by default instead of rbtdb.
rbtdb databases can still be used by specifying "database rbt;"
in a zone statement.
2024-03-06 09:57:24 +01:00
Ondřej Surý
41a0ee1071
Add workaround for jemalloc linking order
Because we don't use jemalloc functions directly, but only via the
libisc library, the dynamic linker might pull the jemalloc library
too late when memory has been already allocated via standard libc
allocator.

Add a workaround round isc_mem_create() that makes the dynamic linker
to pull jemalloc earlier than libc.
2024-01-18 09:34:36 +01:00
Mark Andrews
cbfcdbc199 Adjust message buffer sizes in test code 2023-11-16 11:22:02 +11:00
Evan Hunt
6231fd66af rename QP-related types to use standard BIND nomenclature
changed type names in QP trie code to match the usual convention:
 - qp_node_t -> dns_qpnode_t
 - qp_ref_t -> dns_qpref_t
 - qp_shift_t -> dns_qpshift_t
 - qp_weight_t -> dns_qpweight_t
 - qp_chunk_t -> dns_qpchunk_t
 - qp_cell_t -> dns_qpcell_t
2023-09-28 00:32:39 -07:00
Evan Hunt
3bf23fadb0 improvements to the QP iterator
- make iterators reversible: refactor dns_qpiter_next() and add a new
  dns_qpiter_prev() function to support iterating both forwards and
  backwards through a QP trie.
- added a 'name' parameter to dns_qpiter_next() (as well as _prev())
  to make it easier to retrieve the nodename while iterating, without
  having to construct it from pointer value data.
2023-09-28 00:30:51 -07:00
Evan Hunt
7f0242b8c7 tidy the helper functions for retrieving twigs
- the helper functions for accessing twigs beneath a branch
  (branch_twig_pos(), branch_twig_ptr(), etc) were somewhat confusing
  to read, since several of them were implemented by calling other
  helper functions. they now all show what they're really doing.
- branch_twigs_vector() has been renamed to simply branch_twigs().
- revised some unrelated comments in qp_p.h for clarity.
2023-09-28 00:30:47 -07:00
Evan Hunt
29cf7dceb7 modify dns_qp_findname_ancestor() to return found name
add a 'foundname' parameter to dns_qp_findname_ancestor(),
and use it to set the found name in dns_nametree.

this required adding a dns_qpkey_toname() function; that was
done by moving qp_test_keytoname() from the test library to qp.c.
added some more test cases and fixed bugs with the handling of
relative and empty names.
2023-09-28 07:01:13 +00:00
Ondřej Surý
f5af981831
Change dns_message_create() function to accept memory pools
Instead of creating new memory pools for each new dns_message, change
dns_message_create() method to optionally accept externally created
dns_fixedname_t and dns_rdataset_t memory pools.  This allows us to
preallocate the memory pools in ns_client and dns_resolver units for the
lifetime of dns_resolver_t and ns_clientmgr_t.
2023-09-24 18:07:40 +02:00
Ondřej Surý
c9b4b45943
Replace the linked list of TCP dispatches with hash table
Reusing TCP connections with dns_dispatch_gettcp() used linear linked
list to lookup existing outgoing TCP connections that could be reused.
Replace the linked list with per-loop cds_lfht hashtable to speedup the
lookups.  We use cds_lfht because it allows non-unique node insertion
that we need to check for dispatches in different connection states.
2023-09-16 07:32:18 +02:00
Evan Hunt
a290ed5bd0 remove dns_name_fromstring2()
we don't need two versions of dns_name_fromstring() any longer; we
can just specify an origin value of dns_rootname for absolute names.
2023-08-31 10:29:16 -07:00
Ondřej Surý
d76ab69772 Attach to the dns_dispatchmgr in the dns_view object
The dns_dispatchmgr object was only set in the dns_view object making it
prone to use-after-free in the dns_xfrin unit when shutting down named.

Remove dns_view_setdispatchmgr() and optionally pass the dispatchmgr
directly to dns_view_create() when it is attached and not just assigned,
so the dns_dispatchmgr doesn't cease to exist too early.

The dns_view_getdnsdispatchmgr() is now protected by the RCU lock, the
dispatchmgr reference is incremented, so the caller needs to detach from
it, and the function can return NULL in case the dns_view has been
already shut down.
2023-08-15 10:25:37 -07:00
Ondřej Surý
ea2fe8eea4 Refactor dns_zone_create() to return void
After isc_stats_create() change, the dns_zone_create() cannot fail, so
refactor the function to return void and fix all its uses.
2023-07-27 11:37:44 +02:00
Tony Finch
c319ccd4c9 Fixes for liburcu-qsbr
Move registration and deregistration of the main thread from
`isc_loopmgr_run()` into `isc__initialize()` / `isc__shutdown()`:
liburcu-qsbr fails an assertion if we try to use it from an
unregistered thread, and we need to be able to use it when the
event loops are not running.

Use `rcu_assign_pointer()` and `rcu_dereference()` in qp-trie
transactions so that they properly mark threads as online. The
RCU-protected pointer is no longer declared atomic because
liburcu does not (yet) use standard C atomics.

Fix the definition of `isc_qsbr_rcu_dereference()` to return
the referenced value, and to call the right function inside
liburcu.

Change the thread sanitizer suppressions to match any variant of
`rcu_*_barrier()`
2023-05-15 20:49:42 +00:00
Tony Finch
c890b9b124
Get the tests working with liburcu
Mostly a few qp-trie details to adjust.
2023-05-12 20:48:31 +01:00
Tony Finch
9882a6ef90
The zone table no longer depends on the loop manager
This reverts some of the changes in commit b171cacf4f
because now it isn't necessary to pass the loopmgr around.
2023-05-12 20:48:31 +01:00