Commit graph

1843 commits

Author SHA1 Message Date
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ý
043f11de3f Remove isc_log_write1() and isc_log_vwrite1() functions
The isc_log_write1() and isc_log_vwrite1() functions were meant to
de-duplicate the messages sent to the isc_log subsystem.  However, they
were never used in an entire code base and the whole mechanism around it
was complicated and very inefficient.  Just remove those, there are
better ways to deduplicate syslog messages inside syslog daemons now.
2024-08-20 12:50:39 +00:00
Ondřej Surý
b2dda86254 Replace isc_log_create/destroy with isc_logconfig_get()
Add isc_logconfig_get() function to get the current logconfig and use
the getter to replace most of the little dancing around setting up
logging in the tools. Thus:

    isc_log_create(mctx, &lctx, &logconfig);
    isc_log_setcontext(lctx);
    dns_log_setcontext(lctx);
    ...
    ...use lcfg...
    ...
    isc_log_destroy();

is now only:

    logconfig = isc_logconfig_get(lctx);
    ...use lcfg...

For thread-safety, isc_logconfig_get() should be surrounded by RCU read
lock, but since we never use isc_logconfig_get() in threaded context,
the only place where it is actually used (but not really needed) is
named_log_init().
2024-08-20 12:50:39 +00:00
Ondřej Surý
a8a689531f Use single logging context for everything
Instead of juggling different logging context, use one single logging
context that gets initialized in the libisc constructor and destroyed in
the libisc destructor.

The application is still responsible for creating the logging
configuration before using the isc_log API.

This patch is first in the series in a way that it is transparent for
the users of the isc_log API as the isc_log_create() and
isc_log_destroy() are now thin shims that emulate the previous
functionality, but it isc_log_create() will always return internal
isc__lctx pointer and isc_log_destroy() will actually not destroy the
internal isc__lctx context.

Signed-off-by: Ondřej Surý <ondrej@isc.org>
2024-08-20 12:50:39 +00:00
Ondřej Surý
122a142241 Use constexpr for NS_PER_SEC and friends constants
The contexpr introduced in C23 standard makes perfect sense to be used
instead of preprocessor macros - the symbols are kept, etc.  Define
ISC_CONSTEXPR to be `constexpr` for C23 and `static const` for the older
C standards.  Use the newly introduced macro for the NS_PER_SEC and
friends time constants.
2024-08-19 09:08:55 +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
Ondřej Surý
39aef50b9b
Move the dst__openssl_toresult to isc_tls unit
Since the enable_fips_mode() now resides inside the isc_tls unit, BIND 9
would fail to compile when FIPS mode was enabled as the DST subsystem
logging functions were missing.

Move the crypto library logging functions from the openssl_link unit to
isc_tls unit and enhance it, so it can now be used from both places
keeping the old dst__openssl_toresult* macros alive.
2024-08-08 11:59:41 +02:00
Aydın Mercan
f58ed932d8
use only c23 or c11 noreturn specifiers
Since we require C11 or greater, we can depend on using either _Noreturn
or [[noreturn]].
2024-08-07 18:27:40 +03:00
Aydın Mercan
5dbb560747 remove the crc64 implementation
CRC-64 has been added for map files. Now that the map file format has
been removed, there isn't a reason to keep the implementation.
2024-08-05 11:21:25 +00:00
Ondřej Surý
37dbd57c16
Fix the assertion failure when putting 48-bit number to buffer
When putting the 48-bit number into a fixed-size buffer that's exactly 6
bytes, the assertion failure would occur as the 48-bit number is
internally represented as 64-bit number and the code was checking if
there is enough space for `sizeof(val)`.  This causes assertion failure
when otherwise valid TSIG signature has a bad timing information.

Specify the size of the argument explicitly, so the 48-bit number
doesn't require 8-byte long buffer.
2024-08-05 09:55:18 +02:00
Ondřej Surý
f158884344 Remove ISC_MUTEX_INITIALIZER
It's hard to get it right on different platforms and it's unused
in BIND 9 anyway.
2024-08-05 07:31:39 +00:00
Ondřej Surý
a9b4d42346 Add isc_queue implementation on top of cds_wfcq
Add an isc_queue implementation that hides the gory details of cds_wfcq
into more neat API.  The same caveats as with cds_wfcq.

TODO: Add documentation to the API.
2024-06-05 09:19:56 +02:00
Mark Andrews
9be1873ef3 Add helper function isc_sockaddr_disabled 2024-06-03 18:34:31 +10:00
Aydın Mercan
49e62ee186 fix typing mistakes in trace macros
The detach function declaration in `ISC__REFCOUNT_TRACE_DECL` had an
returned an accidental implicit int. While not allowed since C99, it
became an error by default in GCC 14.

