]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Split DoH3 'socket readable' to a separate function
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 22 Dec 2023 15:54:20 +0000 (16:54 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 22 Dec 2023 15:54:20 +0000 (16:54 +0100)
pdns/dnsdistdist/doh3.cc

index e3c14ccee8cb74b34fa675d8e655736b245ffab7..ab526f4981a56c7b4e6225741194e6881ff87eae 100644 (file)
@@ -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<uint8_t, QUICHE_MAX_CONN_ID_LEN> scid{};
+  size_t scid_len = scid.size();
+  std::array<uint8_t, QUICHE_MAX_CONN_ID_LEN> dcid{};
+  size_t dcid_len = dcid.size();
+  std::array<uint8_t, MAX_TOKEN_LEN> token{};
+  size_t token_len = token.size();
+
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+  auto res = quiche_header_info(reinterpret_cast<const uint8_t*>(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<struct sockaddr*>(&client),
+    client.getSocklen(),
+    // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+    reinterpret_cast<struct sockaddr*>(&clientState.local),
+    clientState.local.getSocklen(),
+  };
+
+  // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
+  auto done = quiche_conn_recv(conn->get().d_conn.get(), reinterpret_cast<uint8_t*>(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<uint8_t, QUICHE_MAX_CONN_ID_LEN> scid{};
-        size_t scid_len = scid.size();
-        std::array<uint8_t, QUICHE_MAX_CONN_ID_LEN> dcid{};
-        size_t dcid_len = dcid.size();
-        std::array<uint8_t, MAX_TOKEN_LEN> token{};
-        size_t token_len = token.size();
-
-        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-        auto res = quiche_header_info(reinterpret_cast<const uint8_t*>(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<struct sockaddr*>(&client),
-          client.getSocklen(),
-          // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-          reinterpret_cast<struct sockaddr*>(&clientState->local),
-          clientState->local.getSocklen(),
-        };
-
-        // NOLINTNEXTLINE(cppcoreguidelines-pro-type-reinterpret-cast)
-        auto done = quiche_conn_recv(conn->get().d_conn.get(), reinterpret_cast<uint8_t*>(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()) {