Mark Andrews [Thu, 27 Oct 2022 02:22:11 +0000 (13:22 +1100)]
Move the mapping of SIG and RRSIG to ANY
dns_db_findext() asserts if RRSIG is passed to it and
query_lookup_stale() failed to map RRSIG to ANY to prevent this. To
avoid cases like this in the future, move the mapping of SIG and RRSIG
to ANY for qctx->type to qctx_init().
Evan Hunt [Thu, 10 Nov 2022 05:56:16 +0000 (21:56 -0800)]
test failure conditions
verify that updates are refused when the client is disallowed by
allow-query, and update forwarding is refused when the client is
is disallowed by update-forwarding.
verify that "too many DNS UPDATEs" appears in the log file when too
many simultaneous updates are processing.
Evan Hunt [Wed, 9 Nov 2022 01:32:41 +0000 (17:32 -0800)]
move update ACL and update-policy checks before quota
check allow-update, update-policy, and allow-update-forwarding before
consuming quota slots, so that unauthorized clients can't fill the
quota.
(this moves the access check before the prerequisite check, which
violates the precise wording of RFC 2136. however, RFC co-author Paul
Vixie has stated that the RFC is mistaken on this point; it should have
said that access checking must happen *no later than* the completion of
prerequisite checks, not that it must happen exactly then.)
limit the number of simultaneous DNS UPDATE events that can be
processed by adding a quota for update and update forwarding.
this quota currently, arbitrarily, defaults to 100.
also add a statistics counter to record when the update quota
has been exceeded.
Aram Sargsyan [Mon, 12 Dec 2022 09:20:48 +0000 (09:20 +0000)]
Use sizeof(*ptr) for allocating/freeing memory in forward.c
As shown in the previous commit, using sizeof(type_t) is a little
bit more error-prone when copy-pasting code, so extracting the
size information from the pointer which is being dealt with seems
like a better alternative.
Aram Sargsyan [Fri, 9 Dec 2022 12:41:38 +0000 (12:41 +0000)]
Fix dns_fwdtable_addfwd() error path cleanup bug
Free 'sizeof(dns_forwarder_t)' bytes of memory instead of
'sizeof(dns_sockaddr_t)' bytes, because `fwd` is a pointer
to a 'dns_forwarder_t' type structure.
expected_creads can exceed the number of file descriptors on some
platforms.
% ./udp_test
[==========] Running 18 test(s).
[ RUN ] mock_listenudp_uv_udp_open
[ OK ] mock_listenudp_uv_udp_open
[ RUN ] mock_listenudp_uv_udp_bind
[ OK ] mock_listenudp_uv_udp_bind
[ RUN ] mock_listenudp_uv_udp_recv_start
[ OK ] mock_listenudp_uv_udp_recv_start
[ RUN ] mock_udpconnect_uv_udp_open
[ OK ] mock_udpconnect_uv_udp_open
[ RUN ] mock_udpconnect_uv_udp_bind
[ OK ] mock_udpconnect_uv_udp_bind
[ RUN ] mock_udpconnect_uv_udp_connect
[ OK ] mock_udpconnect_uv_udp_connect
[ RUN ] mock_udpconnect_uv_recv_buffer_size
[ OK ] mock_udpconnect_uv_recv_buffer_size
[ RUN ] mock_udpconnect_uv_send_buffer_size
[ OK ] mock_udpconnect_uv_send_buffer_size
[ RUN ] udp_noop
[ OK ] udp_noop
[ RUN ] udp_noresponse
[ OK ] udp_noresponse
[ RUN ] udp_shutdown_connect
[ OK ] udp_shutdown_connect
[ RUN ] udp_shutdown_read
[ OK ] udp_shutdown_read
[ RUN ] udp_cancel_read
[ OK ] udp_cancel_read
[ RUN ] udp_timeout_recovery
[ OK ] udp_timeout_recovery
[ RUN ] udp_double_read
[ OK ] udp_double_read
[ RUN ] udp_recv_one
[ OK ] udp_recv_one
[ RUN ] udp_recv_two
[ OK ] udp_recv_two
[ RUN ] udp_recv_send
udp__connect_cb(0x0, too many open files, 0x0)
udp__connect_cb(0x0, too many open files, 0x0)
udp__connect_cb(0x0, too many open files, 0x0)
udp__connect_cb(0x0, too many open files, 0x0)
udp__connect_cb(0x0, too many open files, 0x0)
udp__connect_cb(0x0, too many open files, 0x0)
%
Ondřej Surý [Wed, 11 Jan 2023 08:28:10 +0000 (09:28 +0100)]
Prefer the pthread_barrier implementation over uv_barrier
Prefer the pthread_barrier implementation on platforms where it is
available over uv_barrier implementation. This also solves the problem
with thread sanitizer builds on macOS that doesn't have pthread barrier.
Tony Finch [Tue, 20 Dec 2022 11:38:51 +0000 (11:38 +0000)]
Auto-tag merge requests created by git-replay-merge
The target branch is added to the title of the MR, and a "Backport"
label is added. If the target branch starts with "v" a version label
is added too.
While I am here, clean up remnants of the old gitlab API (which has
been replaced by push options for our purposes) and improve the
command-line parsing.
Ondřej Surý [Wed, 4 Jan 2023 11:21:00 +0000 (12:21 +0100)]
Get rid of locking during UDP and TCP listen
We already have a synchronization mechanism when starting the UDP and
TCP listener children - barriers. Change how we start the first-born
child (tid == 0), so we don't have to race for sock->parent->result and
sock->parent->fd.
Ondřej Surý [Tue, 3 Jan 2023 07:27:54 +0000 (08:27 +0100)]
Simplify tracing the reference counting in isc_netmgr
Always track the per-worker sockets in the .active_sockets field in the
isc__networker_t struct and always track the per-socket handles in the
.active_handles field ian the isc_nmsocket_t struct.
Evan Hunt [Fri, 6 Jan 2023 06:18:55 +0000 (22:18 -0800)]
remove nonfunctional DSCP implementation
DSCP has not been fully working since the network manager was
introduced in 9.16, and has been completely broken since 9.18.
This seems to have caused very few difficulties for anyone,
so we have now marked it as obsolete and removed the
implementation.
To ensure that old config files don't fail, the code to parse
dscp key-value pairs is still present, but a warning is logged
that the feature is obsolete and should not be used. Nothing is
done with configured values, and there is no longer any
range checking.
Timo Teräs [Wed, 28 Dec 2022 15:13:41 +0000 (17:13 +0200)]
Refactor OpenSSL ECDSA to use pkeypair
- Use separate EVP_PKEY for public and private keys
- On private key load, generate public key allowing better consistency
- Support OpenSSL3 providers
- Clean up key construction abstraction
- Various other clean ups
Matthijs Mekking [Wed, 14 Dec 2022 10:41:10 +0000 (11:41 +0100)]
Don't set EDE in ns_client_aclchecksilent
The ns_client_aclchecksilent is used to check multiple ACLs before
the decision is made that a query is denied. It is also used to
determine if recursion is available. In those cases we should not
set the extended DNS error "Prohibited".
Timo Teräs [Mon, 26 Dec 2022 14:55:48 +0000 (16:55 +0200)]
Provide identical BN_GENCB_new shim
Instead of trying to optimize by using a stack local variable
with additional #ifdef logic, use identical implementations of
the upstream functions to reduce #ifdef clutter.
Move the definitions from dst_openssl.h to openssl_shim.h where
rest of the shim is.
Aram Sargsyan [Thu, 5 Jan 2023 15:01:35 +0000 (15:01 +0000)]
Fix a use-after-free bug in dns_zonemgr_releasezone()
The dns_zonemgr_releasezone() function makes a decision to destroy
'zmgr' (based on its references count, after decreasing it) inside
a lock, and then destroys the object outside of the lock.
This causes a race with dns_zonemgr_detach(), which could destroy
the object in the meantime.
Change dns_zonemgr_releasezone() to detach from 'zmgr' and destroy
the object (if needed) using dns_zonemgr_detach(), outside of the
lock.
Timo Teräs [Mon, 26 Dec 2022 12:25:18 +0000 (14:25 +0200)]
Refactor OpenSSL RSA exponent bits checking to a helper function
- Make it a separate opensslrsa_check_exponent_bits() function to
clean up the code a bit
- Always use provider API first if using openssl 3.0, and fallback
to EVP API for older openssl or if built with engine support
- Use RSA_get0_key() (with shim for openssl 1.0) to avoid memory
allocations
Ondřej Surý [Mon, 9 Jan 2023 11:48:19 +0000 (12:48 +0100)]
Change ISC_R_EXISTS to ISC_R_SUCCESS in dns/rbtdb.c:findnodeintree()
In the previous refactoring, the findnodeintree() function could return
ISC_R_EXISTS (from dns_db_addnode() call) instead of ISC_R_SUCCESS
leading to node being attached, but never detached.
Change the ISC_R_EXISTS result code returned from dns_rbt_addnode() to
the ISC_R_SUCCESS in the findnodeintree() function (called internally by
dns_db_findnode() and dns_db_findnsec3node()).
Matthijs Mekking [Thu, 17 Nov 2022 13:52:26 +0000 (13:52 +0000)]
Consider non-stale data when in serve-stale mode
With 'stale-answer-enable yes;' and 'stale-answer-client-timeout off;',
consider the following situation:
A CNAME record and its target record are in the cache, then the CNAME
record expires, but the target record is still valid.
When a new query for the CNAME record arrives, and the query fails,
the stale record is used, and then the query "restarts" to follow
the CNAME target. The problem is that the query's multiple stale
options (like DNS_DBFIND_STALEOK) are not reset, so 'query_lookup()'
treats the restarted query as a lookup following a failed lookup,
and returns a SERVFAIL answer when there is no stale data found in the
cache, even if there is valid non-stale data there available.
With this change, query_lookup() now considers non-stale data in the
cache in the first place, and returns it if it is available.
Evan Hunt [Sun, 8 Jan 2023 00:30:21 +0000 (16:30 -0800)]
use separate barriers for "stop" and "listen" operations
On some platforms, when a synchronizing barrier is cleared, one
thread can progress while other threads are still in the process
of releasing the barrier. If a barrier is reused by the progressing
thread during this window, it can cause a deadlock. This can occur if,
for example, we stop listening immediately after we start, because the
stop and listen functions both use socket->barrier. This has been
addressed by using separate barrier objects for stop and listen.
Ondřej Surý [Fri, 6 Jan 2023 07:49:11 +0000 (08:49 +0100)]
Deduplicate DNS_RBTDB_STRONG_RWLOCK_CHECK macros
There were couple of redundant macros on both sides of
DNS_RBTDB_STRONG_RWLOCK_CHECK #ifdef block. Use a single set of
macros, but disable the extra REQUIRES if the #define is not set.
Ondřej Surý [Thu, 5 Jan 2023 21:26:23 +0000 (22:26 +0100)]
Extend expire_header() to check node lock type
Extend the expire_header() to accept the node lock type as one of the
arguments and check whether the the node lock is always write locked +
fix that bug.
While doing that, it was found that expire_header() invocation in
rdataset_expire() passes `false` as a type of tree lock instead of
`isc_rwlocktype_none`.
(Un)fortunately, both values mapped to 0, so no harm was done, but it
has been fixed nevertheless.
Instead of doing that over again, introduce new NODE_FORCEUPGRADE()
and TREE_FORCEUPGRADE() that does exactly this code, and simplify
the aforementioned code with just: