Ondřej Surý [Thu, 26 Oct 2023 08:54:28 +0000 (10:54 +0200)]
Fix assertion failure when using -X and lock-file in configuration
When 'lock-file <lockfile1>' was used in configuration at the same time
as using `-X <lockfile2>` in `named` invocation, there was an invalid
logic that would lead to a double isc_mem_strdup() call on the
<lockfile2> value.
Skip the second allocation if `lock-file` is being used in
configuration, so the <lockfile2> is used only single time.
Ondřej Surý [Thu, 26 Oct 2023 07:14:10 +0000 (09:14 +0200)]
Allowing changing Userspace-RCU variant only in developer mode
The Userspace-RCU variants other than membarrier is untested and at
least in QSBR case it's broken. Allow changing the Userspace-RCU
variant only in the developer's mode.
Evan Hunt [Wed, 25 Oct 2023 21:59:55 +0000 (14:59 -0700)]
Prevent a possible race in dns_qpmulti_query() and _snapshot()
The `.reader` member of dns_qpmulti_t was accessed without RCU
protection; reader_open() calls rcu_dereference() on it, and this
call needs to be inside an RCU critical section.
A similar problem was identified in the dns_qpmulti_snapshot() - the
RCU critical section was completely missing.
These are relicts of the isc_qsbr - in the QSBR mode the rcu_read_lock()
and rcu_read_unlock() are no-ops and whole event loop is a critical section.
Mark Andrews [Thu, 26 Oct 2023 04:07:58 +0000 (15:07 +1100)]
Check that the lock file was not removed too early
When named fails to starts due to not being able to obtain
a lock on the lock file that lock file should remain. Check
that the lock file exists before and after the attempt to
start a second instance of named.
Mark Andrews [Thu, 26 Oct 2023 03:50:43 +0000 (14:50 +1100)]
Only remove the lock file if we managed to lock it
The lock file was being removed when we hadn't successfully locked
it which defeated the purpose of the lockfile. Adjust cleanup_lockfile
such that it only unlinks the lockfile if we have successfully locked
the lockfile and it is still active (lockfile != NULL).
Ondřej Surý [Thu, 19 Oct 2023 08:22:59 +0000 (10:22 +0200)]
Refactor dns_message using ISC_LIST_FOREACH macros
Do a light refactoring and cleanups that replaces common list walking
patterns with ISC_LIST_FOREACH macros and split some nested loops into
separate static functions to reduce the nesting depth.
Ondřej Surý [Thu, 19 Oct 2023 08:21:20 +0000 (10:21 +0200)]
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
Ondřej Surý [Mon, 23 Oct 2023 10:26:50 +0000 (12:26 +0200)]
Add dispatch_getcp and dispatch_newtcp tests
Refactor the dispatch unit test to use more local variables (previously
dispatchmgr, dispatch and dispentry were all global), and add two new
tests:
* dispatch_getcp - test whether the TCP connection will get reused
* dispatch_newtcp - test that the TCP connection will not get reused
when DNS_DISPATCHOPT_UNSHARED is in effect
Ondřej Surý [Fri, 20 Oct 2023 06:14:27 +0000 (08:14 +0200)]
Add option to mark TCP dispatch as unshared
The current dispatch code could reuse the TCP connection when
dns_dispatch_gettcp() would be used first. This is problematic as the
dns_resolver doesn't use TCP connection sharing, but dns_request could
get the TCP stream that was created outside of the dns_request.
Add new DNS_DISPATCHOPT_UNSHARED option to dns_dispatch_createtcp() that
would prevent the TCP stream to be reused. Use that option in the
dns_resolver call to dns_dispatch_createtcp() to prevent dns_request
from reusing the TCP connections created by dns_resolver.
Additionally, the dns_xfrin unit added TCP connection sharing for
incoming transfers. While interleaving *xfr streams on a TCP connection
should work this should be a deliberate change and be property of the
server that can be controlled. Additionally some level of parallel TCP
streams is desirable. Revert to the old behaviour by removing the
dns_dispatch_gettcp() calls from dns_xfrin and use the new option to
prevent from sharing the transfer streams with dns_request.
Ondřej Surý [Fri, 20 Oct 2023 05:58:26 +0000 (07:58 +0200)]
Don't set the offloaded work result from main thread
The xfrin_recv_done() was accessing xfr->result where we stored the
result of the offloaded work from a thread that could receive data while
processing the transfer on the offloaded thread.
Completely remove the offloaded result from the dns_xfrin_t structure
and keep it local for *xfr_apply() and *xfr_apply_done() as the failure
is already recorded in .shutdown_result and we now that the processing
has failed because .shuttingdown has been already set.
Aram Sargsyan [Thu, 19 Oct 2023 12:57:13 +0000 (12:57 +0000)]
sd_notify(3): set the MONOTONIC_USEC field with RELOADING=1
When using sd_notify(3) to send a message to the service manager
about named being reloaded, systemd also requires the MONOTONIC_USEC
field to be set to the current monotonic time in microseconds,
otherwise the 'systemctl reload' command fails.
Aram Sargsyan [Fri, 20 Oct 2023 10:45:35 +0000 (10:45 +0000)]
Fix shutdown races in catzs
The dns__catz_update_cb() does not expect that 'catzs->zones'
can become NULL during shutdown.
Add similar checks in the dns__catz_update_cb() and dns_catz_zone_get()
functions to protect from such a case. Also add an INSIST in the
dns_catz_zone_add() function to explicitly state that such a case
is not expected there, because that function is called only during a
reconfiguration.
Mark Andrews [Tue, 17 Oct 2023 23:45:41 +0000 (10:45 +1100)]
Suppress reporting upcoming changes in root hints
To reduce the amount of log spam when root servers change their
addresses keep a table of upcoming changes by expected date and time
and suppress reporting differences for them until then.
Add initial entry for B.ROOT-SERVERS.NET, Nov 27, 2023.
Ondřej Surý [Fri, 13 Oct 2023 12:41:22 +0000 (14:41 +0200)]
Offload AXFR and IXFR processing
Instead of processing received data synchronously, store the incoming
differences in the list and process them asynchronously when we need to
commit the data into the database and/or journal.
Ondřej Surý [Fri, 13 Oct 2023 10:16:37 +0000 (12:16 +0200)]
Remove all locking from XFR
Instead of locking the struct dns_xfrin members that get accessed from
the statistics, convert those into atomic types and use atomic accesses
to prevent ThreadSanitizer from blowing up.
In fact, even the atomic operations are not really needed here, because
all writes are done from a single thread and we don't really require
consistency from the statistics. It's easier to use atomics here, but
it is slightly confusing as it suggests there might be multithreaded
accesses to those variables while in fact, the only off-thread access
happens when collecting the statistics.
Ondřej Surý [Thu, 12 Oct 2023 15:48:56 +0000 (17:48 +0200)]
Remove the logic that applies differences when over limit
The ixfr_putdata() and axfr_putdata() had a logic to apply dns_diff when
the number of pending tuples went over 100. Since we are going to
offload the XFR data processing, we don't need to do that anymore.
Ondřej Surý [Thu, 19 Oct 2023 09:39:53 +0000 (11:39 +0200)]
Disable OpenSSL memory contexts for OpenSSL < 3.0.0
OpenSSL 1.1 has already reached end-of-life and since we are
experiencing a weird memory leak in the mirror system test on just
Ubuntu 20.04 (Focal) with OpenSSL 1.1, we disable the legacy code for
enabling memory contexts for OpenSSL < 3.0.0 in this commit.
Aram Sargsyan [Thu, 19 Oct 2023 08:46:58 +0000 (08:46 +0000)]
Fix an error in the qp_test.c unit test
In order to check whether there are enough inserted values the
code uses the 'tests' variable (loop counter), which is unreliable,
because the loop sometimes removes an item instead of inserting
one (when the randomly generated item already exists).
Instead of the loop counter, use the existing variable 'inserted',
which should indicate the correct number of the inserted items.
Mark Andrews [Wed, 16 Aug 2023 04:40:12 +0000 (14:40 +1000)]
Adjust UDP timeouts used in zone maintenance
Drop timeout before resending a UDP request from 15 seconds to 5
seconds and add 1 second to the total time to allow for the reply
to the third request to arrive. This will speed up the time it
takes for named to recover from a lost packet when refreshing a
zone and for it to determine that a primary is down.
Matthijs Mekking [Thu, 12 Oct 2023 11:56:46 +0000 (13:56 +0200)]
Update addzone test
Now that inline-signing is ignored when there is no dnssec-policy,
add 'dnssec-policy default;' to the zones when attempting to add them
via 'rndc addzone'.
Matthijs Mekking [Thu, 12 Oct 2023 10:04:30 +0000 (12:04 +0200)]
Update inline-signing documentation
Add the missing documentation for 'dnssec-policy/inline-signing'.
Update the zone-only option 'inline-signing' to indicate that the
use of inline signing should be set in 'dnssec-policy' and that this
is merely a way to override the value for the given zone.
Matthijs Mekking [Thu, 12 Oct 2023 10:02:02 +0000 (12:02 +0200)]
Ignore inline-signing by default
Ignore the option 'inline-signing' unless there is a 'dnssec-policy'
configured for the zone. Having inline signing enabled while the zone
is not DNSSEC signed does not make sense.
If there is a 'dnssec-policy' the 'inline-signing' zone-only option
can be used to override the value for the given zone.
Matthijs Mekking [Mon, 16 Oct 2023 09:08:59 +0000 (11:08 +0200)]
Two minor fixes in the kasp system test
The 'dynamic-signed-inline-signing.kasp' zone was set up with
the environment variable 'ksktimes', but that should be 'csktimes'
which is set one line above. Since the values are currently the same
the behavior is identical, but of course it should use the correct
variable.
The 'step4.enable-dnssec.autosign' zone was set up twice. This is
unnecessary.
Matthijs Mekking [Fri, 13 Oct 2023 09:46:05 +0000 (11:46 +0200)]
Don't resign raw version of the zone
Update the function 'set_resigntime()' so that raw versions of
inline-signing zones are not scheduled to be resigned.
Also update the check in the same function for zone is dynamic, there
exists a function 'dns_zone_isdynamic()' that does a similar thing
and is more complete.
Also in 'zone_postload()' check whether the zone is not the raw
version of an inline-signing zone, preventing calculating the next
resign time.
Ondřej Surý [Fri, 13 Oct 2023 06:59:41 +0000 (08:59 +0200)]
Convert rwlock in dns_acl to RCU
The dns_aclenv_t contains two dns_acl_t - localhost and localnets that
can be swapped with a different ACLs as we configure BIND 9. Instead of
protecting those two pointers with heavyweight read-write lock, use RCU
mechanism to dereference and swap the pointers.
Petr Špaček [Tue, 10 Oct 2023 09:27:16 +0000 (11:27 +0200)]
Describe BIND threat model
Basically all local data is considered trusted, and proper ACLs and
limits need to be explicitly configured. We are also free to let
protocol non-compliant servers burn in flames.
Michał Kępień [Thu, 12 Oct 2023 12:24:42 +0000 (14:24 +0200)]
Remove PDF-related bits from the build system
Read the Docs is capable of building the PDF version of the BIND 9 ARM
using just the contents of the doc/arm/ directory - it does not need the
build system to facilitate that. Since the BIND 9 ARM is also built in
other formats when "make doc" is run, drop the parts of the build system
that enable building the PDF version as they pull in complexity without
bringing much added value in return. Update related files accordingly.
Ondřej Surý [Thu, 12 Oct 2023 07:20:42 +0000 (09:20 +0200)]
Use mul and div instead of bitshifts to calculate srtt
There was a microoptimization for smoothing srtt with bitshifts. Revert
the code to use * 98 / 100, it doesn't really make that difference on
modern CPUs, for comparison here:
muldiv:
imul eax, edi, 98
imul rax, rax, 1374389535
shr rax, 37
ret
shift:
mov eax, edi
sal eax, 9
sub eax, edi
shr eax, 9
ret
Ondřej Surý [Thu, 12 Oct 2023 07:17:40 +0000 (09:17 +0200)]
Skip the no-op code in adjustsrtt()
If factor == DNS_ADB_RTTADJAGE and addr->entry->lastage == now we would
load value into new_srtt and then immediatelly store it back which
triggers the synchronization between threads using .srtt values.
Replace some ADB entry locking with atomics to reduce ADB contention
Use atomics on couple of ADB entry members (.srtt, .flags, .expires, and
.lastage) to remove ADB entry locking from couple of hot spots. The
most prominent place is copy_namehook_lists() that gets called under ADB
name lock and if the namehook list is long it acquires-releases quite a
few ADB entry locks. Changing those ADB entry members to atomics
allowed us to new_adbaddrinfo() not require locked ADB entry and since
adbentry_overquota() already used atomics and handling lame information
was dropped in the previous commit, we could not make the
copy_namehook_lists() lockless.
The other hotspot is dns_adb_adjustsrtt() and dns_adb_agesrtt() that can
now use atomics because .srtt is already atomic_uint.
And the last place that could now use atomics is dns_adb_changeflags().