`ISC_REFCOUNT_TRACE_IMPL` and `ISC_REFCOUNT_STATIC_TRACE_IMPL` expanded
into the wrong macros, trying to declare it again with the wrong number
of parameters.
2024-05-17 18:11:23 -07:00
Mark Andrews
b7de2c7cb9 Clang-format header file changes 2024-05-17 16:03:21 -07:00
Aydın Mercan
09e4fb2ffa
Return the old counter value in isc_stats_increment
Returning the value allows for better high-water tracking without
running into edge cases like the following:

0. The counter is at value X
1. Increment the value (X+1)
2. The value is decreased multiple times in another threads (X+1-Y)
3. Get the value (X+1-Y)
4. Update-if-greater misses the X+1 value which should have been the
   high-water
2024-05-10 12:08:52 +03:00
Mark Andrews
88c48dde5e Stop processing catalog zone changes when shutting down
Abandon catz_addmodzone_cb  and catz_delzone_cb processing if the
loop is shutting down.
2024-05-09 08:17:44 +10:00
Evan Hunt
a5d0e6c4ba add static macros for ISC_REFCOUNT_DECL/IMPL
this commit adds a mechanism to statically declare attach/detach
and ref/unref methods, for objects that are only accessed within
a single C file.
2024-04-30 12:31:48 -07:00
Michal Nowak
f454fa6dea
Update sources to Clang 18 formatting 2024-04-23 13:11:52 +02:00
Evan Hunt
63659e2e3a
complete removal of isc_loop_current()
isc_loop() can now take its place.

This also requires changes to the test harness - instead of running the
setup and teardown outside of th main loop, we now schedule the setup
and teardown to run on the loop (via isc_loop_setup() and
isc_loop_teardown()) - this is needed because the new the isc_loop()
call has to be run on the active event loop, but previously the
isc_loop_current() (and the variants like isc_loop_main()) would work
even outside of the loop because it needed just isc_tid() to work, but
not the full loop (which was mainly true for the main thread).
2024-04-02 10:35:56 +02: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
Ondřej Surý
2367b6a2e1
Reduce sizeof isc_sockaddr from 152 to 48 bytes
After removing sockaddr_unix from isc_sockaddr, we can also remove
sockaddr_storage and reduce the isc_sockaddr size from 152 bytes to just
48 bytes needed to hold IPv6 addresses.
2024-02-08 15:13:47 +01:00
Ondřej Surý
2463e5232d
Use proper padding instead of using alignas()
As it was pointed out, the alignas() can't be used on objects larger
than `max_align_t` otherwise the compiler might miscompile the code to
use auto-vectorization on unaligned memory.

As we were only using alignas() as a way to prevent false memory
sharing, we can use manual padding in the affected structures.
2024-02-08 10:54:35 +01:00
Ondřej Surý
0c18ed7ec6
Remove isc__tls_setfatalmode() function and the calls
With _exit() instead of exit() in place, we don't need
isc__tls_setfatalmode() mechanism as the atexit() calls will not be
executed including OpenSSL atexit hooks.
2024-02-08 08:01:58 +01:00
Ondřej Surý
2c98ccbdba
Use error checking mutex in developer mode on Linux
When developer mode is enabled, use error checking mutex type, so we can
discover wrong use of mutexes faster.
2024-02-07 20:54:05 +01:00
Ondřej Surý
01038d894f
Always use adaptive mutexes on Linux
When adaptive mutexes are available (with glibc), always use them.
Remove the autoconf switch and also fix the static initializer.
2024-02-07 20:54:05 +01:00
Aydın Mercan
197de93bdc
Forward declare mallocx in isc/mem.h
cmocka.h and jemalloc.h/malloc_np.h has conflicting macro definitions.
While fixing them with push_macro for only malloc is done below, we only
need the non-standard mallocx interface which is easy to just define by
ourselves.
2024-01-18 09:34:36 +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
Aydın Mercan
2690dc48d3
Expose the TCP client count in statistics channel
The statistics channel does not expose the current number of TCP clients
connected, only the highwater. Therefore, users did not have an easy
means to collect statistics about TCP clients served over time. This
information could only be measured as a seperate mechanism via rndc by
looking at the TCP quota filled.

