From: Remi Gacogne Date: Fri, 22 Dec 2023 15:54:20 +0000 (+0100) Subject: dnsdist: Split DoH3 'socket readable' to a separate function X-Git-Tag: auth-4.9.0-alpha1~18^2~9 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7d16b9a1e921d4cb1fc9a35044e7da2fde6ca060;p=thirdparty%2Fpdns.git dnsdist: Split DoH3 'socket readable' to a separate function --- diff --git a/pdns/dnsdistdist/doh3.cc b/pdns/dnsdistdist/doh3.cc index e3c14ccee8..ab526f4981 100644 --- a/pdns/dnsdistdist/doh3.cc +++ b/pdns/dnsdistdist/doh3.cc @@ -805,6 +805,104 @@ static void processH3Events(ClientState& clientState, DOH3Frontend& frontend, H3 } } +static void handleSocketReadable(DOH3Frontend& frontend, ClientState& clientState, Socket& sock) +{ + DEBUGLOG("Received datagram"); + std::string bufferStr; + ComboAddress client; + sock.recvFrom(bufferStr, client); + + uint32_t version{0}; + uint8_t type{0}; + std::array scid{}; + size_t scid_len = scid.size(); + std::array dcid{}; + size_t dcid_len = dcid.size(); + std::array token{}; + size_t token_len = token.size(); + + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + auto res = quiche_header_info(reinterpret_cast(bufferStr.data()), bufferStr.size(), LOCAL_CONN_ID_LEN, + &version, &type, + scid.data(), &scid_len, + dcid.data(), &dcid_len, + token.data(), &token_len); + if (res != 0) { + DEBUGLOG("Error in quiche_header_info: " << res); + return; + } + + // destination connection ID, will have to be sent as original destination connection ID + PacketBuffer serverConnID(dcid.begin(), dcid.begin() + dcid_len); + // source connection ID, will have to be sent as destination connection ID + PacketBuffer clientConnID(scid.begin(), scid.begin() + scid_len); + auto conn = getConnection(frontend.d_server_config->d_connections, serverConnID); + + if (!conn) { + DEBUGLOG("Connection not found"); + if (!quiche_version_is_supported(version)) { + DEBUGLOG("Unsupported version"); + ++frontend.d_doh3UnsupportedVersionErrors; + handleVersionNegociation(sock, clientConnID, serverConnID, client); + return; + } + + if (token_len == 0) { + /* stateless retry */ + DEBUGLOG("No token received"); + handleStatelessRetry(sock, clientConnID, serverConnID, client, version); + return; + } + + PacketBuffer tokenBuf(token.begin(), token.begin() + token_len); + auto originalDestinationID = validateToken(tokenBuf, client); + if (!originalDestinationID) { + ++frontend.d_doh3InvalidTokensReceived; + DEBUGLOG("Discarding invalid token"); + return; + } + + DEBUGLOG("Creating a new connection"); + conn = createConnection(*frontend.d_server_config, serverConnID, *originalDestinationID, clientState.local, client); + if (!conn) { + return; + } + } + DEBUGLOG("Connection found"); + quiche_recv_info recv_info = { + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(&client), + client.getSocklen(), + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + reinterpret_cast(&clientState.local), + clientState.local.getSocklen(), + }; + + // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) + auto done = quiche_conn_recv(conn->get().d_conn.get(), reinterpret_cast(bufferStr.data()), bufferStr.size(), &recv_info); + if (done < 0) { + return; + } + + if (quiche_conn_is_established(conn->get().d_conn.get())) { + DEBUGLOG("Connection is established"); + + if (!conn->get().d_http3) { + conn->get().d_http3 = QuicheHTTP3Connection(quiche_h3_conn_new_with_transport(conn->get().d_conn.get(), frontend.d_server_config->http3config.get()), + quiche_h3_conn_free); + if (!conn->get().d_http3) { + return; + } + DEBUGLOG("Successfully created HTTP/3 connection"); + } + + processH3Events(clientState, frontend, conn->get(), client, serverConnID); + } + else { + DEBUGLOG("Connection not established"); + } +} + // this is the entrypoint from dnsdist.cc void doh3Thread(ClientState* clientState) { @@ -828,100 +926,7 @@ void doh3Thread(ClientState* clientState) mplexer->getAvailableFDs(readyFDs, 500); if (std::find(readyFDs.begin(), readyFDs.end(), sock.getHandle()) != readyFDs.end()) { - DEBUGLOG("Received datagram"); - std::string bufferStr; - ComboAddress client; - sock.recvFrom(bufferStr, client); - - uint32_t version{0}; - uint8_t type{0}; - std::array scid{}; - size_t scid_len = scid.size(); - std::array dcid{}; - size_t dcid_len = dcid.size(); - std::array token{}; - size_t token_len = token.size(); - - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - auto res = quiche_header_info(reinterpret_cast(bufferStr.data()), bufferStr.size(), LOCAL_CONN_ID_LEN, - &version, &type, - scid.data(), &scid_len, - dcid.data(), &dcid_len, - token.data(), &token_len); - if (res != 0) { - DEBUGLOG("Error in quiche_header_info: " << res); - continue; - } - - // destination connection ID, will have to be sent as original destination connection ID - PacketBuffer serverConnID(dcid.begin(), dcid.begin() + dcid_len); - // source connection ID, will have to be sent as destination connection ID - PacketBuffer clientConnID(scid.begin(), scid.begin() + scid_len); - auto conn = getConnection(frontend->d_server_config->d_connections, serverConnID); - - if (!conn) { - DEBUGLOG("Connection not found"); - if (!quiche_version_is_supported(version)) { - DEBUGLOG("Unsupported version"); - ++frontend->d_doh3UnsupportedVersionErrors; - handleVersionNegociation(sock, clientConnID, serverConnID, client); - continue; - } - - if (token_len == 0) { - /* stateless retry */ - DEBUGLOG("No token received"); - handleStatelessRetry(sock, clientConnID, serverConnID, client, version); - continue; - } - - PacketBuffer tokenBuf(token.begin(), token.begin() + token_len); - auto originalDestinationID = validateToken(tokenBuf, client); - if (!originalDestinationID) { - ++frontend->d_doh3InvalidTokensReceived; - DEBUGLOG("Discarding invalid token"); - continue; - } - - DEBUGLOG("Creating a new connection"); - conn = createConnection(*frontend->d_server_config, serverConnID, *originalDestinationID, clientState->local, client); - if (!conn) { - continue; - } - } - DEBUGLOG("Connection found"); - quiche_recv_info recv_info = { - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - reinterpret_cast(&client), - client.getSocklen(), - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - reinterpret_cast(&clientState->local), - clientState->local.getSocklen(), - }; - - // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast) - auto done = quiche_conn_recv(conn->get().d_conn.get(), reinterpret_cast(bufferStr.data()), bufferStr.size(), &recv_info); - if (done < 0) { - continue; - } - - if (quiche_conn_is_established(conn->get().d_conn.get())) { - DEBUGLOG("Connection is established"); - - if (!conn->get().d_http3) { - conn->get().d_http3 = QuicheHTTP3Connection(quiche_h3_conn_new_with_transport(conn->get().d_conn.get(), frontend->d_server_config->http3config.get()), - quiche_h3_conn_free); - if (!conn->get().d_http3) { - continue; - } - DEBUGLOG("Successfully created HTTP/3 connection"); - } - - processH3Events(*clientState, *frontend, conn->get(), client, serverConnID); - } - else { - DEBUGLOG("Connection not established"); - } + handleSocketReadable(*frontend, *clientState, sock); } if (std::find(readyFDs.begin(), readyFDs.end(), responseReceiverFD) != readyFDs.end()) {