2
0
mirror of https://gitlab.isc.org/isc-projects/bind9 synced 2025-08-22 18:19:42 +00:00

338 Commits

Author SHA1 Message Date
Ondřej Surý
7f498cc60d
Give every memory pool a name
Instead of giving the memory pools names with an explicit call to
isc_mempool_setname(), add the name to isc_mempool_create() call to have
all the memory pools an unconditional name.
2025-05-29 05:46:46 +02:00
Evan Hunt
dd9a685f4a simplify code around isc_mem_put() and isc_mem_free()
it isn't necessary to set a pointer to NULL after calling
isc_mem_put() or isc_mem_free(), because those macros take
care of it automatically.
2025-05-28 17:22:32 -07:00
Evan Hunt
8487e43ad9 make all ISC_LIST_FOREACH calls safe
previously, ISC_LIST_FOREACH and ISC_LIST_FOREACH_SAFE were
two separate macros, with the _SAFE version allowing entries
to be unlinked during the loop. ISC_LIST_FOREACH is now also
safe, and the separate _SAFE macro has been removed.

similarly, the ISC_LIST_FOREACH_REV macro is now safe, and
ISC_LIST_FOREACH_REV_SAFE has also been removed.
2025-05-23 13:09:10 -07:00
Aram Sargsyan
74a8acdc8d Separate the single setter/getter functions for TCP timeouts
Previously all kinds of TCP timeouts had a single getter and setter
functions. Separate each timeout to its own getter/setter functions,
because in majority of cases only one is required at a time, and it's
not optimal expanding those functions every time a new timeout value
is implemented.
2025-04-23 17:03:05 +00:00
Aram Sargsyan
70ad94257d Implement tcp-primaries-timeout
The new 'tcp-primaries-timeout' configuration option works the same way
as the existing 'tcp-initial-timeout' option, but applies only to the
TCP connections made to the primary servers, so that the timeout value
can be set separately for them. The default is 15 seconds.

Also, while accommodating zone.c's code to support the new option, make
a light refactoring with the way UDP timeouts are calculated by using
definitions instead of hardcoded values.
2025-04-23 17:03:05 +00:00
Evan Hunt
ad7f744115 use ISC_LIST_FOREACH in more places
use the ISC_LIST_FOREACH pattern in places where lists had
been iterated using a different pattern from the typical
`for` loop: for example, `while (!ISC_LIST_EMPTY(...))` or
`while ((e = ISC_LIST_HEAD(...)) != NULL)`.
2025-03-31 13:45:14 -07: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ý
2aa70fff76
Remove unused isc_mutexblock and isc_condition units
The isc_mutexblock and isc_condition units were no longer in use and
were removed.
2025-03-01 07:33:09 +01:00
Michał Kępień
d6f9785ac6
Enable extraction of exact local socket addresses
Extracting the exact address that each wildcard/TCP socket is bound to
locally requires issuing the getsockname() system call, which libuv
exposes via its uv_*_getsockname() functions.  This is only required for
detailed logging and comes at a noticeable performance cost, so it
should not happen by default.  However, it is useful for debugging
certain problems (e.g. cryptic system test failures), so a convenient
way of enabling that behavior should exist.

Update isc_nmhandle_localaddr() so that it calls uv_*_getsockname() when
the ISC_SOCKET_DETAILS preprocessor macro is set at compile time.
Ensure proper handling of sockets that wrap other sockets.

Set the new ISC_SOCKET_DETAILS macro by default when --enable-developer
is passed to ./configure.  This enables detailed logging in the system
tests run in GitLab CI without affecting performance in non-development
BIND 9 builds.

Note that setting the ISC_SOCKET_DETAILS preprocessor macro at compile
time enables all callers of isc_nmhandle_localaddr() to extract the
exact address of a given local socket, which results e.g. in dnstap
captures containing more accurate information.