In order to expose the exact current count of connected TCP clients
(tracked by the "tcp-clients" quota) as a statistics counter, an
extra, dedicated Network Manager callback would need to be
implemented for that purpose (a counterpart of ns__client_tcpconn()
that would be run when a TCP connection is torn down), which is
inefficient. Instead, track the number of currently-connected TCP
clients separately for IPv4 and IPv6, as Network Manager statistics.
2024-01-17 11:11:12 +03:00
Artem Boldariev
9d052522a0 Add TLS cipher-suites related low-level functionality
This commits adds low-level wrappers on top of
'SSL_CTX_set_ciphersuites()'. These are going to be a foundation
behind the 'cipher-suites' option of the 'tls' statement.
2024-01-12 13:27:59 +02:00
Aydın Mercan
294329da3a Use <isc/atomic.h> instead of <stdatomic.h> directly in <isc/types.h> 2024-01-03 17:04:31 +00:00
Aydın Mercan
9c4dd863a6 Move atomic statscounter next to the non-atomic definition 2023-12-14 09:11:48 +01:00
Artem Boldariev
4a88fc9d5b PROXYv2 over UDP transport
This commit adds a new transport that supports PROXYv2 over UDP. It is
built on top of PROXYv2 handling code (just like PROXY Stream). It
works by processing and stripping the PROXYv2 headers at the beginning
of a datagram (when accepting a datagram) or by placing a PROXYv2
header to the beginning of an outgoing datagram.

The transport is built in such a way that incoming datagrams are being
handled with minimal memory allocations and copying.
2023-12-06 15:15:25 +02:00
Artem Boldariev
9d7343cd7d DoH: add PROXY over TLS support
This commit extends DNS over HTTP(S) transport with PROXY over TLS
support.
2023-12-06 15:15:25 +02:00
Artem Boldariev
eb52015db1 Stream DNS: add PROXY over TLS support
This commit extends Stream DNS with PROXY over TLS support.
2023-12-06 15:15:25 +02:00
Artem Boldariev
3d1b6c48ab Add PROXY over TLS support to PROXY Stream
This commit makes it possible to use PROXY Stream not only over TCP,
but also over TLS. That is, now PROXY Stream can work in two modes as
far as TLS is involved:

1. PROXY over (plain) TCP - PROXYv2 headers are sent unencrypted before
TLS handshake messages. That is the main mode as described in the
PROXY protocol specification (as it is clearly stated there), and most
of the software expects PROXYv2 support to be implemented that
way (e.g. HAProxy);

2. PROXY over (encrypted) TLS - PROXYv2 headers are sent after the TLS
handshake has happened. For example, this mode is being used (only ?)
by "dnsdist". As far as I can see, that is, in fact, a deviation from
the spec, but I can certainly see how PROXYv2 could end up being
implemented this way elsewhere.
2023-12-06 15:15:24 +02:00
Artem Boldariev
eccc3fe0a0 Add PROXYv2 support to DNS over HTTP(S) transport
This commit extends DNS over HTTP(S) transport with PROXYv2 support.
2023-12-06 15:15:24 +02:00
Artem Boldariev
e97903ca14 Add PROXY support to Stream DNS
This commit makes it possible to use Stream DNS on top of PROXY Stream
either directly or indirectly (in the case when TLS is involved).
2023-12-06 15:15:24 +02:00
Artem Boldariev
4437096ba0 Make it possible to use TLS Stream on top of PROXY Stream
This commit modifies TLS Stream to make it possible to use over PROXY
Stream. That is required to add PROVYv2 support into TLS-based
transports (DNS over HTTP, DNS over TLS).
2023-12-06 15:15:24 +02:00
Artem Boldariev
d119d666b3 PROXY Stream transport
This commit adds a new stream-based transport with an interface
compatible with TCP. The transport is built on top of TCP transport
and the new PROXYv2 handling code. Despite being built on top of TCP,
it can be easily extended to work on top of any TCP-like stream-based
transport. The intention of having this transport is to add PROXYv2
support into all existing stream-based DNS transport (DNS over TCP,
DNS over TLS, DNS over HTTP) by making the work on top of this new
transport.

The idea behind the transport is simple after accepting the connection
or connecting to a remote server it enters PROXYv2 handling mode: that
is, it either attempts to read (when accepting the connection) or send
(when establishing a connection) a PROXYv2 header. After that it works
like a mere wrapper on top of the underlying stream-based
transport (TCP).
2023-12-06 15:15:24 +02:00
Artem Boldariev
2c76717881 Add PROXYv2 header utilities
This commit adds a set of utilities for dealing with PROXYv2 headers,
both parsing and generating them. The code has no dependencies from
the networking code and is (for the most part) a "separate library".

The part responsible for handling incoming PROXYv2 headers is
structured as a state machine which accepts data as input and calls a
callback to notify the upper-level code about the data processing
status.

