summaryrefslogtreecommitdiffstats
path: root/doq.cc
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-26 06:28:37 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-06-26 06:28:37 +0000
commit037d41a914237592dc3e82751b8be3ff06407af0 (patch)
treef111444510b128085cbd03f7e72bcddcdef8a7e3 /doq.cc
parentReleasing progress-linux version 1.9.4-1~progress7.99u1. (diff)
downloaddnsdist-037d41a914237592dc3e82751b8be3ff06407af0.tar.xz
dnsdist-037d41a914237592dc3e82751b8be3ff06407af0.zip
Merging upstream version 1.9.5.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doq.cc')
-rw-r--r--doq.cc42
1 files changed, 27 insertions, 15 deletions
diff --git a/doq.cc b/doq.cc
index 247b67a..9910d75 100644
--- a/doq.cc
+++ b/doq.cc
@@ -51,8 +51,8 @@ using namespace dnsdist::doq;
class Connection
{
public:
- Connection(const ComboAddress& peer, QuicheConfig config, QuicheConnection conn) :
- d_peer(peer), d_conn(std::move(conn)), d_config(std::move(config))
+ Connection(const ComboAddress& peer, const ComboAddress& localAddr, QuicheConfig config, QuicheConnection conn) :
+ d_peer(peer), d_localAddr(localAddr), d_conn(std::move(conn)), d_config(std::move(config))
{
}
Connection(const Connection&) = delete;
@@ -62,6 +62,7 @@ public:
~Connection() = default;
ComboAddress d_peer;
+ ComboAddress d_localAddr;
QuicheConnection d_conn;
QuicheConfig d_config;
@@ -338,14 +339,14 @@ static void sendBackDOQUnit(DOQUnitUniquePtr&& unit, const char* description)
}
}
-static std::optional<std::reference_wrapper<Connection>> createConnection(DOQServerConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const ComboAddress& local, const ComboAddress& peer)
+static std::optional<std::reference_wrapper<Connection>> createConnection(DOQServerConfig& config, const PacketBuffer& serverSideID, const PacketBuffer& originalDestinationID, const ComboAddress& peer, const ComboAddress& localAddr)
{
auto quicheConfig = std::atomic_load_explicit(&config.config, std::memory_order_acquire);
auto quicheConn = QuicheConnection(quiche_accept(serverSideID.data(), serverSideID.size(),
originalDestinationID.data(), originalDestinationID.size(),
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- reinterpret_cast<const struct sockaddr*>(&local),
- local.getSocklen(),
+ reinterpret_cast<const struct sockaddr*>(&localAddr),
+ localAddr.getSocklen(),
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
reinterpret_cast<const struct sockaddr*>(&peer),
peer.getSocklen(),
@@ -356,7 +357,7 @@ static std::optional<std::reference_wrapper<Connection>> createConnection(DOQSer
quiche_conn_set_keylog_path(quicheConn.get(), config.df->d_quicheParams.d_keyLogFile.c_str());
}
- auto conn = Connection(peer, std::move(quicheConfig), std::move(quicheConn));
+ auto conn = Connection(peer, localAddr, std::move(quicheConfig), std::move(quicheConn));
auto pair = config.d_connections.emplace(serverSideID, std::move(conn));
return pair.first->second;
}
@@ -641,7 +642,7 @@ static void handleReadableStream(DOQFrontend& frontend, ClientState& clientState
return;
}
DEBUGLOG("Dispatching query");
- doq_dispatch_query(*(frontend.d_server_config), std::move(streamBuffer), clientState.local, client, serverConnID, streamID);
+ doq_dispatch_query(*(frontend.d_server_config), std::move(streamBuffer), conn.d_localAddr, client, serverConnID, streamID);
conn.d_streamBuffers.erase(streamID);
}
@@ -654,10 +655,21 @@ static void handleSocketReadable(DOQFrontend& frontend, ClientState& clientState
PacketBuffer tokenBuf;
while (true) {
ComboAddress client;
+ ComboAddress localAddr;
+ client.sin4.sin_family = clientState.local.sin4.sin_family;
+ localAddr.sin4.sin_family = clientState.local.sin4.sin_family;
buffer.resize(4096);
- if (!sock.recvFromAsync(buffer, client) || buffer.empty()) {
+ if (!dnsdist::doq::recvAsync(sock, buffer, client, localAddr)) {
return;
}
+ if (localAddr.sin4.sin_family == 0) {
+ localAddr = clientState.local;
+ }
+ else {
+ /* we don't get the port, only the address */
+ localAddr.sin4.sin_port = clientState.local.sin4.sin_port;
+ }
+
DEBUGLOG("Received DoQ datagram of size " << buffer.size() << " from " << client.toStringWithPort());
uint32_t version{0};
@@ -693,14 +705,14 @@ static void handleSocketReadable(DOQFrontend& frontend, ClientState& clientState
if (!quiche_version_is_supported(version)) {
DEBUGLOG("Unsupported version");
++frontend.d_doqUnsupportedVersionErrors;
- handleVersionNegociation(sock, clientConnID, serverConnID, client, buffer);
+ handleVersionNegociation(sock, clientConnID, serverConnID, client, localAddr, buffer);
continue;
}
if (token_len == 0) {
/* stateless retry */
DEBUGLOG("No token received");
- handleStatelessRetry(sock, clientConnID, serverConnID, client, version, buffer);
+ handleStatelessRetry(sock, clientConnID, serverConnID, client, localAddr, version, buffer);
continue;
}
@@ -713,7 +725,7 @@ static void handleSocketReadable(DOQFrontend& frontend, ClientState& clientState
}
DEBUGLOG("Creating a new connection");
- conn = createConnection(*frontend.d_server_config, serverConnID, *originalDestinationID, clientState.local, client);
+ conn = createConnection(*frontend.d_server_config, serverConnID, *originalDestinationID, client, localAddr);
if (!conn) {
continue;
}
@@ -724,8 +736,8 @@ static void handleSocketReadable(DOQFrontend& frontend, ClientState& clientState
reinterpret_cast<struct sockaddr*>(&client),
client.getSocklen(),
// NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
- reinterpret_cast<struct sockaddr*>(&clientState.local),
- clientState.local.getSocklen(),
+ reinterpret_cast<struct sockaddr*>(&localAddr),
+ localAddr.getSocklen(),
};
auto done = quiche_conn_recv(conn->get().d_conn.get(), buffer.data(), buffer.size(), &recv_info);
@@ -741,7 +753,7 @@ static void handleSocketReadable(DOQFrontend& frontend, ClientState& clientState
handleReadableStream(frontend, clientState, *conn, streamID, client, serverConnID);
}
- flushEgress(sock, conn->get().d_conn, client, buffer);
+ flushEgress(sock, conn->get().d_conn, client, localAddr, buffer);
}
else {
DEBUGLOG("Connection not established");
@@ -786,7 +798,7 @@ void doqThread(ClientState* clientState)
for (auto conn = frontend->d_server_config->d_connections.begin(); conn != frontend->d_server_config->d_connections.end();) {
quiche_conn_on_timeout(conn->second.d_conn.get());
- flushEgress(sock, conn->second.d_conn, conn->second.d_peer, buffer);
+ flushEgress(sock, conn->second.d_conn, conn->second.d_peer, conn->second.d_localAddr, buffer);
if (quiche_conn_is_closed(conn->second.d_conn.get())) {
#ifdef DEBUGLOG_ENABLED