]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
If the chain is old, refuse to add more entries to it
authorOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 22 Nov 2023 08:33:32 +0000 (09:33 +0100)
committerOtto Moerbeek <otto.moerbeek@open-xchange.com>
Wed, 22 May 2024 12:07:22 +0000 (14:07 +0200)
pdns/recursordist/lwres.cc
pdns/recursordist/lwres.hh
pdns/recursordist/pdns_recursor.cc
pdns/recursordist/settings/table.py
pdns/recursordist/syncres.cc
pdns/recursordist/syncres.hh

index 28e142ed85b75ed286394ccc61e5fe4f9d4997b0..7061b97f49a44f6af484f934eb707f697da93f6f 100644 (file)
@@ -468,7 +468,7 @@ static LWResult::Result asyncresolve(const ComboAddress& address, const DNSName&
   if (!doTCP) {
     int queryfd;
 
-    ret = asendto(vpacket.data(), vpacket.size(), 0, address, qid, domain, type, weWantEDNSSubnet, &queryfd);
+    ret = asendto(vpacket.data(), vpacket.size(), 0, address, qid, domain, type, weWantEDNSSubnet, &queryfd, *now);
 
     if (ret != LWResult::Result::Success) {
       return ret;
index 8fca61fe15aff946206d374346bacf57e741ff20..216d44c90cecd8464bc51f6146400445a7537247 100644 (file)
@@ -81,7 +81,7 @@ public:
 };
 
 LWResult::Result asendto(const void* data, size_t len, int flags, const ComboAddress& toAddress, uint16_t qid,
-                         const DNSName& domain, uint16_t qtype, bool ecs, int* fileDesc);
+                         const DNSName& domain, uint16_t qtype, bool ecs, int* fileDesc, timeval& now);
 LWResult::Result arecvfrom(PacketBuffer& packet, int flags, const ComboAddress& fromAddr, size_t& len, uint16_t qid,
                            const DNSName& domain, uint16_t qtype, int fileDesc, const struct timeval& now);
 
index 7713869ce6d5e83685ab1da511f550b7661fbabc..921d429a314acceb69828f2c71b9687358d149ab 100644 (file)
@@ -273,18 +273,17 @@ unsigned int authWaitTime(const std::unique_ptr<MT_t>& mtasker)
 {
   const auto max = g_maxMThreads;
   const auto current = mtasker->numProcesses();
-  const unsigned int cutoff = max / 10; /// if we have less than 10% used,  do not reduce auth timeout
+  const unsigned int cutoff = max / 10; // if we have less than 10% used,  do not reduce auth timeout
   if (current < cutoff) {
     return g_networkTimeoutMsec;
   }
-  // current is between cutoff and max
   const auto avail = max - current;
   return std::max(g_networkTimeoutMsec / 10, g_networkTimeoutMsec * avail / (max - cutoff));
 }
 
 /* these two functions are used by LWRes */
 LWResult::Result asendto(const void* data, size_t len, int /* flags */,
-                         const ComboAddress& toAddress, uint16_t qid, const DNSName& domain, uint16_t qtype, bool ecs, int* fileDesc)
+                         const ComboAddress& toAddress, uint16_t qid, const DNSName& domain, uint16_t qtype, bool ecs, int* fileDesc, timeval& now)
 {
 
   auto pident = std::make_shared<PacketID>();
@@ -307,13 +306,19 @@ LWResult::Result asendto(const void* data, size_t len, int /* flags */,
       // don't chain onto existing chained waiter or a chain already processed
       if (chain.first->key->fd > -1 && !chain.first->key->closed) {
         *fileDesc = -1; // gets used in waitEvent / sendEvent later on
-        if (g_maxChainLength > 0 && chain.first->key->authReqChain.size() >= g_maxChainLength) {
+        auto currentChainSize = chain.first->key->authReqChain.size();
+        if (g_maxChainLength > 0 && currentChainSize >= g_maxChainLength) {
+          return  LWResult::Result::OSLimitError;
+        }
+        assert(uSec(chain.first->key->creationTime) != 0);
+        auto age = now - chain.first->key->creationTime;
+        if (uSec(age) > static_cast<uint64_t>(1000) * authWaitTime(g_multiTasker) * 2 / 3) {
           return  LWResult::Result::OSLimitError;
         }
         chain.first->key->authReqChain.insert(qid); // we can chain
         auto maxLength = t_Counters.at(rec::Counter::maxChainLength);
-        if (chain.first->key->authReqChain.size() > maxLength) {
-          t_Counters.at(rec::Counter::maxChainLength) = chain.first->key->authReqChain.size();
+        if (currentChainSize > maxLength) {
+          t_Counters.at(rec::Counter::maxChainLength) = currentChainSize;
         }
         return LWResult::Result::Success;
       }
@@ -353,6 +358,7 @@ LWResult::Result arecvfrom(PacketBuffer& packet, int /* flags */, const ComboAdd
   pident->domain = domain;
   pident->type = qtype;
   pident->remote = fromAddr;
+  pident->creationTime = now;
 
   int ret = g_multiTasker->waitEvent(pident, &packet, authWaitTime(g_multiTasker), &now);
   len = 0;
index 0525094dfee3cce534c3fb50d7fa78e2093686c1..2ac1fe069d7da9f002f61cd87ab4b64ed74c3cea 100644 (file)
@@ -1499,7 +1499,7 @@ means unlimited.
         'default' : '2048',
         'help' : 'Maximum number of simultaneous Mtasker threads',
         'doc' : '''
-Maximum number of simultaneous MTasker threads.
+Maximum number of simultaneous MTasker threads, per worker thread.
  ''',
     },
     {
@@ -1816,6 +1816,7 @@ a new domain is observed.
         'help' : 'Wait this number of milliseconds for network i/o',
         'doc' : '''
 Number of milliseconds to wait for a remote authoritative server to respond.
+If the number of concurrent requests is high, the :program:Recursor uses a lower value.
  ''',
     },
     {
index 01ee4cdc4e501f5c72a2a971d0828341c85f75d3..268a55d850b039dd5c6339b14aaa6d9de3640e3f 100644 (file)
@@ -5400,7 +5400,6 @@ bool SyncRes::doResolveAtThisIP(const std::string& prefix, const DNSName& qname,
     // don't account for resource limits, they are our own fault
     // And don't throttle when the IP address is on the dontThrottleNetmasks list or the name is part of dontThrottleNames
     if (resolveret != LWResult::Result::OSLimitError && !chained && !dontThrottle) {
-      cerr << "THROTTLING !!!!" << remoteIP.toString() << ' ' << int(resolveret) << endl;
       s_nsSpeeds.lock()->find_or_enter(nsName.empty() ? DNSName(remoteIP.toStringWithPort()) : nsName, d_now).submit(remoteIP, 1000000, d_now); // 1 sec
 
       // make sure we don't throttle the root
index 50626a37a1231ef622ecab295be9bb4c78c455d1..bf9fab1b387c1e5fdc848c8f0603866504d704fb 100644 (file)
@@ -764,6 +764,7 @@ struct PacketID
   using chain_t = set<uint16_t>;
   mutable chain_t authReqChain;
   shared_ptr<TCPIOHandler> tcphandler{nullptr};
+  timeval creationTime{};
   string::size_type inPos{0}; // how far are we along in the inMSG
   size_t inWanted{0}; // if this is set, we'll read until inWanted bytes are read
   string::size_type outPos{0}; // how far we are along in the outMSG