diff -ru dnsdist-2.0.3.orig/dnsdist-concurrent-connections.cc dnsdist-2.0.3.CVE-2026-33254/dnsdist-concurrent-connections.cc --- dnsdist-2.0.3.orig/dnsdist-concurrent-connections.cc 2026-03-12 16:00:00.000000000 +0100 +++ dnsdist-2.0.3.CVE-2026-33254/dnsdist-concurrent-connections.cc 2026-04-03 15:50:27.196759683 +0200 @@ -164,7 +164,7 @@ return activity.front(); } -IncomingConcurrentTCPConnectionsManager::NewConnectionResult IncomingConcurrentTCPConnectionsManager::accountNewTCPConnection(const ComboAddress& from, bool isTLS) +IncomingConcurrentTCPConnectionsManager::NewConnectionResult IncomingConcurrentTCPConnectionsManager::accountNewTCPConnection(const ComboAddress& from, bool isTLS, bool isQUIC) { const auto& immutable = dnsdist::configuration::getImmutableConfiguration(); const auto maxConnsPerClient = immutable.d_maxTCPConnectionsPerClient; @@ -185,18 +185,22 @@ ++activity.tcpConnections; }; - auto checkConnectionAllowed = [now, from, maxConnsPerClient, threshold, tcpRate, tlsNewRate, tlsResumedRate, interval, isTLS, &immutable](const ClientEntry& entry) { + auto getProtocol = [isQUIC]() -> std::string { + return isQUIC ? "QUIC" : "TCP"; + }; + + auto checkConnectionAllowed = [now, from, maxConnsPerClient, threshold, tcpRate, tlsNewRate, tlsResumedRate, interval, isTLS, &immutable, &getProtocol](const ClientEntry& entry) { if (entry.d_bannedUntil != 0 && entry.d_bannedUntil >= now) { - vinfolog("Refusing TCP connection from %s: banned", from.toStringWithPort()); + vinfolog("Refusing %s connection from %s: banned", getProtocol(), from.toStringWithPort()); return NewConnectionResult::Denied; } if (maxConnsPerClient > 0 && entry.d_concurrentConnections >= maxConnsPerClient) { - vinfolog("Refusing TCP connection from %s: too many connections", from.toStringWithPort()); + vinfolog("Refusing %s connection from %s: too many connections", getProtocol(), from.toStringWithPort()); return NewConnectionResult::Denied; } if (!checkTCPConnectionsRate(entry.d_activity, now, tcpRate, tlsNewRate, tlsResumedRate, interval, isTLS)) { entry.d_bannedUntil = now + immutable.d_tcpBanDurationForExceedingTCPTLSRate; - vinfolog("Banning TCP connections from %s for %d seconds: too many new TCP/TLS connections per second", from.toStringWithPort(), immutable.d_tcpBanDurationForExceedingTCPTLSRate); + vinfolog("Banning connections from %s for %d seconds: too many new QUIC/TCP/TLS connections per second", from.toStringWithPort(), immutable.d_tcpBanDurationForExceedingTCPTLSRate); return NewConnectionResult::Denied; } @@ -208,7 +212,7 @@ if (current < threshold) { return NewConnectionResult::Allowed; } - vinfolog("Restricting TCP connection from %s: nearly reaching the maximum number of concurrent TCP connections", from.toStringWithPort()); + vinfolog("Restricting %s connection from %s: nearly reaching the maximum number of concurrent TCP connections", getProtocol(), from.toStringWithPort()); return NewConnectionResult::Restricted; }; diff -ru dnsdist-2.0.3.orig/dnsdist-concurrent-connections.hh dnsdist-2.0.3.CVE-2026-33254/dnsdist-concurrent-connections.hh --- dnsdist-2.0.3.orig/dnsdist-concurrent-connections.hh 2026-03-12 16:00:00.000000000 +0100 +++ dnsdist-2.0.3.CVE-2026-33254/dnsdist-concurrent-connections.hh 2026-04-03 15:50:27.196813905 +0200 @@ -34,7 +34,7 @@ Denied = 1, Restricted = 2, }; - static NewConnectionResult accountNewTCPConnection(const ComboAddress& from, bool isTLS); + static NewConnectionResult accountNewTCPConnection(const ComboAddress& from, bool isTLS, bool isQUIC = false); static bool isClientOverThreshold(const ComboAddress& from); static void accountTLSNewSession(const ComboAddress& from); static void accountTLSResumedSession(const ComboAddress& from); diff -ru dnsdist-2.0.3.orig/doh3.cc dnsdist-2.0.3.CVE-2026-33254/doh3.cc --- dnsdist-2.0.3.orig/doh3.cc 2026-03-12 16:00:00.000000000 +0100 +++ dnsdist-2.0.3.CVE-2026-33254/doh3.cc 2026-04-03 15:50:27.196895069 +0200 @@ -30,13 +30,12 @@ #include "misc.hh" #include "sstuff.hh" #include "threadname.hh" -#include "base64.hh" +#include "dnsdist-concurrent-connections.hh" #include "dnsdist-dnsparser.hh" #include "dnsdist-ecs.hh" #include "dnsdist-proxy-protocol.hh" #include "dnsdist-tcp.hh" -#include "dnsdist-random.hh" #include "doq-common.hh" @@ -60,7 +59,18 @@ H3Connection(H3Connection&&) = default; H3Connection& operator=(const H3Connection&) = delete; H3Connection& operator=(H3Connection&&) = default; - ~H3Connection() = default; + ~H3Connection() + { + try { + /* do not account if we have been moved! */ + if (d_conn) { + dnsdist::IncomingConcurrentTCPConnectionsManager::accountClosedTCPConnection(d_peer); + } + } + catch (...) { + /* in theory it might raise an exception, and we cannot allow it to be uncaught in a dtor */ + } + } std::shared_ptr getSNI() { @@ -962,6 +972,12 @@ continue; } + auto connectionResult = dnsdist::IncomingConcurrentTCPConnectionsManager::accountNewTCPConnection(client, true, true); + if (connectionResult == dnsdist::IncomingConcurrentTCPConnectionsManager::NewConnectionResult::Denied) { + DEBUGLOG("Connection not allowed!"); + continue; + } + DEBUGLOG("Creating a new connection"); conn = createConnection(*frontend.d_server_config, serverConnID, *originalDestinationID, localAddr, client); if (!conn) { Only in dnsdist-2.0.3.CVE-2026-33254: doh3.cc.orig diff -ru dnsdist-2.0.3.orig/doq.cc dnsdist-2.0.3.CVE-2026-33254/doq.cc --- dnsdist-2.0.3.orig/doq.cc 2026-03-12 16:00:00.000000000 +0100 +++ dnsdist-2.0.3.CVE-2026-33254/doq.cc 2026-04-03 15:50:27.197002313 +0200 @@ -31,11 +31,11 @@ #include "sstuff.hh" #include "threadname.hh" +#include "dnsdist-concurrent-connections.hh" #include "dnsdist-dnsparser.hh" #include "dnsdist-ecs.hh" #include "dnsdist-proxy-protocol.hh" #include "dnsdist-tcp.hh" -#include "dnsdist-random.hh" #include "doq-common.hh" @@ -59,7 +59,18 @@ Connection(Connection&&) = default; Connection& operator=(const Connection&) = delete; Connection& operator=(Connection&&) = default; - ~Connection() = default; + ~Connection() + { + try { + /* do not account if we have been moved! */ + if (d_conn) { + dnsdist::IncomingConcurrentTCPConnectionsManager::accountClosedTCPConnection(d_peer); + } + } + catch (...) { + /* in theory it might raise an exception, and we cannot allow it to be uncaught in a dtor */ + } + } std::shared_ptr getSNI() { @@ -753,6 +764,12 @@ continue; } + auto connectionResult = dnsdist::IncomingConcurrentTCPConnectionsManager::accountNewTCPConnection(client, true, true); + if (connectionResult == dnsdist::IncomingConcurrentTCPConnectionsManager::NewConnectionResult::Denied) { + DEBUGLOG("Connection not allowed!"); + continue; + } + DEBUGLOG("Creating a new connection"); conn = createConnection(*frontend.d_server_config, serverConnID, *originalDestinationID, client, localAddr); if (!conn) { Only in dnsdist-2.0.3.CVE-2026-33254: doq.cc.orig