Such a design, among other things, makes it easy to write a thorough
unit test suite for that, as there are fewer dependencies as well as
will not stand in the way of any changes in the networking code.
2023-12-06 15:15:24 +02:00
Ondřej Surý
14bdd21e0a
Refactor the handling of isc_mem overmem condition
Previously, there were two methods of working with the overmem
condition:

1. hi/lo water callback - when the overmem condition was reached
   for the first time, the water callback was called with HIWATER
   mark and .is_overmem boolean was set internally.  Similarly,
   when the used memory went below the lo water mark, the water
   callback would be called with LOWATER mark and .is_overmem
   was reset.  This check would be called **every** time memory
   was allocated or freed.

2. isc_mem_isovermem() - a simple getter for the internal
   .is_overmem flag

This commit refactors removes the first method and move the hi/lo water
checks to the isc_mem_isovermem() function, thus we now have only a
single method of checking overmem condition and the check for hi/lo
water is removed from the hot path for memory contexts that doesn't use
overmem checks.
2023-11-29 14:16:20 +01:00
Ondřej Surý
17da9fed58
Remove AES algorithm for DNS cookies
The AES algorithm for DNS cookies was being kept for legacy reasons, and
it can be safely removed in the next major release.  Remove both the AES
usage for DNS cookies and the AES implementation itself.
2023-11-15 10:31:16 +01:00
Ondřej Surý
79d9360011
Reformat sources with up-to-date clang-format-17 2023-11-13 16:52:35 +01:00
Ondřej Surý
d2e84a4b97
Add ISC_LIST_FOREACH_REV(_SAFE) macros
Add complementary macros to ISC_LIST_FOREACH(_SAFE) that walk the lists
in reverse.

  * ISC_LIST_FOREACH_REV(list, elt, link) - walk the static list from
    tail to head
  * ISC_LIST_FOREACH_REV_SAFE(list, elt, link, next) - walk the list
    from tail to head in a manner that's safe against list member
    deletions
2023-10-25 12:36:13 +02:00
Michal Nowak
dd234c60fe
Update the source code formatting using clang-format-17 2023-10-17 17:47:46 +02:00
Ondřej Surý
d46d51be78 Refactor isc_radix_create to return void
The isc_radix_create() can't fail, so change it to return void.
2023-10-13 14:44:40 +02:00
Ondřej Surý
6afa961534
Don't undef <unit>_TRACE, instead add comment how to enable it
In units that support detailed reference tracing via ISC_REFCOUNT
macros, we were doing:

    /* Define to 1 for detailed reference tracing */
    #undef <unit>_TRACE

This would prevent using -D<unit>_TRACE=1 in the CFLAGS.

Convert the above mentioned snippet with just a comment how to enable
the detailed reference tracing:

    /* Add -D<unit>_TRACE=1 to CFLAGS for detailed reference tracing */
2023-10-13 11:40:16 +02:00
Ondřej Surý
3340c82b99
Improve isc_refcount with initializer and implicit destroy
Add ISC_REFCOUNT_INITIALIZER(x) macro and implicitly call
isc_refcount_destroy() in the ISC_REFCOUNT_IMPL() macros
to reduce code duplicities.
2023-09-24 10:08:56 +02:00
Michał Kępień
fc0ee66063 Merge tag 'v9.19.17' 2023-09-20 16:45:47 +02:00
Ondřej Surý
3230c8e369
Add isc_sockaddr_hash_ex that can be used in incremental hashing
Add a sockaddr hashing function that can be used as part of incremental
hashing.
2023-09-19 19:56:33 +02:00
Ondřej Surý
9f40eee0a8
Remove isc_hash_function macro
The last two users of 64-bit isc_hash_function() macro were removed in
the previous commits, remove the macro as well.
2023-09-19 19:56:33 +02:00
Ondřej Surý
9d326aaba3
Use incremental hashing in the isc_sockaddr_hash() function
Instead of copying address back and forth when hashing addr+port, we can
use incremental hashing.  Additionally, switch from 64-bit
isc_hash_function to 32-bit isc_hash32() as the resulting value is
32-bit.
2023-09-19 19:51:51 +02:00
Ondřej Surý
26685ce5a8 Remove Raw and FDWatch type of socket statistics
The isc_sockstatscounter_raw* and isc_sockstatscounter_fdwatch was just
a dead code and those counters were not used anywhere.  Remove them.
2023-09-19 18:51:35 +02:00
Ondřej Surý
7aebbec653 Completely remove the Unix Domain Socket support from BIND 9
The Unix Domain Sockets support in BIND 9 has been completely disabled
since BIND 9.18 and it has been a fatal error since then.  Cleanup the
code and the documentation that suggest that Unix Domain Sockets are
supported.
2023-09-19 18:51:35 +02:00
Ondřej Surý
6fd06c461b
Make dns_dispatch bound to threads
Instead of high number of dispatches (4 * named_g_udpdisp)[1], make the
dispatches bound to threads and make dns_dispatchset_t create a dispatch
for each thread (event loop).