Mention the new preprocessor macro in the section of the ARM that
discusses why exact socket addresses may not be logged by default.
2024-12-29 12:32:05 +01:00
Aydın Mercan
d987e2d745
add separate query counters for new protocols
Add query counters for DoT, DoH, unencrypted DoH and their proxied
counterparts. The protocols don't increment TCP/UDP counters anymore
since they aren't the same as plain DNS-over-53.
2024-11-25 13:07:29 +03:00
Ondřej Surý
0258850f20
Remove redundant parentheses from the return statement 2024-11-19 12:27:22 +01:00
Ondřej Surý
679e90a57d Add isc_log_createandusechannel() function to simplify usage
The new
isc_log_createandusechannel() function combines following calls:

    isc_log_createchannel()
    isc_log_usechannel()

calls into a single call that cannot fail and therefore can be used in
places where we know this cannot fail thus simplifying the error
handling.
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ý
827a153d99 Remove superfluous memset() in isc_nmsocket_init()
The tlsstream part of the isc_nmsocket_t gets initialized via designater
initializer and doesn't need the extra memset() later; just remove it.
2024-08-05 07:32:12 +00:00
Ondřej Surý
4c2ac25a95
Limit the number of DNS message processed from a single TCP read
The single TCP read can create as much as 64k divided by the minimum
size of the DNS message.  This can clog the processing thread and trash
the memory allocator because we need to do as much as ~20k allocations in
a single UV loop tick.

Limit the number of the DNS messages processed in a single UV loop tick
to just single DNS message and limit the number of the outstanding DNS
messages back to 23.  This effectively limits the number of pipelined
DNS messages to that number (this is the limit we already had before).
2024-06-10 16:48:54 +02:00
Ondřej Surý
4e7c4af17f
Throttle reading from TCP if the sends are not getting through
When TCP client would not read the DNS message sent to them, the TCP
sends inside named would accumulate and cause degradation of the
service.  Throttle the reading from the TCP socket when we accumulate
enough DNS data to be sent.  Currently this is limited in a way that a
single largest possible DNS message can fit into the buffer.
2024-06-10 16:48:52 +02:00
Matthijs Mekking
c40e5c8653 Call reset_shutdown if uv_tcp_close_reset failed
If uv_tcp_close_reset() returns an error code, this means the
reset_shutdown callback has not been issued, so do it now.
2024-06-03 10:14:47 +02:00
Matthijs Mekking
5b94bb2129 Do not runtime check uv_tcp_close_reset
When we reset a TCP connection by sending a RST packet, do not bother
requiring the result is a success code.
2024-06-03 10:14:47 +02:00
Mark Andrews
dd57db2274 Remove duplicate unreachable code block
This was accidentially left in during the developement of !8299.
2024-02-12 15:18:46 +11:00
Ondřej Surý
15329d471e
Add memory pools for isc_nmsocket_t structures
To reduce memory pressure, we can add light per-loop (netmgr worker)
memory pools for isc_nmsocket_t structures.  This will help in
situations where there's a lot of churn creating and destroying the
nmsockets.
2024-02-08 15:13:47 +01:00
Ondřej Surý
750bd364b5
Reduce the isc_nmsocket_t size from 1840 to 1208 bytes
Embedding isc_nmsocket_h2_t directly inside isc_nmsocket_t had increased
the size of isc_nmsocket_t to 1840 bytes.  Making the isc_nmsocket_h2_t
to be a pointer to the structure and allocated on demand allows us to
reduce the size to 1208 bytes.  While there are still some possible
reductions in the isc_nmsocket_t (embedded tlsstream, streamdns
structures), this was the far biggest drop in the memory usage.
2024-02-08 15:13:47 +01:00
Ondřej Surý
cb1d2e57e9
Remove unused mutex from netmgr
The netmgr->lock was dead code, remove it.
2024-02-07 20:54:05 +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
3c45dd59cb Add a utility function to dump all active sockets on a NM instance
Add the new isc__nm_dump_active_manager() function that can be used
for debugging purposes: it dumps all active sockets withing the
network manager instance.
2023-12-06 15:15:25 +02: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
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
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
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
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ý
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ý
89fcb6f897
Apply the isc_mem_cget semantic patch 2023-08-31 22:08:35 +02:00
Ondřej Surý
0c9cf8fabb
Limit the memory pool for the uvreqs
Set the number of maximum free items for the uvreq memory pool to 64.
2023-08-21 16:34:30 +02:00
Ondřej Surý
f36e118b9a
Limit the number of inactive handles kept for reuse
Instead of growing and never shrinking the list of the inactive
handles (to be reused mostly on the UDP connections), limit the number
of maximum number of inactive handles kept to 64.  Instead of caching
the inactive handles for all listening sockets, enable the caching on on
UDP listening sockets.  For TCP, the handles were cached for each
accepted socket thus reusing the handles only for long-standing TCP
connections, but not reusing the handles across different TCP streams.
2023-08-21 16:34:30 +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
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ý
3b10814569
Fix the streaming read callback shutdown logic
When shutting down TCP sockets, the read callback calling logic was
flawed, it would call either one less callback or one extra.  Fix the
logic in the way:

1. When isc_nm_read() has been called but isc_nm_read_stop() hasn't on
   the handle, the read callback will be called with ISC_R_CANCELED to
   cancel active reading from the socket/handle.

2. When isc_nm_read() has been called and isc_nm_read_stop() has been
   called on the on the handle, the read callback will be called with
   ISC_R_SHUTTINGDOWN to signal that the dormant (not-reading) socket
   is being shut down.

3. The .reading and .recv_read flags are little bit tricky.  The
   .reading flag indicates if the outer layer is reading the data (that
   would be uv_tcp_t for TCP and isc_nmsocket_t (TCP) for TLSStream),
   the .recv_read flag indicates whether somebody is interested in the
   data read from the socket.

   Usually, you would expect that the .reading should be false when
   .recv_read is false, but it gets even more tricky with TLSStream as
   the TLS protocol might need to read from the socket even when sending
   data.

   Fix the usage of the .recv_read and .reading flags in the TLSStream
   to their true meaning - which mostly consist of using .recv_read
   everywhere and then wrapping isc_nm_read() and isc_nm_read_stop()
   with the .reading flag.

4. The TLS failed read helper has been modified to resemble the TCP code
   as much as possible, clearing and re-setting the .recv_read flag in
   the TCP timeout code has been fixed and .recv_read is now cleared
   when isc_nm_read_stop() has been called on the streaming socket.

5. The use of Network Manager in the named_controlconf, isccc_ccmsg, and
   isc_httpd units have been greatly simplified due to the improved design.

6. More unit tests for TCP and TLS testing the shutdown conditions have
   been added.

Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2023-04-20 12:58:32 +02:00
Ondřej Surý
f677cf6b73
Remove unused netmgr->worker->sendbuf
By inspecting the code, it was discovered that .sendbuf member of the
isc__nm_networker_t was unused and just consuming ~64k per worker.
Remove the member and the association allocation/deallocation.
2023-04-14 16:20:14 +02:00
Ondřej Surý
1715cad685
Refactor the isc_quota code and fix the quota in TCP accept code
In e18541287231b721c9cdb7e492697a2a80fd83fc, the TCP accept quota code
became broken in a subtle way - the quota would get initialized on the
first accept for the server socket and then deleted from the server
socket, so it would never get applied again.

Properly fixing this required a bigger refactoring of the isc_quota API
code to make it much simpler.  The new code decouples the ownership of
the quota and acquiring/releasing the quota limit.

After (during) the refactoring it became more clear that we need to use
the callback from the child side of the accepted connection, and not the
server side.
2023-04-12 14:10:37 +02:00
Ondřej Surý
3adba8ce23
Use isc_job_run() for reading from StreamDNS socket
Change the reading in the StreamDNS code to use isc_job_run() instead of
using isc_async_run() for less allocations and more streamlined
execution.
2023-04-12 14:10:37 +02:00
Ondřej Surý
74cbf523b3
Run closehandle_cb on run queue instead of async queue
Instead of using isc_async_run() when closing StreamDNS handle, add
isc_job_t member to the isc_nmhandle_t structure and use isc_job_run()
to avoid allocation/deallocation on the StreamDNS hot-path.
2023-04-12 14:10:37 +02:00
Tony Finch
555690a3c9 Simplify thread spawning
The `isc_trampoline` module had a lot of machinery to support stable
thread IDs for use by hazard pointers. But the hazard pointer code
is gone, and the `isc_loop` module now has its own per-loop thread
IDs.

