]> granicus.if.org Git - pdns/commitdiff
implement simplistic 60 dnssec key cache
authorBert Hubert <bert.hubert@netherlabs.nl>
Tue, 11 Jan 2011 19:59:06 +0000 (19:59 +0000)
committerBert Hubert <bert.hubert@netherlabs.nl>
Tue, 11 Jan 2011 19:59:06 +0000 (19:59 +0000)
git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1870 d19b8d6e-7fed-0310-83ef-9ca221ded41b

pdns/dbdnsseckeeper.cc
pdns/dnsseckeeper.hh

index 6d5e997cb501a89f4a780c149f77fde7d157fff9..f543334f17fe5d3769039720e4e78bae7fb66ee7 100644 (file)
 #include <boost/format.hpp>
 #include <boost/assign/std/vector.hpp> // for 'operator+=()'
 #include <boost/assign/list_inserter.hpp>
+
+
 using namespace boost::assign;
 using namespace std;
 using namespace boost;
 
+DNSSECKeeper::keycache_t DNSSECKeeper::s_keycache;
+DNSSECKeeper::nseccache_t DNSSECKeeper::s_nseccache;
+pthread_mutex_t DNSSECKeeper::s_nseccachelock = PTHREAD_MUTEX_INITIALIZER;
+pthread_mutex_t DNSSECKeeper::s_keycachelock = PTHREAD_MUTEX_INITIALIZER;
+
 bool DNSSECKeeper::haveActiveKSKFor(const std::string& zone) 
 {
+  {
+    Lock l(&s_keycachelock);
+    keycache_t::const_iterator iter = s_keycache.find(zone);
+    if(iter != s_keycache.end() && iter->d_ttd < time(0)) { 
+      if(iter->d_keys.empty())
+        return false;
+      else
+        return true;
+    }
+    else
+      ; 
+  }
   keyset_t keys = getKeys(zone, true);
-  // need to get an *active* one!
-  //cerr<<__FUNCTION__<<"Got "<<keys.size()<<" keys"<<endl;
+  
   BOOST_FOREACH(keyset_t::value_type& val, keys) {
     if(val.second.active) {
       return true;
@@ -115,19 +133,51 @@ void DNSSECKeeper::activateKey(const std::string& zname, unsigned int id)
 
 bool DNSSECKeeper::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* ns3p, bool* narrow)
 {
-  vector<string> meta;
-  if(narrow) {
-    d_db.getDomainMetadata(zname, "NSEC3NARROW", meta);
-    *narrow=false;
-    if(!meta.empty() && meta[0]=="1")
-      *narrow=true;
+  time_t now = time(0);
+  {
+    Lock l(&s_nseccachelock); 
+    
+    nseccache_t::const_iterator iter = s_nseccache.find(zname);
+    if(iter != s_nseccache.end() && iter->d_ttd < now)
+    {
+      if(iter->d_nsec3param.empty()) // this says: no NSEC3
+        return false;
+        
+      if(ns3p) {
+        NSEC3PARAMRecordContent* tmp=dynamic_cast<NSEC3PARAMRecordContent*>(DNSRecordContent::mastermake(QType::NSEC3PARAM, 1, iter->d_nsec3param));
+        *ns3p = *tmp;
+        delete tmp;
+      }
+      if(narrow)
+        *narrow = iter->d_narrow;
+      return true;
+    }
   }
-  meta.clear();
+  vector<string> meta;
   d_db.getDomainMetadata(zname, "NSEC3PARAM", meta);
   
-  if(meta.empty())
-    return false;
+  NSECCacheEntry nce;
+  nce.d_domain=zname;
+  nce.d_ttd = now+60;
+  
+  if(meta.empty()) {
+    nce.d_nsec3param.clear(); // store 'no nsec3'
+    nce.d_narrow = false;
+    Lock l(&s_nseccachelock);
+    s_nseccache.insert(nce);
     
+    return false;
+  }
+  nce.d_nsec3param = *meta.begin();
+  
+  meta.clear();
+  d_db.getDomainMetadata(zname, "NSEC3NARROW", meta);
+  nce.d_narrow = meta.empty() || meta[1]!="1";
+  
+  if(narrow) {
+    *narrow=nce.d_narrow;
+  }
+  
   if(ns3p) {
     string descr = *meta.begin();
     reportAllTypes();
@@ -139,6 +189,9 @@ bool DNSSECKeeper::getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordConte
     *ns3p = *tmp;
     delete tmp;
   }
+  Lock l(&s_nseccachelock);
+  s_nseccache.insert(nce);
+  
   return true;
 }
 
@@ -163,12 +216,21 @@ void DNSSECKeeper::unsetNSEC3PARAM(const std::string& zname)
 
 DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const std::string& zone, boost::tribool allOrKeyOrZone) 
 {
+  time_t now = time(0);
+  {
+    Lock l(&s_keycachelock);
+    keycache_t::const_iterator iter = s_keycache.find(zone);
+    if(iter != s_keycache.end() && iter->d_ttd < now) { 
+      return iter->d_keys;
+    }
+    
+  }
+  
   keyset_t keyset;
   vector<UeberBackend::KeyData> dbkeyset;
   
   d_db.getDomainKeys(zone, 0, dbkeyset);
-  // do db thing
-  //cerr<<"Here: received " <<dbkeyset.size()<<" keys"<<endl;
+  
   BOOST_FOREACH(UeberBackend::KeyData& kd, dbkeyset) 
   {
     DNSSECPrivateKey dpk;
@@ -189,6 +251,14 @@ DNSSECKeeper::keyset_t DNSSECKeeper::getKeys(const std::string& zone, boost::tri
       keyset.push_back(make_pair(dpk, kmd));
   }
   sort(keyset.begin(), keyset.end(), keyCompareByKindAndID);
+  Lock l(&s_keycachelock);
+  
+  KeyCacheEntry kce;
+  kce.d_domain=zone;
+  kce.d_keys = keyset;
+  kce.d_ttd = now + 60;
+  s_keycache.insert(kce);
+  
   return keyset;
 }
 
index f004e06981a03497040dca76d2164e0ef815b140..1f93ee53d3d659185580d59d6463ab236b0b9bb7 100644 (file)
@@ -5,6 +5,13 @@
 #include <string.h>
 #include <vector>
 #include <boost/logic/tribool.hpp>
+#include <boost/multi_index_container.hpp>
+#include <boost/multi_index/ordered_index.hpp>
+#include <boost/tuple/tuple_comparison.hpp>
+#include <boost/multi_index/key_extractors.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
+
+using namespace ::boost::multi_index;
 #include "dnsrecords.hh"
 #include "ueberbackend.hh"
 
@@ -113,8 +120,9 @@ public:
     bool active;
     bool keyOrZone;
     string fname;
-  }; 
-  typedef std::vector<std::pair<DNSSECPrivateKey, KeyMetaData> > keyset_t;
+  };
+  typedef std::pair<DNSSECPrivateKey, KeyMetaData> keymeta_t; 
+  typedef std::vector<keymeta_t > keyset_t;
 private:
   UeberBackend d_db;
 public:
@@ -134,6 +142,58 @@ public:
   bool getNSEC3PARAM(const std::string& zname, NSEC3PARAMRecordContent* n3p=0, bool* narrow=0);
   void setNSEC3PARAM(const std::string& zname, const NSEC3PARAMRecordContent& n3p, const bool& narrow=false);
   void unsetNSEC3PARAM(const std::string& zname);
+  
+  struct KeyCacheEntry
+  {
+    typedef vector<DNSSECKeeper::keymeta_t> keys_t;
+  
+    uint32_t getTTD() const
+    {
+      return d_ttd;
+    }
+  
+    string d_domain;
+    unsigned int d_ttd;
+    mutable keys_t d_keys;
+  };
+  
+  struct NSECCacheEntry
+  {
+    NSECCacheEntry() : d_narrow(false) {}
+    typedef vector<DNSSECKeeper::keymeta_t> keys_t;
+  
+    uint32_t getTTD() const
+    {
+      return d_ttd;
+    }
+  
+    string d_domain;
+    unsigned int d_ttd;
+  
+    mutable std::string d_nsec3param;
+    mutable bool d_narrow;
+  };
+  
+  
+  typedef multi_index_container<
+    KeyCacheEntry,
+    indexed_by<
+      ordered_unique<member<KeyCacheEntry, std::string, &KeyCacheEntry::d_domain>, CIStringCompare >,
+      sequenced<>
+    >
+  > keycache_t;
+  typedef multi_index_container<
+    NSECCacheEntry,
+    indexed_by<
+      ordered_unique<member<NSECCacheEntry, std::string, &NSECCacheEntry::d_domain>, CIStringCompare >,
+      sequenced<>
+    >
+  > nseccache_t;
+
+  static keycache_t s_keycache;
+  static nseccache_t s_nseccache;
+  static pthread_mutex_t s_keycachelock;
+  static pthread_mutex_t s_nseccachelock;
 };
 
 #endif