This required couple of other changes:

1. The dns_dispatch_createudp() must be called on loop, so the isc_tid()
   is already initialized - changes to nsupdate and mdig were required.

2. The dns_requestmgr had only a single dispatch per v4 and v6.  Instead
   of using single dispatch, use dns_dispatchset_t for each protocol -
   this is same as dns_resolver.
2023-09-16 07:32:17 +02:00
Ondřej Surý
282c4709b8
Rewrite the QID lookup table to cds_lfht
Looking up unique message ID in the dns_dispatch has been using custom
hash tables.  Rewrite the custom hashtable to use cds_lfht API, removing
one extra lock in the cold-cache resolver hot path.
2023-09-16 07:32:17 +02:00
Ondřej Surý
e270266627
Refactor isc_hashmap to accept custom match function
Refactor isc_hashmap to allow custom matching functions.  This allows us
to have better tailored keys that don't require fixed uint8_t arrays,
but can be composed of more fields from the stored data structure.
2023-09-16 07:20:48 +02:00
Ondřej Surý
6ac286d4a3
Implement incremental version of isc_hash32 and isc_hash64
Add support for incremental hashing to the isc_hash unit, both 32-bit
and 64-bit incremental hashing is now supported.

This is commit second in series adding incremental hashing to libisc.
2023-09-12 16:17:06 +02:00
Ondřej Surý
4dd49ac528
Implement incremental version of SipHash 2-4 and HalfSipHash 2-4
When inserting items into hashtables (hashmaps), we might have a
fragmented key (as an example we might want to hash DNS name + class +
type).  We either need to construct continuous key in the memory and
then hash it en bloc, or incremental hashing is required.

This incremental version of SipHash 2-4 algorithm is the first building
block.

As SipHash 2-4 is often used in the hot paths, I've turned the
implementation into header-only version in the process.
2023-09-12 16:17:06 +02:00
Mark Andrews
820b0cceef
Limit isccc_cc_fromwire recursion depth
Named and rndc do not need a lot of recursion so the depth is
set to 10.
2023-09-07 19:46:19 +02:00
Artem Boldariev
6e98b58d15
Add ability to set per jemalloc arena dirty and muzzy decay values
This commit adds couple of functions to change "dirty_decay_ms" and
"muzzy_decay_ms" settings on arenas associated with memory contexts.
2023-09-05 09:39:41 +02:00
Artem Boldariev
8550c52588
Make it possible to create memory contexts backed by jemalloc arenas
This commit extends the internal memory management middleware code in
BIND so that memory contexts backed by dedicated jemalloc arenas can
be created. A new function (isc_mem_create_arena()) is added for that.

Moreover, it extends the existing code so that specialised memory
contexts can be created easily, should we need that functionality for
other future purposes. We have achieved that by passing the flags to
the underlying jemalloc-related calls. See the above
isc_mem_create_arena(), which can serve as an example of this.

Having this opens up possibilities for creating memory contexts tuned
for specific needs.
2023-09-05 09:39:41 +02:00
Ondřej Surý
d9048b3db1
Remove ISC_MEM_ZERO and isc_mem_*x() API
Use the new isc_mem_c*() calloc-like API for allocations that are
zeroed.

In turn, this also fixes couple of incorrect usage of the ISC_MEM_ZERO
for structures that need to be zeroed explicitly.

There are few places where isc_mem_cput() is used on structures with a
flexible member (or similar).
2023-08-31 22:08:35 +02:00
Ondřej Surý
8ac679a980
Remove ISC_MEM_ALIGN() memory flag
The ISC_MEM_ALIGN() was not used anywhere (except mem.c itself), so just
remove the unused flag.
2023-08-31 22:08:35 +02:00
Ondřej Surý
89fcb6f897
Apply the isc_mem_cget semantic patch 2023-08-31 22:08:35 +02:00
Ondřej Surý
6272482113
Checked array allocation arithmetic with isc_mem_get and friends
Add new isc_mem_cget(), isc_mem_creget(), and isc_mem_cput() macros to
complement the isc_mem_callocate() (which works like calloc()).

