]> granicus.if.org Git - pdns/commitdiff
rec: Move replaced negcache entries to the back of the expunge queue
authorRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 18 Apr 2019 08:05:03 +0000 (10:05 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Thu, 18 Apr 2019 08:05:03 +0000 (10:05 +0200)
Otherwise they might get expunged very quickly while they just have
been inserted.

pdns/cachecleaner.hh
pdns/recursordist/negcache.cc
pdns/recursordist/test-negcache_cc.cc

index 1d80b1740cbf0e0003a198a25298aab8d99ba7a5..884029858e1af8108b2eac2ad40fe609b4f15e45 100644 (file)
@@ -201,3 +201,15 @@ template <typename T> uint64_t purgeExactLockedCollection(T& mc, const DNSName&
 
   return delcount;
 }
+
+template<typename Index>
+std::pair<typename Index::iterator,bool>
+lruReplacingInsert(Index& i,const typename Index::value_type& x)
+{
+  std::pair<typename Index::iterator,bool> res = i.insert(x);
+  if (!res.second) {
+    moveCacheItemToBack(i, res.first);
+    res.second = i.replace(res.first, x);
+  }
+  return res;
+}
index 0f5325c33a4f0fe51f51226267b7d299562313ca..f7f5646f45d345f95e6ee50d469b1d4d264ade34 100644 (file)
@@ -101,7 +101,7 @@ bool NegCache::get(const DNSName& qname, const QType& qtype, const struct timeva
  * \param ne The NegCacheEntry to add to the cache
  */
 void NegCache::add(const NegCacheEntry& ne) {
-  replacing_insert(d_negcache, ne);
+  lruReplacingInsert(d_negcache, ne);
 }
 
 /*!
index f5ddec76b9a8e5256ffafdb39d9db1001fe1e26a..b67874c2ee1ff357e620e167e881423d851dfaee 100644 (file)
@@ -264,6 +264,59 @@ BOOST_AUTO_TEST_CASE(test_prune) {
   BOOST_CHECK_EQUAL(cache.size(), 100);
 }
 
+BOOST_AUTO_TEST_CASE(test_prune_valid_entries) {
+  DNSName power1("powerdns.com.");
+  DNSName power2("powerdns-1.com.");
+  DNSName auth("com.");
+
+  struct timeval now;
+  Utility::gettimeofday(&now, 0);
+
+  NegCache cache;
+  NegCache::NegCacheEntry ne;
+
+  /* insert power1 then power2 */
+  ne = genNegCacheEntry(power1, auth, now);
+  cache.add(ne);
+  ne = genNegCacheEntry(power2, auth, now);
+  cache.add(ne);
+
+  BOOST_CHECK_EQUAL(cache.size(), 2);
+
+  /* power2 has been inserted more recently, so it should be
+     removed last */
+  cache.prune(1);
+  BOOST_CHECK_EQUAL(cache.size(), 1);
+
+  const NegCache::NegCacheEntry* got = nullptr;
+  bool ret = cache.get(power2, QType(1), now, &got);
+  BOOST_REQUIRE(ret);
+  BOOST_CHECK_EQUAL(got->d_name, power2);
+  BOOST_CHECK_EQUAL(got->d_auth, auth);
+
+  /* insert power1 back */
+  ne = genNegCacheEntry(power1, auth, now);
+  cache.add(ne);
+  BOOST_CHECK_EQUAL(cache.size(), 2);
+
+  /* replace the entry for power2 */
+  ne = genNegCacheEntry(power2, auth, now);
+  cache.add(ne);
+
+  BOOST_CHECK_EQUAL(cache.size(), 2);
+
+  /* power2 has been updated more recently, so it should be
+     removed last */
+  cache.prune(1);
+
+  BOOST_CHECK_EQUAL(cache.size(), 1);
+  got = nullptr;
+  ret = cache.get(power2, QType(1), now, &got);
+  BOOST_REQUIRE(ret);
+  BOOST_CHECK_EQUAL(got->d_name, power2);
+  BOOST_CHECK_EQUAL(got->d_auth, auth);
+}
+
 BOOST_AUTO_TEST_CASE(test_wipe_single) {
   string qname(".powerdns.com");
   DNSName auth("powerdns.com");