The trampoline machinery seems over-complicated for its remaining
tasks, so move the per-thread initialization into `isc/thread.c`,
and delete the rest.
2023-03-31 17:21:52 +01:00
Ondřej Surý
2c0a9575d7
Replace __attribute__((unused)) with ISC_ATTR_UNUSED attribute macro
Instead of marking the unused entities with UNUSED(x) macro in the
function body, use a `ISC_ATTR_UNUSED` attribute macro that expans to
C23 [[maybe_unused]] or __attribute__((__unused__)) as fallback.
2023-03-30 23:29:25 +02:00
Ondřej Surý
2846888c57
Attach the accept "client" socket to .listener member of the socket
When accepting a TCP connection in the higher layers (tlsstream,
streamdns, and http) attach to the socket the connection was accepted
on, and use this socket instead of the parent listening socket.

This has an advantage - accessing the sock->listener now doesn't break
the thread boundaries, so we can properly check whether the socket is
being closed without requiring .closing member to be atomic_bool.
2023-03-30 16:10:08 +02:00
Ondřej Surý
45365adb32
Convert sock->active to non-atomic variable, cleanup rchildren
The last atomic_bool variable sock->active was converted to non-atomic
bool by properly handling the listening socket case where we were
checking parent socket instead of children sockets.

This is no longer necessary as we properly set the .active to false on
the children sockets.

Additionally, cleanup the .rchildren - the atomic variable was used for
mutex+condition to block until all children were listening, but that's
now being handled by a barrier.

Finally, just remove dead .self and .active_child_connections members of
the netmgr socket.
2023-03-30 16:10:08 +02:00
Ondřej Surý
e1a4572fd6
Refactor the use of atomics in netmgr
Now that everything runs on their own loop and we don't cross the thread
boundaries (with few exceptions), most of the atomic_bool variables used
to track the socket state have been unatomicized because they are always
accessed from the matching thread.

The remaining few have been relaxed: a) the sock->active is now using
acquire/release memory ordering; b) the various global limits are now
using relaxed memory ordering - we don't really care about the
synchronization for those.
2023-03-30 16:10:08 +02:00
Ondřej Surý
1844590ad9
Refactor isc_job_run to not-make any allocations
Change the isc_job_run() to not-make any allocations.  The caller must
make sure that it allocates isc_job_t - usually as part of the argument
passed to the callback.

For simple jobs, using isc_async_run() is advised as it allocates its
own separate isc_job_t.
2023-03-30 16:00:52 +02:00
Ondřej Surý
639d5065a3
Refactor the isc__nm_uvreq_t to have idle callback
Change the isc__nm_uvreq_t to have the idle callback as a separate
member as we always need to use it to properly close the uvreq.

Slightly refactor uvreq_put and uvreq_get to remove the unneeded
arguments - in uvreq_get(), we always use sock->worker, and in
uvreq_put, we always use req->sock, so there's not reason to pass those
extra arguments.
2023-03-29 21:16:44 +02:00
Ondřej Surý
476198f26c
Use uv_idle API for calling asynchronous connect/read/send callback
Instead of using isc_job_run() that's quite heavy as it allocates memory
for every new job, add uv_idle_t to uvreq union, and use uv_idle API
directly to execute the connect/read/send callback without any
additional allocations.
2023-03-29 21:16:44 +02:00
Evan Hunt
fe7ed2ba24 update stream sockets with bound address/port
when isc_nm_listenstreamdns() is called with a local port of 0,
a random port is chosen. call uv_getsockname() to determine what
the port is as soon as the socket is bound, and add a function
isc_nmsocket_getaddr() to retrieve it, so that the caller can
connect to the listening socket. this will be used in cases
where the same process is acting as both client and server.
2023-03-28 12:38:28 -07:00