]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/recursordist/recpacketcache.cc
Merge pull request #13387 from omoerbeek/rec-b-root-servers
[thirdparty/pdns.git] / pdns / recursordist / recpacketcache.cc
index 10fa9cbd1d9ea8adfae8ed4002ce1a0d13ea84ff..0b54090e058a9e7b28ec86ca7bce677d562d2789 100644 (file)
 
 unsigned int RecursorPacketCache::s_refresh_ttlperc{0};
 
+void RecursorPacketCache::setShardSizes(size_t shardSize)
+{
+  for (auto& shard : d_maps) {
+    auto lock = shard.lock();
+    lock->d_shardSize = shardSize;
+  }
+}
+
 uint64_t RecursorPacketCache::size() const
 {
   uint64_t count = 0;
   for (const auto& map : d_maps) {
-    count += map.d_entriesCount;
+    count += map.getEntriesCount();
   }
   return count;
 }
@@ -53,6 +61,18 @@ uint64_t RecursorPacketCache::getMisses()
   return sum;
 }
 
+pair<uint64_t, uint64_t> RecursorPacketCache::stats()
+{
+  uint64_t contended = 0;
+  uint64_t acquired = 0;
+  for (auto& shard : d_maps) {
+    auto content = shard.lock();
+    contended += content->d_contended_count;
+    acquired += content->d_acquired_count;
+  }
+  return {contended, acquired};
+}
+
 uint64_t RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qtype, bool subtree)
 {
   uint64_t count = 0;
@@ -72,7 +92,7 @@ uint64_t RecursorPacketCache::doWipePacketCache(const DNSName& name, uint16_t qt
       }
       if (qtype == 0xffff || iter->d_type == qtype) {
         iter = idx.erase(iter);
-        map.d_entriesCount--;
+        map.decEntriesCount();
         count++;
       }
       else {
@@ -106,12 +126,16 @@ bool RecursorPacketCache::checkResponseMatches(MapCombo::LockedContent& shard, s
       *age = static_cast<uint32_t>(now - iter->d_creation);
       // we know ttl is > 0
       auto ttl = static_cast<uint32_t>(iter->d_ttd - now);
-      if (s_refresh_ttlperc > 0 && !iter->d_submitted) {
-        const uint32_t deadline = iter->getOrigTTL() * s_refresh_ttlperc / 100;
-        const bool almostExpired = ttl <= deadline;
-        if (almostExpired) {
-          iter->d_submitted = true;
-          pushAlmostExpiredTask(qname, qtype, iter->d_ttd, Netmask());
+      if (s_refresh_ttlperc > 0 && !iter->d_submitted && taskQTypeIsSupported(qtype)) {
+        const dnsheader_aligned header(iter->d_packet.data());
+        const auto* headerPtr = header.get();
+        if (headerPtr->rcode == RCode::NoError) {
+          const uint32_t deadline = iter->getOrigTTL() * s_refresh_ttlperc / 100;
+          const bool almostExpired = ttl <= deadline;
+          if (almostExpired) {
+            iter->d_submitted = true;
+            pushAlmostExpiredTask(qname, qtype, iter->d_ttd, Netmask());
+          }
         }
       }
       *responsePacket = iter->d_packet;
@@ -211,26 +235,26 @@ void RecursorPacketCache::insertResponsePacket(unsigned int tag, uint32_t qhash,
     return;
   }
 
-  struct Entry entry(qname, qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState);
+  struct Entry entry(DNSName(qname), qtype, qclass, std::move(responsePacket), std::move(query), tcp, qhash, now + ttl, now, tag, valState);
   if (pbdata) {
     entry.d_pbdata = std::move(*pbdata);
   }
 
   shard->d_map.insert(entry);
-  map.d_entriesCount++;
+  map.incEntriesCount();
 
-  if (shard->d_map.size() > d_maxSize / d_maps.size()) {
+  if (shard->d_map.size() > shard->d_shardSize) {
     auto& seq_idx = shard->d_map.get<SequencedTag>();
     seq_idx.erase(seq_idx.begin());
-    map.d_entriesCount--;
+    map.decEntriesCount();
   }
-  assert(map.d_entriesCount == shard->d_map.size()); // XXX
+  assert(map.getEntriesCount() == shard->d_map.size()); // NOLINT(cppcoreguidelines-pro-bounds-array-to-pointer-decay): clib implementation
 }
 
-void RecursorPacketCache::doPruneTo(size_t maxSize)
+void RecursorPacketCache::doPruneTo(time_t now, size_t maxSize)
 {
   size_t cacheSize = size();
-  pruneMutexCollectionsVector<SequencedTag>(*this, d_maps, maxSize, cacheSize);
+  pruneMutexCollectionsVector<SequencedTag>(now, d_maps, maxSize, cacheSize);
 }
 
 uint64_t RecursorPacketCache::doDump(int file)
@@ -251,16 +275,18 @@ uint64_t RecursorPacketCache::doDump(int file)
   size_t shardNum = 0;
   size_t min = std::numeric_limits<size_t>::max();
   size_t max = 0;
+  uint64_t maxSize = 0;
 
   for (auto& shard : d_maps) {
     auto lock = shard.lock();
     const auto& sidx = lock->d_map.get<SequencedTag>();
     const auto shardSize = lock->d_map.size();
-    fprintf(filePtr.get(), "; packetcache shard %zu; size %zu\n", shardNum, shardSize);
+    fprintf(filePtr.get(), "; packetcache shard %zu; size %zu/%zu\n", shardNum, shardSize, lock->d_shardSize);
     min = std::min(min, shardSize);
     max = std::max(max, shardSize);
+    maxSize += lock->d_shardSize;
     shardNum++;
-  for (const auto& entry : sidx) {
+    for (const auto& entry : sidx) {
       count++;
       try {
         fprintf(filePtr.get(), "%s %" PRId64 " %s  ; tag %d %s\n", entry.d_name.toString().c_str(), static_cast<int64_t>(entry.d_ttd - now), DNSRecordContent::NumberToType(entry.d_type).c_str(), entry.d_tag, entry.d_tcp ? "tcp" : "udp");
@@ -270,6 +296,6 @@ uint64_t RecursorPacketCache::doDump(int file)
       }
     }
   }
-  fprintf(filePtr.get(), "; packetcache size: %" PRIu64 "/%zu shards: %zu min/max shard size: %zu/%zu\n", size(), d_maxSize, d_maps.size(), min, max);
+  fprintf(filePtr.get(), "; packetcache size: %" PRIu64 "/%" PRIu64 " shards: %zu min/max shard size: %zu/%zu\n", size(), maxSize, d_maps.size(), min, max);
   return count;
 }