diff options
Diffstat (limited to '')
-rw-r--r-- | doq.cc | 42 |
1 files changed, 27 insertions, 15 deletions
@@ -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 |