Remi Gacogne [Wed, 4 Dec 2024 13:39:56 +0000 (14:39 +0100)]
dnsdist: Allow resetting `setWeightedBalancingFactor()` to zero
Zero is the initial value, but until now it was only possible to pass
a value greater than or equal to 1.0 to `setWeightedBalancingFactor()`
so it was not possible to reset it to the default value.
Remi Gacogne [Tue, 26 Nov 2024 08:42:47 +0000 (09:42 +0100)]
Merge pull request #14878 from rgacogne/ddist19-backport-14768
dnsdist-1.9.x: Backport of #14768 - setTicketsKeyAddedHook: pass a std::string to the hook to avoid luawrapper to truncate content at potential null chars
Remi Gacogne [Thu, 3 Oct 2024 07:10:09 +0000 (09:10 +0200)]
dnsdist: Disable eBPF filtering on QUIC (DoQ, DoH3) sockets
The current eBPF code tries to parse the beginning of the DNS payload
to extract the qname for all UDP datagrams, which is not course
not working correctly for QUIC packets. I don't immediately see a way
to identify QUIC packets from our eBPF code, so for now this commit
disables the eBPF filtering feature on QUIC sockets.
dnsdist: Add EDNS to responses generated from raw record data
My reasoning is that it makes sense to add EDNS to responses generated
from DNSdist provided that:
- the initial query had EDNS
- `setAddEDNSToSelfGeneratedResponses` has not been set to `false`
- we are only provided part of the response and not a full response
packet
See https://github.com/cloudflare/quiche/pull/1769
but it does not matter in our case since we install
the Quiche library in such a way (libdnsdist-quiche.so)
that we are the only user, and it will always be updated
with DNSdist. Keeping it makes our life significantly harder
since several packaging tools look a the `SONAME`.
Remi Gacogne [Tue, 20 Aug 2024 10:26:33 +0000 (12:26 +0200)]
dnsdist: Fix EDNS flags confusion when editing the OPT header
We used to wrongly reverse the byte-ordering of the existing EDNS
flags when editing the OPT header, for example when setting an
extended DNS error status.
Remi Gacogne [Tue, 20 Aug 2024 11:04:11 +0000 (13:04 +0200)]
dnsdist: Return a valid unix timestamp for Dynamic Block's `until`
We internally use a timestamp obtained via `CLOCK_MONOTONIC` which
is quite useless to an external observer, so convert it to a normal
unix timestamp in the Lua accessor.
Remi Gacogne [Tue, 20 Aug 2024 12:44:57 +0000 (14:44 +0200)]
dnsdist: Stop reporting timeouts in `topSlow()`, add `topTimeouts()`
Until this commit `topSlow()` returned queries that timed out, which
is not very helpful. This was happening because timeouts are internally
recorded with a very high response time.
With this change, `topSlow()` now ignores queries that timed out, and
a new command is added to look into these: `topTimeouts()`.
Michael Cho [Fri, 16 Aug 2024 02:49:17 +0000 (22:49 -0400)]
Fix build with boost 1.86.0
Boost 1.86.0 changes seem to no longer indirectly include header which
causes build to fail with:
```
uuid-utils.cc:38:58:
error: 'random' is not a class, namespace, or enumeration
```
boost/random/mersenne_twister.hpp has been available since Boost 1.21.2
dnsdist: Fix handling of proxy protocol payload outside of TLS for DoT
After reading the proxy protocol payload from the I/O buffer
we were clearing the buffer but failed to properly reset the
position, leading to an exception when trying to read the DNS
payload after processing the TLS handshake:
```
Got an exception while handling (reading) TCP query from 127.0.0.1:59426: Calling tryRead() with a too small buffer (2) for a read of 18446744073709551566 bytes starting at 52
```
The huge value comes from the fact that the position (52 here)
is larger than the size of the buffer (2 at this point to read
the size of the incoming DNS payload), leading to an unsigned
underflow. The code is properly detecting that the value makes
no sense in this context, but the connection is then dropped
because we cannot recover.
It turns out we had a end-to-end test for the "proxy protocol
outside of TLS" case but only over incoming DoH, and the DoH
case avoids this specific issue because the buffer is always
properly resized, and the position updated.
Remi Gacogne [Thu, 27 Jun 2024 14:07:20 +0000 (16:07 +0200)]
dnsdist: Handle Quiche >= 0.22.0
Quiche broke its existing API in 0.22.0: https://github.com/cloudflare/quiche/pull/1726
This pull request adds m4 code to detect whether the Quiche version
we are building against is >= 0.22.0, and if it is defines
`HAVE_QUICHE_STREAM_ERROR_CODES` which is later used by the code
using Quiche to know which version of the API to use.
Otto Moerbeek [Wed, 19 Jun 2024 11:10:15 +0000 (13:10 +0200)]
dns.cc: use pdns::views::UnsignedCharView
Includes minor cleanup and additions to make UnsignedCharView usable for this use case.
Supersedes #14356
Fixes
/usr/include/c++/v1/__fwd/string_view.h:22:41: warning: 'char_traits<unsigned char>' is deprecated: char_traits<T> for T not equal to char, wchar_t, char8_t, char16_t or char32_t is non-standard and is provided for a temporary period. It will be removed in LLVM 19, so please migrate off of it. [-Wdeprecated-declarations]
dnsdist: Fix a data race in the AF_XDP/XSK dnsdist <-> backend code
The existing code was sharing the same XskWorker between the thread
handling incoming queries (possibly replying right away for
self-answered and cache hit responses) and the one handling responses
coming from a backend (without XSK), which is wrong since the internal
queues are single-producer (and single consumer, but a worker is only
assigned to a single XskRouter which is OK).
This commit introduces a new, separate worker for the threads handling
responses coming from a backend without XSK (it was already the case
for responses coming from a backend via XSK). The new worker is marked
"outgoing-only" to ensure we are not confused about what it can be used
for, which is only sending packets, not receiving any.
dnsdist: Fix a race in the XSK/AF_XDP backend handling code
For performance reasons we used to keep a local list of available frames
in our `XskWorker` object, like we are doing in the `XskSocket` one,
to avoid having to go to the shared list which is protected by a lock.
Unfortunately, while it works well for the `XskSocket` because it is
accessed by a single `XskRouter` thread, the `XskWorker` object can
be accessed by multiple threads at once: `XskResponderThread`,
`responderThread`, `XskClientThread` and `XskRouter`. Most of the
time these threads do not acquire nor release frames to the local
list, but `responderThread` does acquire one when a response frame
is punted to the regular networking stack, and all of them release
frames when an unexpected condition occurs, for example when a queue
is full. This leads to memory corruption and to a crash.
This commit gets rid of the local list of frames in the `XskWorker`
object, acquiring and releasing them to the shared list instead, since
performance in these cases is likely not as critical. If it turns out
to be too slow, we can look into caching a few frames in a thread-local
list, but then we need to be careful not to hold on them indefinitely
which might be tricky.
Remi Gacogne [Mon, 17 Jun 2024 10:42:02 +0000 (12:42 +0200)]
dnsdist: Fix a race condition with custom Lua web handlers
Custom web handlers written in Lua modify the global Lua context,
but until now they did not take the lock protecting it so a data
race condition was possible.
Reported by TSAN while running our unit tests.
Remi Gacogne [Tue, 4 Jun 2024 14:28:31 +0000 (16:28 +0200)]
dnsdist: Edit the systemd unit file, `CAP_BPF` is no longer enough
We used to be able to use only `CAP_BPF` since kernel 5.8, but the
eBPF verifier has been made more strict a few versions later and we
now require `CAP_SYS_ADMIN` again.