Commit graph

53 commits

Author SHA1 Message Date
Evan Hunt
a52b17d39b
remove isc_task completely
as there is no further use of isc_task in BIND, this commit removes
it, along with isc_taskmgr, isc_event, and all other related types.

functions that accepted taskmgr as a parameter have been cleaned up.
as a result of this change, some functions can no longer fail, so
they've been changed to type void, and their callers have been
updated accordingly.

the tasks table has been removed from the statistics channel and
the stats version has been updated. dns_dyndbctx has been changed
to reference the loopmgr instead of taskmgr, and DNS_DYNDB_VERSION
has been udpated as well.
2023-02-16 18:35:32 +01:00
Tony Finch
6927a30926 Remove do-nothing header <isc/print.h>
This one really truly did nothing. No lines added!
2023-02-15 16:44:47 +00:00
Ondřej Surý
28fe8104ee
Add isc_hashmap_find() DbC check for valuep
This adds DbC check, so we don't pass non-NULL memory for a valued to
the isc_hashmap_find() function.
2023-02-15 09:30:04 +01:00
Evan Hunt
7fd78344e0 refactor isc_ratelimiter to use loop callbacks
the rate limter now uses loop callbacks rather than task events.
the API for isc_ratelimiter_enqueue() has been changed; we now pass
in a loop, a callback function and a callback argument, and
receive back a rate limiter event object (isc_rlevent_t). it
is no longer necessary for the caller to allocate the event.

the callback argument needs to include a pointer to the rlevent
object so that it can be freed using isc_rlevent_free(), or by
dequeueing.
2023-01-31 21:41:19 -08:00
Ondřej Surý
3d4e41d076 Remove the total memory counter
The total memory counter had again little or no meaning when we removed
the internal memory allocator.  It was just a monotonic counter that
would count add the allocation sizes but never subtracted anything, so
it would be just a "big number".
2023-01-24 17:57:16 +00:00
Mark Andrews
5c06c67001 Remove conditional around mock tests for OpenBSD
We now use multiple barriers.
2023-01-20 13:32:25 +00:00
Artem Boldariev
7962e7f575 tlsctx_client_session_cache_new() -> tlsctx_client_session_create()
Additionally to renaming, it changes the function definition so that
it accepts a pointer to pointer instead of returning a pointer to the
new object.

It is mostly done to make it in line with other functions in the
module.
2022-12-23 11:10:11 +02:00
Artem Boldariev
5a4861aff6 Add missing "dnsstream_utils_test_data.h" to the Makefile.am
This commit ensures that "dnsstream_utils_test_data.h" is referenced
by Makefile.am and, thus, is not missing from a created tarball.
2022-12-21 14:18:04 +02:00
Ondřej Surý
6cb6373b5a Convert Stream DNS to use isc_buffer API
Drop the whole isc_dnsbuffer API and use new improved isc_buffer API
that provides same functionality as the isc_dnsbuffer unit now.
2022-12-20 22:13:53 +02:00
Artem Boldariev
4860b66fba Make isc_nm_tlssocket unit tests available in non DoH-enabled builds
This commit ensures that generic TLS unit tests are available in non
DoH-enabled builds, as isc_nm_tlssocket is not tied exclusively to the
DoH implementation anymore.
2022-12-20 22:13:53 +02:00
Artem Boldariev
85cefb80f8 Re-purpose TLS DNS and TCP DNS unit tests for Stream DNS
This commit modifies the existing unit tests for TLS DNS and TCP DNS
in such a way that the new Stream DNS transport is used as it is
intended to be a drop-in replacement for these two transports.
2022-12-20 22:13:52 +02:00
Artem Boldariev
ae63471e50 Add a set of unit tests for dnsbuffer_t and dnsstream_assembler_t
This commit adds a set of unit tests for isc_dnsbuffer_t and
isc_dnsstream_assembler_t which help to verify that they work as
expected.
2022-12-20 21:24:45 +02:00
Ondřej Surý
2ddea1e41c
Add a static pre-allocated buffer to isc_buffer_t
When the buffer is allocated via isc_buffer_allocate() and the size is
smaller or equal ISC_BUFFER_STATIC_SIZE (currently 512 bytes), the
buffer will be allocated as a flexible array member in the buffer
structure itself instead of allocating it on the heap.  This should help
when the buffer is used on the hot-path with small allocations.
2022-12-20 19:13:48 +01:00
Ondřej Surý
6bd2b34180
Enable auto-reallocation for all isc_buffer_allocate() buffers
When isc_buffer_t buffer is created with isc_buffer_allocate() assume
that we want it to always auto-reallocate instead of having an extra
call to enable auto-reallocation.
2022-12-20 19:13:48 +01:00
Ondřej Surý
2a94123d5b
Refactor the isc_buffer_{get,put}uintN, add isc_buffer_peekuintN
The Stream DNS implementation needs a peek methods that read the value
from the buffer, but it doesn't advance the current position.  Add
isc_buffer_peekuintX methods, refactor the isc_buffer_{get,put}uintN
methods to modern integer types, and move the isc_buffer_getuintN to the
header as static inline functions.
2022-12-20 19:13:48 +01:00
Ondřej Surý
aea251f3bc
Change the isc_buffer_reserve() to take just buffer pointer
The isc_buffer_reserve() would be passed a reference to the buffer
pointer, which was unnecessary as the pointer would never be changed
in the current implementation.  Remove the extra dereference.
2022-12-20 19:13:48 +01:00
Ondřej Surý
7cefcb6184
Allow zero length keys in isc_hashmap
In case, we are trying to hash the empty key into the hashmap, the key
is going to have zero length.  This might happen in the unit test.
Allow this and add a unit test to ensure the empty zero-length key
doesn't hash to slot 0 as SipHash 2-4 (our hash function of choice) has
no problem with zero-length inputs.
2022-12-14 17:59:07 +01:00
Michal Nowak
afdb41a5aa
Update sources to Clang 15 formatting 2022-11-29 08:54:34 +01:00
Tony Finch
00307fe318 Deduplicate time unit conversion factors
The various factors like NS_PER_MS are now defined in a single place
and the names are no longer inconsistent. I chose the _PER_SEC names
rather than _PER_S because it is slightly more clear in isolation;
but the smaller units are always NS, US, and MS.
2022-11-25 13:23:36 +00:00
Ondřej Surý
f46ce447a6
Add isc_hashmap API that implements Robin Hood hashing
Add new isc_hashmap API that differs from the current isc_ht API in
several aspects:

1. It implements Robin Hood Hashing which is open-addressing hash table
   algorithm (e.g. no linked-lists)

2. No memory allocations - the array to store the nodes is made of
   isc_hashmap_node_t structures instead of just pointers, so there's
   only allocation on resize.

3. The key is not copied into the hashmap node and must be also stored
   externally, either as part of the stored value or in any other
   location that's valid as long the value is stored in the hashmap.

This makes the isc_hashmap_t a little less universal because of the key
storage requirements, but the inserts and deletes are faster because
they don't require memory allocation on isc_hashmap_add() and memory
deallocation on isc_hashmap_delete().
2022-11-10 15:07:19 +01:00
Artem Boldariev
cad73b95bf TLS DNS unit tests: do not share the port with TCP DNS tests
TLS DNS unit tests were sharing the port with TCP DNS tests by
mistake. That could have caused conflicts between the two, when
running the unit tests in parallel. This commit fixes that.
2022-11-01 14:42:08 +02:00
Artem Boldariev
5167cc5982 TCP and TLS DNS tests: properly pass connection callback
After the loop manager refactoring TCP DNS and TLS DNS unit tests
ended up broken.

The problem is that in these unit tests the code is written in such a
way that for establishing a new connection tcpdns_connect() and
tlsdns_connect() functions are used. However, in these tests as a
connection callback function connect_connect_cb() is used. The
function logic is responsible for determining the function for
establishing subsequent connection.

To do so, it called get_stream_connect_function() ... which can return
only tcp_connect() or tls_connect(), not tcpdns_connect() or
tlsdns_connect(). That is definitely *not* what was implied.

All this time the unit tests were testing something, but now what was
intended.

This commit fixes the problem by passing the tcpdns_connect() and
tlsdns_connect() function pointers to connect_connect_cb().
2022-11-01 14:42:08 +02:00
Evan Hunt
dc878e3098 isc_async_run() runs events in reverse order
when more than one event was scheduled in the isc_aysnc queue,
they were executed in reverse order. we need to pull events
off the back of queue instead the front, so that uv_loop will
run them in the right order.

note that isc_job_run() has the same behavior, because it calls
uv_idle_start() directly. in that case we just document it so
it'll be less surprising in the future.
2022-10-31 05:43:45 -07:00
Ondřej Surý
6ba0a22627
Change the return type of isc_lex_create() to void
The isc_lex_create() cannot fail, so cleanup the return type from
isc_result_t to void.
2022-10-26 12:55:06 +02:00
Ondřej Surý
ed37949d5f Restore ignoring ISC_R_CONNREFUSED in connect_read_cb
In ac4cc8443d, the ISC_R_CONNREFUSED was
removed in connect_read_cb, but it can actually happen in the udp_test:

    [ RUN      ] udp_recv_send
    connect_read_cb(0x7f2c2801a270, connection refused, (nil))
