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.
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.
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.
- 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
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.
Instead of trying to enforce one pkey to contain both a private
and a public key pair, refactor the code to have separate public
and private pkeys.
This is a prerequisite for proper openssl 3.0 providers support
and greatly simplifies the code.
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.
- 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
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()).
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.
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.
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.
There was a repetetive pattern:
if (NODE_TRYUPGRADE(&nodelock->lock, nlocktypep) != ISC_R_SUCCESS)
{
NODE_UNLOCK(&nodelock->lock, nlocktypep);
NODE_WRLOCK(&nodelock->lock, nlocktypep);
}
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:
NODE_FORCEUPGRADE(&nodelock->lock, nlocktypep);
Previously, dns_dispatch_gettcp() could pick a TCP connection created by
different thread - this breaks our contractual promise to DNS dispatch
by using the TCP connection on a different thread than it was created.
Add .tid member to the dns_dispatch_t struct and skip the dispatches
from other threads when looking up a TCP dispatch that we can reuse in
dns_request.
NOTE: This is going to be properly refactored, but this change could be
also backported to 9.18 for better stability and thread-affinity.
Since dns_master_dump() can no longer return DNS_R_CONTINUE,
the error recovery code in synchronous calls to zone_dump() had
branches that could no longer be reached. This has been cleaned
up by using a boolean variable to determine whether the write
is asynchronous rather than depending on the result code.
The following report suggests that the 'size' parameter in the two
calls to 'isc_mem_get()' should be set to the
'count * sizeof(*tlsnames)' and 'count * sizeof(*keynames)'
respectively.
/lib/dns/remote.c: 117 in dns_remote_init()
111 }
112 } else {
113 remote->keynames = NULL;
114 }
115
116 if (tlsnames != NULL) {
>>> CID 432259: (SIZEOF_MISMATCH)
>>> Passing argument "count * 8UL /* sizeof (tlsnames) */" to
>>> function "isc__mem_get" and then casting the return value to
>>> "dns_name_t **" is suspicious. In this particular case
>>> "sizeof (dns_name_t **)" happens to be equal to
>>> "sizeof (dns_name_t *)", but this is not a portable assumption.
117 remote->tlsnames = isc_mem_get(mctx, count * sizeof(tlsnames));
118 for (i = 0; i < count; i++) {
119 remote->tlsnames[i] = NULL;
120 }
121 for (i = 0; i < count; i++) {
122 if (tlsnames[i] != NULL) {
/lib/dns/remote.c: 99 in dns_remote_init()
93 memmove(remote->dscps, dscp, count * sizeof(isc_dscp_t));
94 } else {
95 remote->dscps = NULL;
96 }
97
98 if (keynames != NULL) {
>>> CID 432259: (SIZEOF_MISMATCH)
>>> Passing argument "count * 8UL /* sizeof (keynames) */" to
>>> function "isc__mem_get" and then casting the return value to
>>> "dns_name_t **" is suspicious. In this particular case
>>> "sizeof (dns_name_t **)" happens to be equal to "sizeof
>>> (dns_name_t *)", but this is not a portable assumption.
99 remote->keynames = isc_mem_get(mctx, count * sizeof(keynames));
100 for (i = 0; i < count; i++) {
101 remote->keynames[i] = NULL;
102 }
103 for (i = 0; i < count; i++) {
104 if (keynames[i] != NULL) {
When shutting down, the cleanup path should not try to destroy
'newnodes', because it is NULL at that point.
Introduce another label for the "shuttingdown" scenario.
The clean_namehooks() function does't hold the 'adb->entries_lock'
lock, so calling maybe_expire_entry() is not thread-safe.
Instead of adding a lock/unlock, leave the expiration to later,
e.g. by the get_attached_and_locked_entry() function.
Also fix a couple of comment typos.
Remove parsing the configuration options 'alt-transfer-source',
'alt-transfer-source-v6', and 'use-alt-transfer-source', and remove
the corresponding code that implements the feature.
Use the configured 'source' and 'source-v6' when initiating a zone
transfer, sending a notify, or when checking for the DS. Remove the
special code for using alternate transfer sources.
Update some system tests to use the new configuration and make sure
the tests still work.
The dns_remote_t structure is intended to replace the variables in
the structure that deals with remote server communication to primaries,
parental agents, forwarders, etc.
Normally, when a 'resquery_t' object is created in fctx_query(),
we call dns_adb_beginudpfetch() (which increases the ADB quota)
only if it's a UDP query. Then, in fctx_cancelquery(), we call
dns_adb_endudpfetch() to decreases back the ADB quota, again only
if it's a UDP query.
The problem is that a UDP query can become a TCP query, preventing
the quota from adjusting back in fctx_cancelquery() later.
Call dns_adb_beginudpfetch() also when switching the query type
from UDP to TCP.
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.
The dns_request code is very sensitive about calling the connected and
deadlocks when the timing is "right" in several places. Move the call
to the connected callback to the (udp|tcp)_connected() functions, so
they are called asynchronously instead of directly from
the (udp|tcp)_dispentry_cancel() functions.
The TCP dispatches are removed from the dispatchmgr->list in the
dispatch_destroy() and there's a brief period of time where
dns_dispatch_gettcp() can find a dispatch in connected state that's
being destroyed.
Set the dispatch state to DNS_DISPATCHSTATE_NONE in the TCP connection
callback if there are no responses waiting, and ignore TCP dispatches
with zero references in dns_dispatch_gettcp().