]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
dnsdist: Clear owned downstream TCP connections as soon as possible
authorRemi Gacogne <remi.gacogne@powerdns.com>
Fri, 7 Mar 2025 11:34:46 +0000 (12:34 +0100)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Wed, 30 Apr 2025 10:43:26 +0000 (12:43 +0200)
(cherry picked from commit bcf887845bea6ac273b885da694ee70e80569824)

pdns/dnsdist-tcp.cc
pdns/dnsdistdist/dnsdist-tcp-upstream.hh

index 6ae523bc80cb560ca6c7f847625c636f6eaf77c6..f24912f206c6d2feee212cc6e20a30cb2525538b 100644 (file)
@@ -128,6 +128,7 @@ static std::pair<std::shared_ptr<TCPConnectionToBackend>, bool> getOwnedDownstre
       if (conn->matchesTLVs(tlvs)) {
         DEBUGLOG("Got one owned connection accepting more for " << backend->getName());
         conn->setReused();
+        ++backend->tcpReusedConnections;
         return {conn, tlvsMismatch};
       }
       DEBUGLOG("Found one connection to " << backend->getName() << " but with different TLV values");
@@ -144,6 +145,10 @@ std::shared_ptr<TCPConnectionToBackend> IncomingTCPConnectionState::getDownstrea
   auto [downstream, tlvsMismatch] = getOwnedDownstreamConnection(d_ownedConnectionsToBackend, backend, tlvs);
 
   if (!downstream) {
+    if (backend->d_config.useProxyProtocol && tlvsMismatch) {
+      clearOwnedDownstreamConnections(backend);
+    }
+
     /* we don't have a connection to this backend owned yet, let's get one (it might not be a fresh one, though) */
     downstream = t_downstreamTCPConnectionsManager.getConnectionToDownstream(d_threadData.mplexer, backend, now, std::string());
     // if we had an existing connection but the TLVs are different, they are likely unique per query so do not bother keeping the connection
@@ -322,6 +327,11 @@ void IncomingTCPConnectionState::registerOwnedDownstreamConnection(std::shared_p
   }
 }
 
+void IncomingTCPConnectionState::clearOwnedDownstreamConnections(const std::shared_ptr<DownstreamState>& downstream)
+{
+  d_ownedConnectionsToBackend.erase(downstream);
+}
+
 /* called when the buffer has been set and the rules have been processed, and only from handleIO (sometimes indirectly via handleQuery) */
 IOState IncomingTCPConnectionState::sendResponse(const struct timeval& now, TCPResponse&& response)
 {
index 58b88bb26d96413726083430c356f59589a06f4e..93d7489bd27767c51d5bc736cab45649ccdaa00a 100644 (file)
@@ -118,6 +118,7 @@ public:
 
   std::shared_ptr<TCPConnectionToBackend> getDownstreamConnection(std::shared_ptr<DownstreamState>& backend, const std::unique_ptr<std::vector<ProxyProtocolValue>>& tlvs, const struct timeval& now);
   void registerOwnedDownstreamConnection(std::shared_ptr<TCPConnectionToBackend>& conn);
+  void clearOwnedDownstreamConnections(const std::shared_ptr<DownstreamState>& downstream);
 
   static size_t clearAllDownstreamConnections();