The overflow checks are implemented as macros in the <isc/mem.h>, so
that the compiler can see that the element size is constant: it should
always be `sizeof(something)`.
2023-08-31 22:08:35 +02:00
Aram Sargsyan
a33dc921dc Fix a condition in isc_dnsstream_assembler_incoming()
Before calling isc_buffer_putmem(), there is a condition to check
that 'buf_size' is greater than 0. At this point 'buf_size' is
guaranteed to be greater than zero, so either the condition is
redundant, or 'unprocessed_size' should be checked instead, which
seems more logical, because calling isc_buffer_putmem() with
'unprocessed_size' being zero is not useful, although harmless.
2023-08-24 11:59:57 +00:00
Aram Sargsyan
9a271371d3 Handle cases when buf_size is zero
The isc_dnsstream_assembler_incoming() inline function expects that
when 'buf_size' is zero, then 'buf' must be NULL. The expectation is
not correct, because those values come from the libuv read callback,
and its documentation notes[1] that 'nread' ('buf_size' here) might
be 0, which does not indicate an error or EOF, but is equivalent to
EAGAIN or EWOULDBLOCK under read(2).

Change the isc_dnsstream_assembler_incoming() inline function to
remove the invalid expectation.

[1] https://docs.libuv.org/en/v1.x/stream.html#c.uv_read_cb
2023-08-24 11:59:57 +00:00
Tony Finch
52fcc9fc0f
Remove some unnecessary token pasting macrology
There used to be an extra layer of indirection in the memory functions
for certain dynamic linking scenarios. This involved variant spellings
like isc__mem and isc___mem. The isc___mem variants were removed in
commit 7de846977b so the token pasting is no longer needed and
only serves to obfuscate.
2023-08-23 14:49:15 +02:00
Tony Finch
c622b349e4
Apply the SET_IF_NOT_NULL() semantic patch
spatch --sp-file cocci/set_if_not_null.spatch --use-gitgrep --dir "." --include-headers --in-place
2023-08-15 12:21:41 +02:00
Tony Finch
0d6dcd217d
A SET_IF_NOT_NULL() macro for optional return values
The SET_IF_NOT_NULL() macro avoids a fair amount of tedious boilerplate,
checking pointer parameters to see if they're non-NULL and updating
them if they are.  The macro was already in the dns_zone unit, and this
commit moves it to the <isc/util.h> header.

I have included a Coccinelle semantic patch to use SET_IF_NOT_NULL()
where appropriate. The patch needs an #include in `openssl_shim.c`
in order to work.
2023-08-15 12:04:29 +02:00
Ondřej Surý
b6b0d81a36
Cleanup the __tsan_acquire/__tsan_release
With ThreadSanitizer support added to the Userspace RCU, we no longer
need to wrap the call_rcu and caa_container_of with
__tsan_{acquire,release} hints.  Remove the direct calls to
__tsan_{acquire,release} and the isc_urcu_{container,cleanup} macros.
2023-07-28 08:59:08 +02:00
Ondřej Surý
dc3e07572b
Workaround AddressSanitizer overzealous check
The cds_lfht_for_each_entry and cds_lfht_for_each_entry_duplicate macros
had a code that operated on the NULL pointer, at the end of the list it
was calling caa_container_of() on the NULL pointer in the init-clause
and iteration-expression, but the result wasn't actually used anywhere
because the cond-expression in the for loop has prevented executing
loop-statement.  This made AddressSanitizer notice the invalid operation
and rightfully complain.

This was reported to the upstream and fixed there.  Pull the upstream
fix into our <isc/urcu.h> header, so our CI checks pass.
2023-07-27 15:21:39 +02:00
Ondřej Surý
5321c474ea Refactor isc_stats_create() and its downstream users to return void
The isc_stats_create() can no longer return anything else than
ISC_R_SUCCESS.  Refactor isc_stats_create() and its variants in libdns,
libns and named to just return void.
2023-07-27 11:37:44 +02:00
Evan Hunt
e37d02905c
add isc_loop_now() to get consistent time
isc_loop_now() is a front-end to uv_now(), returning the start
time of the current event loop tick.
2023-07-19 15:32:21 +02:00
Evan Hunt
4db150437e
clean up unused dns_db methods
to reduce the amount of common code that will need to be shared
between the separated cache and zone database implementations,
clean up unused portions of dns_db.

the methods dns_db_dump(), dns_db_isdnssec(), dns_db_printnode(),
dns_db_resigned(), dns_db_expirenode() and dns_db_overmem() were
either never called or were only implemented as nonoperational stub
functions: they have now been removed.

dns_db_nodefullname() was only used in one place, which turned out
to be unnecessary, so it has also been removed.

dns_db_ispersistent() and dns_db_transfernode() are used, but only
the default implementation in db.c was ever actually called. since
they were never overridden by database methods, there's no need to
retain methods for them.