2022-10-12 19:21:42 +02:00
Ondřej Surý
076cdf7444
Gracefully handle ISC_R_SHUTTINGDOWN in udp__send_cb
The ISC_R_SHUTTINGDOWN should be handled the same as ISC_R_CANCELED in
the udp__send_cb(), as we might be sending the data while the
loopmgr/netmgr shutdown has been initiated.
2022-10-12 15:36:25 +02:00
Ondřej Surý
af257140e6
Make sure the unit test listening and connecting ports are different
In rare circumstances, the UDP port for the listening socket and the UDP
port for the connecting socket might be the same.  Because we use the
"reuse" port socket option, this isn't caught when binding the socket,
and thus the connected client socket could send a datagram to itself,
completely bypassing the server.  This doesn't happen under normal
operation mode because `named` is listening on a privileged port (53),
and even if not, it doesn't usually talk to itself as the tests do.

Pick an arbitrary port for listening (9153-9156) that is outside the
ephemeral port range for the network manager related unit tests (except
the `doh_test).
2022-10-12 15:36:25 +02:00
Ondřej Surý
d7cfb7c792
Retry on timeout in the UDP recv_one, recv_two and double_read tests
Since we are testing UDP on the localhost and the same interface, the
UDP datagrams can't get lost.  Change the connect read callback, so it
starts reading again on the timeout instead of just getting stuck, and
fail when any other result codes than ISC_R_SUCCESS and ISC_R_TIMEDOUT
are received because we don't expect them to happen in these simple
tests.
2022-10-12 15:33:58 +02:00
Artem Boldariev
070d373c56 DoH unit test: remove broken remnants of slowdown logic
This commit removes broken remnants of unit test slowdown logic, which
caused unit test hangs on platforms susceptible to "too many open
files" error, notably OpenBSD.
2022-10-12 16:24:04 +03:00
Ondřej Surý
ac4cc8443d
Ignore additional return codes in the netmgr unit tests
There was inconsistency in which error codes would get accepted and
ignored in the network manager unit test callbacks.  Add following
results, so we just detach the handle instead of causing assertion
failure:

* ISC_R_SHUTTINGDOWN - when the network manager is shutting down
* ISC_R_CANCELED - the socket has been shut down
* ISC_R_EOF - the (TCP) communication has ended on the other side
* ISC_R_CONNECTIONRESET - the TCP connection was reset

This should fix some of the spurious unit test failures.
2022-10-12 15:07:53 +02:00
Ondřej Surý
02c42a20b7
Handle double timeout in udp_cancel_read test
If sending took too long the isc_nm_read() could timeout twice, leading
to extra 'cread' counter in the udp_cancel_read test.  Increase the
cread counter only on ISC_R_EOF (canceled read) and deal with the
multiple ISC_R_TIMEOUTS gracefully.
2022-10-11 15:01:35 +02:00
Ondřej Surý
dbf5672f32
Replace isc_mem_*_aligned(..., alignment) with isc_mem_*x(..., flags)
Previously, the isc_mem_get_aligned() and friends took alignment size as
one of the arguments.  Replace the specific function with more generic
extended variant that now accepts ISC_MEM_ALIGN(alignment) for aligned
allocations and ISC_MEM_ZERO for allocations that zeroes
the (re-)allocated memory before returning the pointer to the caller.
2022-10-05 16:44:05 +02:00
Ondřej Surý
c14a4ac763
Add a case-insensitive option directly to siphash 2-4 implementation
Formerly, the isc_hash32() would have to change the key in a local copy
to make it case insensitive.  Change the isc_siphash24() and
isc_halfsiphash24() functions to lowercase the input directly when
reading it from the memory and converting the uint8_t * array to
64-bit (respectively 32-bit numbers).
2022-10-04 10:32:40 +02:00
Ondřej Surý
f7fc48a2ba
Add isc_ratelimiter API unit tests
The isc_ratelimiter API was missing unit tests.

Add a new set of unit tests for the isc_ratelimiter API.
2022-09-30 10:36:30 +02:00
Ondřej Surý
2d2022a509
Make the debugging flags local to the memory context
Previously, the isc_mem_debugging would be single global variable that
would affect the behavior of the memory context whenever it would be
changed which could be after some allocation were already done.

Change the memory debugging options to be local to the memory context
and immutable, so all allocations within the same memory context are
treated the same.
2022-09-27 17:10:41 +02:00
Ondřej Surý
0086ebf3fc
Bump the libuv requirement to libuv >= 1.34.0
By bumping the minimum libuv version to 1.34.0, it allows us to remove
all libuv shims we ever had and makes the code much cleaner.  The
up-to-date libuv is available in all distributions supported by BIND
9.19+ either natively or as a backport.
2022-09-27 17:09:10 +02:00
Ondřej Surý
fffd444440
Cleanup the asychronous code in the stream implementations
After the loopmgr work has been merged, we can now cleanup the TCP and
TLS protocols a little bit, because there are stronger guarantees that
the sockets will be kept on the respective loops/threads.  We only need
asynchronous call for listening sockets (start, stop) and reading from
the TCP (because the isc_nm_read() might be called from read callback
again.

This commit does the following changes (they are intertwined together):

1. Cleanup most of the asynchronous events in the TCP code, and add
   comments for the events that needs to be kept asynchronous.

2. Remove isc_nm_resumeread() from the netmgr API, and replace
   isc_nm_resumeread() calls with existing isc_nm_read() calls.

3. Remove isc_nm_pauseread() from the netmgr API, and replace
   isc_nm_pauseread() calls with a new isc_nm_read_stop() call.

4. Disable the isc_nm_cancelread() for the streaming protocols, only the
   datagram-like protocols can use isc_nm_cancelread().

5. Add isc_nmhandle_close() that can be used to shutdown the socket
  earlier than after the last detach.  Formerly, the socket would be
  closed only after all reading and sending would be finished and the
  last reference would be detached.  The new isc_nmhandle_close() can
  be used to close the underlying socket earlier, so all the other
  asynchronous calls would call their respective callbacks immediately.

Co-authored-by: Ondřej Surý <ondrej@isc.org>
Co-authored-by: Artem Boldariev <artem@isc.org>
2022-09-22 14:51:15 +02:00
Ondřej Surý
8d7f173e7c
Add more unit tests for isc_timer
Add more tests that deal with rescheduling and restarting the existing
timer and measure that the timer fired at the expected intervals.
2022-09-22 09:46:25 +02:00
Tony Finch
bd251de035
Move random number re-seeding out of the hot path
Instead of checking if we need to re-seed for every isc_random call,
seed the random number generator in the libisc global initializer
and the per-thread initializer.
2022-09-19 16:27:12 +02:00
Ondřej Surý
f6e4f620b3
Use the semantic patch to do the unsigned -> unsigned int change
Apply the semantic patch on the whole code base to get rid of 'unsigned'
usage in favor of explicit 'unsigned int'.
2022-09-19 15:56:02 +02:00
Ondřej Surý
014da8599f Improve the udp_shutdown_read and udp_cancel_read tests
In the udp_shutdown_read unit test, delay the isc_loopmgr_shutdown() to
the send callback, and in the udp_cancel_read test wait for a single
timed out test, then read again, send an UDP packet and cancel the read
from the send callback.
2022-09-19 14:16:07 +02:00
Ondřej Surý
eac8bc5c1a
Prevent unexpected UDP client read callbacks
The network manager UDP code was misinterpreting when the libuv called
the udp_recv_cb with nrecv == 0 and addr == NULL -> this doesn't really
mean that the "stream" has ended, but the libuv indicates that the
receive buffer can be freed.  This could lead to assertion failure in
the code that calls isc_nm_read() from the network manager read callback
due to the extra spurious callbacks.

Properly handle the extra callback calls from the libuv in the client
read callback, and refactor the UDP isc_nm_read() implementation to be
synchronous, so no datagram is lost between the time that we stop the
reading from the UDP socket and we restart it again in the asychronous
udpread event.

Add a unit test that tests the isc_nm_read() call from the read
callback to receive two datagrams.
2022-09-19 12:20:41 +02:00
Tony Finch
68029bfc9d Tests and benchmark for isc_ascii
The test is to verify basic functionality. The benchmark compares a
number of alternative tolower() implementations on large and small
strings.
2022-09-12 12:23:39 +01:00
Ondřej Surý
37a1be5acc
Split netmgr_test into separate per-transport unit tests
The netmgr_test unit test has been subdivided into tcp_test,
tcpdns_test, tls_test, tlsdns_test, and udp_test components.
These have been updated to use the new loopmgr.
2022-08-26 09:09:25 +02:00
Ondřej Surý
b69e783164
Update netmgr, tasks, and applications to use isc_loopmgr
Previously:

* applications were using isc_app as the base unit for running the
  application and signal handling.

* networking was handled in the netmgr layer, which would start a
  number of threads, each with a uv_loop event loop.

* task/event handling was done in the isc_task unit, which used
  netmgr event loops to run the isc_event calls.

In this refactoring:

* the network manager now uses isc_loop instead of maintaining its
  own worker threads and event loops.

* the taskmgr that manages isc_task instances now also uses isc_loopmgr,
  and every isc_task runs on a specific isc_loop bound to the specific
  thread.

* applications have been updated as necessary to use the new API.

* new ISC_LOOP_TEST macros have been added to enable unit tests to
  run isc_loop event loops. unit tests have been updated to use this
  where needed.
2022-08-26 09:09:24 +02:00
Ondřej Surý
49b149f5fd
Update isc_timer to use isc_loopmgr
* isc_timer was rewritten using the uv_timer, and isc_timermgr_t was
  completely removed; isc_timer objects are now directly created on the
  isc_loop event loops.

* the isc_timer API has been simplified. the "inactive" timer type has
  been removed; timers are now stopped by calling isc_timer_stop()
  instead of resetting to inactive.

* isc_manager now creates a loop manager rather than a timer manager.

* modules and applications using isc_timer have been updated to use the
  new API.
2022-08-25 17:17:07 +02:00
Ondřej Surý
84c90e223f
New event loop handling API
This commit introduces new APIs for applications and signal handling,
intended to replace isc_app for applications built on top of libisc.

* isc_app will be replaced with isc_loopmgr, which handles the
  starting and stopping of applications. In isc_loopmgr, the main
  thread is not blocked, but is part of the working thread set.
  The loop manager will start a number of threads, each with a
  uv_loop event loop running. Setup and teardown functions can be
  assigned which will run when the loop starts and stops, and
  jobs can be scheduled to run in the meantime. When
  isc_loopmgr_shutdown() is run from any the loops, all loops
  will shut down and the application can terminate.

* signal handling will now be handled with a separate isc_signal unit.
  isc_loopmgr only handles SIGTERM and SIGINT for application
  termination, but the application may install additional signal
  handlers, such as SIGHUP as a signal to reload configuration.

* new job running primitives, isc_job and isc_async, have been added.
  Both units schedule callbacks (specifying a callback function and
  argument) on an event loop. The difference is that isc_job unit is
  unlocked and not thread-safe, so it can be used to efficiently
  run jobs in the same thread, while isc_async is thread-safe and
  uses locking, so it can be used to pass jobs from one thread to
  another.

* isc_tid will be used to track the thread ID in isc_loop worker
  threads.

* unit tests have been added for the new APIs.
2022-08-25 12:24:29 +02:00
Mark Andrews
9b7af9d85c Call isc_mutex_destroy(&lasttime_mx); 2022-08-24 16:41:55 +10:00
Ondřej Surý
deae974366 Directly cause assertion failure on pthreads primitives failure
Instead of returning error values from isc_rwlock_*(), isc_mutex_*(),
and isc_condition_*() macros/functions and subsequently carrying out
runtime assertion checks on the return values in the calling code,
trigger assertion failures directly in those macros/functions whenever
any pthread function returns an error, as there is no point in
continuing execution in such a case anyway.
2022-07-13 13:19:32 +02:00
Artem Boldariev
0f9b6a7bc1 *_noresponse, tlsdns_listen_noalpn: csends == 1 is not guaranteed
This commit removes an assertion from the unit test which cannot be
guaranteed.

According to the test, exactly one client send must succeed. However,
it cannot really be guaranteed, as do not start to read data in the
accept callback on the server nor attach to the accepted handle. Thus,
we can expect the connection to be closed soon after we have returned
from the callback.

Interestingly enough, the test would pass just fine on TCP because:

a) there are fewer layers involved and thus there is less processing;

b) it is possible for the data to be sent and end up in an internal OS
socket buffer without being touched by an application's code on the
server. In such a case the client's write callback still would be
called successfully;

There is a chance for the test to succeed over TLS as well (as it
happily did before), but as the code has been changed to close unused
connections as soon as possible, the chance is far slimmer now.

What can be guaranteed is:

* cconnects == 1 (number client connections equals 1);
* saccepts == 1 (number of accepted connections equals 1).
2022-07-12 14:40:22 +03:00