From: Bert Hubert Date: Tue, 11 Jan 2011 19:59:06 +0000 (+0000) Subject: implement simplistic 60 dnssec key cache X-Git-Tag: auth-3.0~377 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=d473cb9ac5b31f0a1dfdff03bb3213902a95dfa3;p=pdns implement simplistic 60 dnssec key cache git-svn-id: svn://svn.powerdns.com/pdns/trunk/pdns@1870 d19b8d6e-7fed-0310-83ef-9ca221ded41b --- diff --git a/pdns/dbdnsseckeeper.cc b/pdns/dbdnsseckeeper.cc index 6d5e997cb..f543334f1 100644 --- a/pdns/dbdnsseckeeper.cc +++ b/pdns/dbdnsseckeeper.cc @@ -29,15 +29,33 @@ #include #include // for 'operator+=()' #include + + 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 "< 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(DNSRecordContent::mastermake(QType::NSEC3PARAM, 1, iter->d_nsec3param)); + *ns3p = *tmp; + delete tmp; + } + if(narrow) + *narrow = iter->d_narrow; + return true; + } } - meta.clear(); + vector 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 dbkeyset; d_db.getDomainKeys(zone, 0, dbkeyset); - // do db thing - //cerr<<"Here: received " < #include #include +#include +#include +#include +#include +#include + +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 > keyset_t; + }; + typedef std::pair keymeta_t; + typedef std::vector 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 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 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, CIStringCompare >, + sequenced<> + > + > keycache_t; + typedef multi_index_container< + NSECCacheEntry, + indexed_by< + ordered_unique, 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