in rbtdb.c, beginload() and endload() methods are no longer defined for
the cache database, because that was never used (except in a few unit
tests which can easily be modified to use the zone implementation
instead).  issecure() is also no longer defined for the cache database,
as the cache is always insecure and the default implementation of
dns_db_issecure() returns false.

for similar reasons, hashsize() is no longer defined for zone databases.

implementation functions that are shared between zone and cache are now
prepended with 'dns__rbtdb_' so they can become nonstatic.

serve_stale_ttl is now a common member of dns_db.
2023-07-17 14:50:25 +02:00
Tony Finch
81d73600c1
Add isc_mem_callocate() for safer array allocation
As well as clearing the fresh memory, `calloc()`-like functions must
ensure that the count and size do not overflow when multiplied.

Use `isc_mem_callocate()` in `isc__uv_calloc()`.
2023-06-27 12:38:09 +02:00
Tony Finch
7474cad4ad
Add <isc/overflow.h> for checked mul, add, and sub
The `ISC_OVERFLOW_XXX()` macros are usually wrappers around
`__builtin_xxx_overflow()`, with alternative implementations
for compilers that lack the builtins.

Replace the overflow checks in `isc/time.c` with the new macros.
2023-06-27 12:38:09 +02:00
Ondřej Surý
a8e6c3b8f7
Make isc_result tables smaller
The isc_result_t enum was to sparse when each library code would skip to
next << 16 as a base.  Remove the huge holes in the isc_result_t enum to
make the isc_result tables more compact.

This change required a rewrite how we map dns_rcode_t to isc_result_t
and back, so we don't ever return neither isc_result_t value nor
dns_rcode_t out of defined range.
2023-06-15 15:32:04 +02:00
Mark Andrews
e6e4ac05b8 Fix typo in synchronize_rcu macro (add h)
synchronize_rcu has not been used until now in BIND9 and there
was a typo in the define (a 'h' was missing).
2023-06-06 08:10:09 +10:00
Ondřej Surý
f760ee3f8c
Disable URCU inlining if inlined rcu_dereference() fails to compile
In some cases, the inlined version rcu_dereference() would not compile
when working on pointer to opaque struct (namely Ubuntu Jammy).  Detect
such condition in the autoconf and disable the inlining of the small
functions if it breaks the build.
2023-06-01 16:51:38 +02:00
Michał Kępień
6029010dd2
Remove <isc/cmocka.h>
The last use of the cmocka_add_test_byname() helper macro was removed in
commit 63fe9312ff.  Remove the
<isc/cmocka.h> header that defines it.
2023-05-18 15:12:23 +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
fc770a8bd0
Remove the now-unused ISC_STACK
We are using the liburcu concurrent data structures instead.
2023-05-12 20:49:43 +01:00
Tony Finch
c377e0a9e3
Help thread sanitizer to cope with liburcu
All the places the qp-trie code was using `call_rcu()` needed
`__tsan_release()` and `__tsan_acquire()` annotations, so
add a couple of wrappers to encapsulate this pattern.

With these wrappers, the tests run almost clean under thread
sanitizer. The remaining problems are due to `rcu_barrier()`
which can be suppressed using `.tsan-suppress`. It does not
suppress the whole of `liburcu`, because we would like thread
sanitizer to detect problems in `call_rcu()` callbacks, which
are called from `liburcu`.

The CI jobs have been updated to use `.tsan-suppress` by
default, except for a special-case job that needs the
additional suppressions in `.tsan-suppress-extra`.

We might be able to get rid of some of this after liburcu gains
support for thread sanitizer.

Note: the `rcu_barrier()` suppression is not entirely effective:
tsan sometimes reports races that originate inside `rcu_barrier()`
but tsan has discarded the stack so it does not have the
information required to suppress the report. These "races" can
be made much easier to reproduce by adding `atexit_sleep_ms=1000`
to `TSAN_OPTIONS`. The problem with tsan's short memory can be
addressed by increasing `history_size`: when it is large enough
(6 or 7) the `rcu_barrier()` stack usually survives long enough
for suppression to work.
2023-05-12 20:48:31 +01:00
Tony Finch
05ca11e122
Remove isc_qsbr (we are using liburcu instead)
This commit breaks the qp-trie code.
2023-05-12 20:48:31 +01:00
Tony Finch
4f97a679f0
A macro for the size of a struct with a flexible array member
It can be fairly long-winded to allocate space for a struct with a
flexible array member: in general we need the size of the struct, the
size of the member, and the number of elements. Wrap them all up in a
STRUCT_FLEX_SIZE() macro, and use the new macro for the flexible
arrays in isc_ht and dns_qp.
2023-05-12 20:48:31 +01:00
Ondřej Surý
00f1823366
Change the isc_quota API to use cds_wfcqueue internally
The isc_quota API was using locked list of isc_job_t objects to keep the
waiting TCP accepts.  Change the isc_quota implementation to use
cds_wfcqueue internally - the enqueue is wait-free and only dequeue
needs to be locked.
2023-05-12 14:16:25 +02:00
Ondřej Surý
7b1d985de2
Change the isc_async API to use cds_wfcqueue internally
The isc_async API was using lock-free stack (where enqueue operation was
not wait-free).  Change the isc_async to use cds_wfcqueue internally -
enqueue and splice (move the queue members from one list to another) is
nonblocking and wait-free.
2023-05-12 14:16:25 +02:00
Ondřej Surý
7220851f67
Replace glue_cache hashtable with direct link in rdatasetheader
Instead of having a global hashtable with a global rwlock for the GLUE
cache, move the glue_list directly into rdatasetheader and use
Userspace-RCU to update the pointer when the glue_list is empty.

Additionally, the cached glue_lists needs to be stored in the RBTDB
version for early cleaning, otherwise the circular dependencies between
nodes and glue_lists will prevent nodes to be ever cleaned up.
2023-05-12 13:25:39 +02:00
Michal Nowak
31935a3537
Disable ASAN in nsupdate for fatal cases
Clang 16 LeakSanitizer reports a memory leak when dns_request_create()
returned a TLS error in the nsupdate system test. While technically a
memory leak on error handling, it's not a problem because the program is
immediately terminated; nsupdate is not expected to run for a prolonged
time.
2023-05-11 13:39:51 +02:00
Tony Finch
7d1ceaf35d
Move per-thread RCU setup into isc_thread
All the per-loop `libuv` setup remains in `isc_loop`, but the per-thread
RCU setup is moved to `isc_thread` alongside the other per-thread setup.
This avoids repeating the per-thread setup for `call_rcu()` helpers,
and explains a little better why some parts of the per-thread setup
is missing for `call_rcu()` helpers.

This also removes the per-loop `call_rcu()` helpers as we refactored the
isc__random_initialize() in the previous commit.
2023-04-27 12:38:53 +02:00
Tony Finch
e0248bf60f
Simplify isc_thread a little
Remove the `isc_threadarg_t` and `isc_threadresult_t`
typedefs which were unhelpful disguises for `void *`,
and free the dummy jemalloc allocation sooner.
2023-04-27 12:38:53 +02:00
Tony Finch
06f534fa69
Avoid spurious compilation failures in liburcu headers
When liburcu is not installed from a system package, its headers are
not treated as system headers by the compiler, so BIND's -Werror and
other warning options take effect. The liburcu headers have a lot
of inline functions, some of which do not use all their arguments,
which BIND's build treats as an error.
2023-04-27 12:38:53 +02:00
Ondřej Surý
c2c907d728
Improve the Userspace RCU integration
This commit allows BIND 9 to be compiled with different flavours of
Userspace RCU, and improves the integration between Userspace RCU and
our event loop:

- In the RCU QSBR, the thread is put offline when polling and online
  when rcu_dereference, rcu_assign_pointer (or friends) are called.

- In other RCU modes, we check that we are not reading when reaching the
  quiescent callback in the event loop.

- We register the thread before uv_work_run() callback is called and
  after it has finished.  The rcu_(un)register_thread() has a large
  overhead, but that's fine in this case.
2023-04-27 12:38:53 +02:00
Ondřej Surý
ae997d9e21
Add ISC_LIST_FOREACH(_SAFE) macros
There's a recurring pattern walking the ISC_LISTs that just repeats over
and over.  Add two macros:

 * ISC_LIST_FOREACH(list, elt, link) - walk the static list
 * ISC_LIST_FOREACH_SAFE(list, elt, link, next) - walk the list in
   a manner that's safe against list member deletions
2023-04-25 08:16:46 +02:00
Evan Hunt
0393b54afb
add a result code for ENOPROTOOPT, EPROTONOSUPPORT
there was no isc_result_t value for invalid protocol errors
that could be returned from libuv.
2023-04-21 12:42:10 +02:00
Ondřej Surý
b497e90179
Add isc_spinlock unit with shim pthread_spin implementation
The spinlock is small (atomic_uint_fast32_t at most), lightweight
synchronization primitive and should only be used for short-lived and
most of the time a isc_mutex should be used.

Add a isc_spinlock unit which is either (most of the time) a think
wrapper around pthread_spin API or an efficient shim implementation of
the simple spinlock.
2023-04-21 12:10:02 +02:00