]> granicus.if.org Git - pdns/commitdiff
rec: Cleanup the StaticStorage object, renamed to ThreadLocalStorage
authorRemi Gacogne <remi.gacogne@powerdns.com>
Tue, 4 Apr 2017 17:02:25 +0000 (19:02 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Sun, 14 May 2017 12:30:55 +0000 (14:30 +0200)
pdns/pdns_recursor.cc
pdns/rec_channel_rec.cc
pdns/recursordist/test-syncres_cc.cc
pdns/reczones.cc
pdns/syncres.cc
pdns/syncres.hh
pdns/ws-recursor.cc

index 44b6fdc1e6162859015577d12849551ba2906c2d..90d30ea35e758f6bf06adf19c341f5ce91547e29 100644 (file)
@@ -1424,7 +1424,7 @@ static void handleRunningTCPQuestion(int fd, FDMultiplexer::funcparam_t& var)
 
           if(t_pdl && t_pdl->d_gettag) {
             try {
-              dc->d_tag = t_pdl->gettag(conn->d_remote, dc->d_ednssubnet.source, dest, qname, qtype, &dc->d_policyTags, dc->d_data, ednsOptionsn true, requestorId);
+              dc->d_tag = t_pdl->gettag(conn->d_remote, dc->d_ednssubnet.source, dest, qname, qtype, &dc->d_policyTags, dc->d_data, ednsOptions, true, requestorId);
             }
             catch(std::exception& e)  {
               if(g_logCommonErrors)
@@ -2060,15 +2060,11 @@ static void houseKeeping(void *)
       t_RC->doPrune(); // this function is local to a thread, so fine anyhow
       t_packetCache->doPruneTo(::arg().asNum("max-packetcache-entries") / g_numWorkerThreads);
 
-      t_sstorage->negcache.prune(::arg().asNum("max-cache-entries") / (g_numWorkerThreads * 10));
+      SyncRes::pruneNegCache(::arg().asNum("max-cache-entries") / (g_numWorkerThreads * 10));
 
       if(!((cleanCounter++)%40)) {  // this is a full scan!
        time_t limit=now.tv_sec-300;
-       for(SyncRes::nsspeeds_t::iterator i = t_sstorage->nsSpeeds.begin() ; i!= t_sstorage->nsSpeeds.end(); )
-         if(i->second.stale(limit))
-           i = t_sstorage->nsSpeeds.erase(i);
-         else
-           ++i;
+        SyncRes::pruneNSSpeeds(limit);
       }
       last_prune=time(0);
     }
@@ -2948,7 +2944,7 @@ try
 {
   t_id=(int) (long) ptr;
   SyncRes tmp(g_now); // make sure it allocates tsstorage before we do anything, like primeHints or so..
-  t_sstorage->domainmap = g_initialDomainMap;
+  SyncRes::setDomainMap(g_initialDomainMap);
   t_allowFrom = g_initialAllowFrom;
   t_udpclientsocks = std::unique_ptr<UDPClientSocks>(new UDPClientSocks());
   t_tcpClientCounts = std::unique_ptr<tcpClientCounts_t>(new tcpClientCounts_t());
index c9f37df019807876ea348305fb4b70b3a3e99ba5..ce3a0d452358c3a6d6edfe44305bd9ddd93c76f3 100644 (file)
@@ -191,7 +191,7 @@ static uint64_t dumpNegCache(NegCache& negcache, int fd)
 
 static uint64_t* pleaseDump(int fd)
 {
-  return new uint64_t(t_RC->doDump(fd) + dumpNegCache(t_sstorage->negcache, fd) + t_packetCache->doDump(fd));
+  return new uint64_t(t_RC->doDump(fd) + dumpNegCache(SyncRes::t_sstorage.negcache, fd) + t_packetCache->doDump(fd));
 }
 
 static uint64_t* pleaseDumpNSSpeeds(int fd)
@@ -274,7 +274,7 @@ uint64_t* pleaseWipePacketCache(const DNSName& canon, bool subtree)
 
 uint64_t* pleaseWipeAndCountNegCache(const DNSName& canon, bool subtree)
 {
-  uint64_t ret = t_sstorage->negcache.wipe(canon, subtree);
+  uint64_t ret = SyncRes::wipeNegCache(canon, subtree);
   return new uint64_t(ret);
 }
 
@@ -621,7 +621,7 @@ static string doCurrentQueries()
 
 uint64_t* pleaseGetThrottleSize()
 {
-  return new uint64_t(t_sstorage ? t_sstorage->throttle.size() : 0);
+  return new uint64_t(SyncRes::getThrottledServersSize());
 }
 
 static uint64_t getThrottleSize()
@@ -631,7 +631,7 @@ static uint64_t getThrottleSize()
 
 uint64_t* pleaseGetNegCacheSize()
 {
-  uint64_t tmp=(t_sstorage ? t_sstorage->negcache.size() : 0);
+  uint64_t tmp=(SyncRes::getNegCacheSize());
   return new uint64_t(tmp);
 }
 
@@ -642,7 +642,7 @@ uint64_t getNegCacheSize()
 
 uint64_t* pleaseGetFailedHostsSize()
 {
-  uint64_t tmp=(t_sstorage ? t_sstorage->fails.size() : 0);
+  uint64_t tmp=(SyncRes::getThrottledServersSize());
   return new uint64_t(tmp);
 }
 uint64_t getFailedHostsSize()
@@ -652,7 +652,7 @@ uint64_t getFailedHostsSize()
 
 uint64_t* pleaseGetNsSpeedsSize()
 {
-  return new uint64_t(t_sstorage ? t_sstorage->nsSpeeds.size() : 0);
+  return new uint64_t(SyncRes::getNSSpeedsSize());
 }
 
 uint64_t getNsSpeedsSize()
index b446e02a7a8df4686d0761dbe74dab01273190db..9072f63c598818a7e24ffe1d718910d9a9c826f3 100644 (file)
@@ -127,6 +127,11 @@ static void init(bool debug=false)
   SyncRes::clearDelegationOnly();
   SyncRes::clearDontQuery();
 
+  SyncRes::clearNSSpeeds();
+  SyncRes::clearEDNSStatuses();
+  SyncRes::clearThrottle();
+  SyncRes::clearFailedServers();
+
   auto luaconfsCopy = g_luaconfs.getCopy();
   luaconfsCopy.dfe.clear();
   g_luaconfs.setState(luaconfsCopy);
@@ -149,13 +154,8 @@ static void initSR(std::unique_ptr<SyncRes>& sr, bool edns0, bool dnssec, SyncRe
   sr->setDoEDNS0(edns0);
   sr->setDoDNSSEC(dnssec);
   sr->setLogMode(lm);
-  t_sstorage->domainmap = std::make_shared<SyncRes::domainmap_t>();
-  t_sstorage->negcache.clear();
-  t_sstorage->nsSpeeds.clear();
-  t_sstorage->ednsstatus.clear();
-  t_sstorage->throttle.clear();
-  t_sstorage->fails.clear();
-  t_sstorage->dnssecmap.clear();
+  SyncRes::setDomainMap(std::make_shared<SyncRes::domainmap_t>());
+  SyncRes::clearNegCache();
 }
 
 static void setLWResult(LWResult* res, int rcode, bool aa=false, bool tc=false, bool edns=false)
@@ -299,7 +299,7 @@ BOOST_AUTO_TEST_CASE(test_root_not_primed_and_no_response) {
   BOOST_CHECK(downServers.size() > 0);
   /* we explicitly refuse to mark the root servers down */
   for (const auto& server : downServers) {
-    BOOST_CHECK_EQUAL(t_sstorage->fails.value(server), 0);
+    BOOST_CHECK_EQUAL(SyncRes::getServerFailsCount(server), 0);
   }
 }
 
@@ -341,8 +341,8 @@ BOOST_AUTO_TEST_CASE(test_edns_formerr_fallback) {
   BOOST_CHECK_EQUAL(ret.size(), 1);
   BOOST_CHECK_EQUAL(queriesWithEDNS, 1);
   BOOST_CHECK_EQUAL(queriesWithoutEDNS, 1);
-  BOOST_CHECK_EQUAL(t_sstorage->ednsstatus.size(), 1);
-  BOOST_CHECK_EQUAL(t_sstorage->ednsstatus[noEDNSServer].mode, SyncRes::EDNSStatus::NOEDNS);
+  BOOST_CHECK_EQUAL(SyncRes::getEDNSStatusesSize(), 1);
+  BOOST_CHECK_EQUAL(SyncRes::getEDNSStatus(noEDNSServer), SyncRes::EDNSStatus::NOEDNS);
 }
 
 BOOST_AUTO_TEST_CASE(test_edns_notimp_fallback) {
@@ -451,8 +451,8 @@ BOOST_AUTO_TEST_CASE(test_all_nss_down) {
   BOOST_CHECK_EQUAL(downServers.size(), 4);
 
   for (const auto& server : downServers) {
-    BOOST_CHECK_EQUAL(t_sstorage->fails.value(server), 1);
-    BOOST_CHECK(t_sstorage->throttle.shouldThrottle(time(nullptr), boost::make_tuple(server, target, QType::A)));
+    BOOST_CHECK_EQUAL(SyncRes::getServerFailsCount(server), 1);
+    BOOST_CHECK(SyncRes::isThrottled(time(nullptr), server, target, QType::A));
   }
 }
 
@@ -499,8 +499,9 @@ BOOST_AUTO_TEST_CASE(test_all_nss_network_error) {
   BOOST_CHECK_EQUAL(downServers.size(), 4);
 
   for (const auto& server : downServers) {
-    BOOST_CHECK_EQUAL(t_sstorage->fails.value(server), 1);
-    BOOST_CHECK(t_sstorage->throttle.shouldThrottle(time(nullptr), boost::make_tuple(server, target, QType::A)));
+    BOOST_CHECK_EQUAL(SyncRes::getServerFailsCount(server), 1);
+    BOOST_CHECK(SyncRes::isThrottled(time(nullptr), server, target, QType::A));
+;
   }
 }
 
@@ -555,8 +556,8 @@ BOOST_AUTO_TEST_CASE(test_os_limit_errors) {
 
   /* Error is reported as "OS limit error" (-2) so the servers should _NOT_ be marked down */
   for (const auto& server : downServers) {
-    BOOST_CHECK_EQUAL(t_sstorage->fails.value(server), 0);
-    BOOST_CHECK(!t_sstorage->throttle.shouldThrottle(time(nullptr), boost::make_tuple(server, target, QType::A)));
+    BOOST_CHECK_EQUAL(SyncRes::getServerFailsCount(server), 0);
+    BOOST_CHECK(!SyncRes::isThrottled(time(nullptr), server, target, QType::A));
   }
 }
 
@@ -1109,7 +1110,7 @@ BOOST_AUTO_TEST_CASE(test_throttled_server) {
     });
 
   /* mark ns as down */
-  t_sstorage->throttle.throttle(time(nullptr), boost::make_tuple(ns, "", 0), SyncRes::s_serverdownthrottletime, 10000);
+  SyncRes::doThrottle(time(nullptr), ns, SyncRes::s_serverdownthrottletime, 10000);
 
   vector<DNSRecord> ret;
   int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
@@ -1130,14 +1131,14 @@ BOOST_AUTO_TEST_CASE(test_throttled_server_count) {
 
   const size_t blocks = 10;
   /* mark ns as down for 'blocks' queries */
-  t_sstorage->throttle.throttle(time(nullptr), boost::make_tuple(ns, "", 0), SyncRes::s_serverdownthrottletime, blocks);
+  SyncRes::doThrottle(time(nullptr), ns, SyncRes::s_serverdownthrottletime, blocks);
 
   for (size_t idx = 0; idx < blocks; idx++) {
-    BOOST_CHECK(t_sstorage->throttle.shouldThrottle(time(nullptr), boost::make_tuple(ns, "", 0)));
+    BOOST_CHECK(SyncRes::isThrottled(time(nullptr), ns));
   }
 
   /* we have been throttled 'blocks' times, we should not be throttled anymore */
-  BOOST_CHECK(!t_sstorage->throttle.shouldThrottle(time(nullptr), boost::make_tuple(ns, "", 0)));
+  BOOST_CHECK(!SyncRes::isThrottled(time(nullptr), ns));
 }
 
 BOOST_AUTO_TEST_CASE(test_throttled_server_time) {
@@ -1151,13 +1152,14 @@ BOOST_AUTO_TEST_CASE(test_throttled_server_time) {
 
   const size_t seconds = 1;
   /* mark ns as down for 'seconds' seconds */
-  t_sstorage->throttle.throttle(time(nullptr), boost::make_tuple(ns, "", 0), seconds, 10000);
-  BOOST_CHECK(t_sstorage->throttle.shouldThrottle(time(nullptr), boost::make_tuple(ns, "", 0)));
+  SyncRes::doThrottle(time(nullptr), ns, seconds, 10000);
+
+  BOOST_CHECK(SyncRes::isThrottled(time(nullptr), ns));
 
   sleep(seconds + 1);
 
   /* we should not be throttled anymore */
-  BOOST_CHECK(!t_sstorage->throttle.shouldThrottle(time(nullptr), boost::make_tuple(ns, "", 0)));
+  BOOST_CHECK(!SyncRes::isThrottled(time(nullptr), ns));
 }
 
 BOOST_AUTO_TEST_CASE(test_dont_query_server) {
@@ -1248,14 +1250,14 @@ BOOST_AUTO_TEST_CASE(test_root_nx_trust) {
   BOOST_CHECK_EQUAL(res, RCode::NXDomain);
   BOOST_CHECK_EQUAL(ret.size(), 1);
   /* one for target1 and one for the entire TLD */
-  BOOST_CHECK_EQUAL(t_sstorage->negcache.size(), 2);
+  BOOST_CHECK_EQUAL(SyncRes::getNegCacheSize(), 2);
 
   ret.clear();
   res = sr->beginResolve(target2, QType(QType::A), QClass::IN, ret);
   BOOST_CHECK_EQUAL(res, RCode::NXDomain);
   BOOST_CHECK_EQUAL(ret.size(), 1);
   /* one for target1 and one for the entire TLD */
-  BOOST_CHECK_EQUAL(t_sstorage->negcache.size(), 2);
+  BOOST_CHECK_EQUAL(SyncRes::getNegCacheSize(), 2);
 
   /* we should have sent only one query */
   BOOST_CHECK_EQUAL(queriesCount, 1);
@@ -1311,7 +1313,7 @@ BOOST_AUTO_TEST_CASE(test_root_nx_trust_specific) {
 
   /* even with root-nx-trust on and a NX answer from the root,
      we should not have cached the entire TLD this time. */
-  BOOST_CHECK_EQUAL(t_sstorage->negcache.size(), 1);
+  BOOST_CHECK_EQUAL(SyncRes::t_sstorage.negcache.size(), 1);
 
   ret.clear();
   res = sr->beginResolve(target2, QType(QType::A), QClass::IN, ret);
@@ -1321,7 +1323,7 @@ BOOST_AUTO_TEST_CASE(test_root_nx_trust_specific) {
   BOOST_CHECK_EQUAL(ret[0].d_name, target2);
   BOOST_CHECK(getRR<ARecordContent>(ret[0])->getCA() == ComboAddress("192.0.2.2"));
 
-  BOOST_CHECK_EQUAL(t_sstorage->negcache.size(), 1);
+  BOOST_CHECK_EQUAL(SyncRes::t_sstorage.negcache.size(), 1);
 
   BOOST_CHECK_EQUAL(queriesCount, 3);
 }
@@ -1373,14 +1375,14 @@ BOOST_AUTO_TEST_CASE(test_root_nx_dont_trust) {
   BOOST_CHECK_EQUAL(res, RCode::NXDomain);
   BOOST_CHECK_EQUAL(ret.size(), 1);
   /* one for target1 */
-  BOOST_CHECK_EQUAL(t_sstorage->negcache.size(), 1);
+  BOOST_CHECK_EQUAL(SyncRes::getNegCacheSize(), 1);
 
   ret.clear();
   res = sr->beginResolve(target2, QType(QType::A), QClass::IN, ret);
   BOOST_CHECK_EQUAL(res, 0);
   BOOST_CHECK_EQUAL(ret.size(), 1);
   /* one for target1 */
-  BOOST_CHECK_EQUAL(t_sstorage->negcache.size(), 1);
+  BOOST_CHECK_EQUAL(SyncRes::getNegCacheSize(), 1);
 
   /* we should have sent three queries */
   BOOST_CHECK_EQUAL(queriesCount, 3);
@@ -1439,7 +1441,7 @@ BOOST_AUTO_TEST_CASE(test_skip_negcache_for_variable_response) {
   BOOST_CHECK_EQUAL(res, RCode::NXDomain);
   BOOST_CHECK_EQUAL(ret.size(), 2);
   /* no negative cache entry because the response was variable */
-  BOOST_CHECK_EQUAL(t_sstorage->negcache.size(), 0);
+  BOOST_CHECK_EQUAL(SyncRes::getNegCacheSize(), 0);
 }
 
 BOOST_AUTO_TEST_CASE(test_ns_speed) {
@@ -1497,12 +1499,12 @@ BOOST_AUTO_TEST_CASE(test_ns_speed) {
 
   /* make pdns-public-ns2.powerdns.com. the fastest NS, with its IPv6 address faster than the IPV4 one,
      then pdns-public-ns1.powerdns.com. on IPv4 */
-  t_sstorage->nsSpeeds[DNSName("pdns-public-ns1.powerdns.com.")].submit(ComboAddress("192.0.2.1:53"), 100, &now);
-  t_sstorage->nsSpeeds[DNSName("pdns-public-ns1.powerdns.com.")].submit(ComboAddress("[2001:DB8::1]:53"), 10000, &now);
-  t_sstorage->nsSpeeds[DNSName("pdns-public-ns2.powerdns.com.")].submit(ComboAddress("192.0.2.2:53"), 10, &now);
-  t_sstorage->nsSpeeds[DNSName("pdns-public-ns2.powerdns.com.")].submit(ComboAddress("[2001:DB8::2]:53"), 1, &now);
-  t_sstorage->nsSpeeds[DNSName("pdns-public-ns3.powerdns.com.")].submit(ComboAddress("192.0.2.3:53"), 10000, &now);
-  t_sstorage->nsSpeeds[DNSName("pdns-public-ns3.powerdns.com.")].submit(ComboAddress("[2001:DB8::3]:53"), 10000, &now);
+  SyncRes::submitNSSpeed(DNSName("pdns-public-ns1.powerdns.com."), ComboAddress("192.0.2.1:53"), 100, &now);
+  SyncRes::submitNSSpeed(DNSName("pdns-public-ns1.powerdns.com."), ComboAddress("[2001:DB8::1]:53"), 10000, &now);
+  SyncRes::submitNSSpeed(DNSName("pdns-public-ns2.powerdns.com."), ComboAddress("192.0.2.2:53"), 10, &now);
+  SyncRes::submitNSSpeed(DNSName("pdns-public-ns2.powerdns.com."), ComboAddress("[2001:DB8::2]:53"), 1, &now);
+  SyncRes::submitNSSpeed(DNSName("pdns-public-ns3.powerdns.com."), ComboAddress("192.0.2.3:53"), 10000, &now);
+  SyncRes::submitNSSpeed(DNSName("pdns-public-ns3.powerdns.com."), ComboAddress("[2001:DB8::3]:53"), 10000, &now);
 
   vector<DNSRecord> ret;
   int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
@@ -2288,7 +2290,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_nord) {
   SyncRes::AuthDomain ad;
   ad.d_rdForward = false;
   ad.d_servers.push_back(forwardedNS);
-  (*t_sstorage->domainmap)[target] = ad;
+  (*SyncRes::t_sstorage.domainmap)[target] = ad;
 
   sr->setAsyncCallback([forwardedNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, std::shared_ptr<RemoteLogger> outgoingLogger, LWResult* res) {
 
@@ -2324,7 +2326,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_rd) {
   SyncRes::AuthDomain ad;
   ad.d_rdForward = false;
   ad.d_servers.push_back(forwardedNS);
-  (*t_sstorage->domainmap)[target] = ad;
+  (*SyncRes::t_sstorage.domainmap)[target] = ad;
 
   sr->setAsyncCallback([forwardedNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, std::shared_ptr<RemoteLogger> outgoingLogger, LWResult* res) {
 
@@ -2357,7 +2359,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_nord) {
   SyncRes::AuthDomain ad;
   ad.d_rdForward = true;
   ad.d_servers.push_back(forwardedNS);
-  (*t_sstorage->domainmap)[target] = ad;
+  (*SyncRes::t_sstorage.domainmap)[target] = ad;
 
   sr->setAsyncCallback([forwardedNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, std::shared_ptr<RemoteLogger> outgoingLogger, LWResult* res) {
 
@@ -2393,7 +2395,7 @@ BOOST_AUTO_TEST_CASE(test_forward_zone_recurse_rd) {
   SyncRes::AuthDomain ad;
   ad.d_rdForward = true;
   ad.d_servers.push_back(forwardedNS);
-  (*t_sstorage->domainmap)[target] = ad;
+  (*SyncRes::t_sstorage.domainmap)[target] = ad;
 
   sr->setAsyncCallback([forwardedNS](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, std::shared_ptr<RemoteLogger> outgoingLogger, LWResult* res) {
 
@@ -2442,7 +2444,7 @@ BOOST_AUTO_TEST_CASE(test_auth_zone_delegation_oob) {
   dr.d_content = std::make_shared<ARecordContent>(nsAddr);
   ad.d_records.insert(dr);
 
-  (*t_sstorage->domainmap)[authZone] = ad;
+  (*SyncRes::t_sstorage.domainmap)[authZone] = ad;
 
   sr->setAsyncCallback([&queriesCount,nsAddr,target,targetAddr](const ComboAddress& ip, const DNSName& domain, int type, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, std::shared_ptr<RemoteLogger> outgoingLogger, LWResult* res) {
         queriesCount++;
index f7fa10c40c5ffc6b561166497d172dcb9bd76cbd..cd7ac7996d7aa2032fb282e1c980b41199e4d7c4 100644 (file)
@@ -229,26 +229,28 @@ void convertServersForAD(const std::string& input, SyncRes::AuthDomain& ad, cons
 
 void* pleaseWipeNegCache()
 {
-  t_sstorage->negcache.clear();   
+  SyncRes::clearNegCache();
   return 0;
 }
 
 void* pleaseUseNewSDomainsMap(std::shared_ptr<SyncRes::domainmap_t> newmap)
 {
-  t_sstorage->domainmap = newmap;
+  SyncRes::setDomainMap(newmap);
   return 0;
 }
 
 string reloadAuthAndForwards()
 {
-  std::shared_ptr<SyncRes::domainmap_t> original=t_sstorage->domainmap;
+  std::shared_ptr<SyncRes::domainmap_t> original=SyncRes::getDomainMap();
   
   try {
     L<<Logger::Warning<<"Reloading zones, purging data from cache"<<endl;
-  
-    for(const auto& i : *t_sstorage->domainmap) {
-      for(const auto& j : i.second.d_records)
-        broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, j.d_name, false));
+
+    if (original) {
+      for(const auto& i : *original) {
+        for(const auto& j : i.second.d_records)
+          broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, j.d_name, false));
+      }
     }
 
     string configname=::arg()["config-dir"]+"/recursor.conf";
index 03b8fa701f8988465e7ca9845f91dc75b22324b8..3e17467419611d764dd3ef6328cd31772956d642 100644 (file)
@@ -49,7 +49,7 @@
 #include "ednssubnet.hh"
 #include "cachecleaner.hh"
 #include "rec-lua-conf.hh"
-thread_local std::unique_ptr<SyncRes::StaticStorage> t_sstorage;
+thread_local SyncRes::ThreadLocalStorage SyncRes::t_sstorage;
 
 unsigned int SyncRes::s_maxnegttl;
 unsigned int SyncRes::s_maxcachettl;
@@ -121,9 +121,6 @@ SyncRes::SyncRes(const struct timeval& now) :  d_outqueries(0), d_tcpoutqueries(
                                               d_cacheonly(false), d_nocache(false), d_doDNSSEC(false), d_doEDNS0(false), d_lm(s_lm)
                                                  
 { 
-  if(!t_sstorage) {
-    t_sstorage = std::unique_ptr<StaticStorage>(new StaticStorage());
-  }
 }
 
 /** everything begins here - this is the entry point just after receiving a packet */
@@ -230,7 +227,7 @@ bool SyncRes::doOOBResolve(const DNSName &qname, const QType &qtype, vector<DNSR
   DNSName authdomain(qname);
 
   domainmap_t::const_iterator iter=getBestAuthZone(&authdomain);
-  if(iter==t_sstorage->domainmap->end()) {
+  if(iter==t_sstorage.domainmap->end()) {
     LOG(prefix<<qname<<": auth storage has no zone for this query!"<<endl);
     return false;
   }
@@ -332,7 +329,7 @@ void SyncRes::doEDNSDumpAndClose(int fd)
     return;
   }
   fprintf(fp,"IP Address\tMode\tMode last updated at\n");
-  for(const auto& eds : t_sstorage->ednsstatus) {
+  for(const auto& eds : t_sstorage.ednsstatus) {
     fprintf(fp, "%s\t%d\t%s", eds.first.toString().c_str(), (int)eds.second.mode, ctime(&eds.second.modeSetAt));
   }
 
@@ -347,7 +344,7 @@ uint64_t SyncRes::doDumpNSSpeeds(int fd)
   fprintf(fp, "; nsspeed dump from thread follows\n;\n");
   uint64_t count=0;
 
-  for(const auto& i : t_sstorage->nsSpeeds)
+  for(const auto& i : t_sstorage.nsSpeeds)
   {
     count++;
     fprintf(fp, "%s -> ", i.first.toString().c_str());
@@ -406,7 +403,7 @@ int SyncRes::asyncresolveWrapper(const ComboAddress& ip, bool ednsMANDATORY, con
   */
 
   SyncRes::EDNSStatus* ednsstatus;
-  ednsstatus = &t_sstorage->ednsstatus[ip]; // does this include port? YES
+  ednsstatus = &t_sstorage.ednsstatus[ip]; // does this include port? YES
 
   if(ednsstatus->modeSetAt && ednsstatus->modeSetAt + 3600 < d_now.tv_sec) {
     *ednsstatus=SyncRes::EDNSStatus();
@@ -503,7 +500,7 @@ int SyncRes::doResolve(const DNSName &qname, const QType &qtype, vector<DNSRecor
       LOG(prefix<<qname<<": Recursion not requested for '"<<qname<<"|"<<qtype.getName()<<"', peeking at auth/forward zones"<<endl);
       DNSName authname(qname);
       domainmap_t::const_iterator iter=getBestAuthZone(&authname);
-      if(iter != t_sstorage->domainmap->end()) {
+      if(iter != t_sstorage.domainmap->end()) {
         const vector<ComboAddress>& servers = iter->second.d_servers;
         if(servers.empty()) {
           ret.clear();
@@ -635,9 +632,9 @@ vector<ComboAddress> SyncRes::getAddrs(const DNSName &qname, unsigned int depth,
     random_shuffle(ret.begin(), ret.end(), dns_random);
 
     // move 'best' address for this nameserver name up front
-    nsspeeds_t::iterator best = t_sstorage->nsSpeeds.find(qname);
+    nsspeeds_t::iterator best = t_sstorage.nsSpeeds.find(qname);
 
-    if(best != t_sstorage->nsSpeeds.end())
+    if(best != t_sstorage.nsSpeeds.end())
       for(ret_t::iterator i=ret.begin(); i != ret.end(); ++i) {
         if(*i==best->second.d_best) {  // got the fastest one
           if(i!=ret.begin()) {
@@ -732,8 +729,8 @@ SyncRes::domainmap_t::const_iterator SyncRes::getBestAuthZone(DNSName* qname) co
 {
   SyncRes::domainmap_t::const_iterator ret;
   do {
-    ret=t_sstorage->domainmap->find(*qname);
-    if(ret!=t_sstorage->domainmap->end())
+    ret=t_sstorage.domainmap->find(*qname);
+    if(ret!=t_sstorage.domainmap->end())
       break;
   }while(qname->chopOff());
   return ret;
@@ -746,7 +743,7 @@ DNSName SyncRes::getBestNSNamesFromCache(const DNSName &qname, const QType& qtyp
   DNSName authdomain(qname);
 
   domainmap_t::const_iterator iter=getBestAuthZone(&authdomain);
-  if(iter!=t_sstorage->domainmap->end()) {
+  if(iter!=t_sstorage.domainmap->end()) {
     if( iter->second.d_servers.empty() )
       // this gets picked up in doResolveAt, the empty DNSName, combined with the
       // empty vector means 'we are auth for this zone'
@@ -858,7 +855,7 @@ bool SyncRes::doCacheCheck(const DNSName &qname, const QType &qtype, vector<DNSR
   bool wasForwardedOrAuth = false;
   bool wasAuth = false;
   domainmap_t::const_iterator iter=getBestAuthZone(&authname);
-  if(iter != t_sstorage->domainmap->end()) {
+  if(iter != t_sstorage.domainmap->end()) {
     wasForwardedOrAuth = true;
     const vector<ComboAddress>& servers = iter->second.d_servers;
     if(servers.empty()) {
@@ -868,7 +865,7 @@ bool SyncRes::doCacheCheck(const DNSName &qname, const QType &qtype, vector<DNSR
   NegCache::NegCacheEntry ne;
 
   if(s_rootNXTrust &&
-     t_sstorage->negcache.getRootNXTrust(qname, d_now, ne) &&
+     t_sstorage.negcache.getRootNXTrust(qname, d_now, ne) &&
       ne.d_auth.isRoot() &&
       !(wasForwardedOrAuth && !authname.isRoot())) { // when forwarding, the root may only neg-cache if it was forwarded to.
     sttl = ne.d_ttd - d_now.tv_sec;
@@ -876,7 +873,7 @@ bool SyncRes::doCacheCheck(const DNSName &qname, const QType &qtype, vector<DNSR
     res = RCode::NXDomain;
     giveNegative = true;
   }
-  else if (t_sstorage->negcache.get(qname, qtype, d_now, ne) &&
+  else if (t_sstorage.negcache.get(qname, qtype, d_now, ne) &&
            !(wasForwardedOrAuth && ne.d_auth != authname)) { // Only the authname nameserver can neg cache entries
     res = 0;
     sttl = ne.d_ttd - d_now.tv_sec;
@@ -975,7 +972,7 @@ inline vector<DNSName> SyncRes::shuffleInSpeedOrder(NsSet &tnameservers, const s
 
   for(const auto& val: rnameservers) {
     double speed;
-    speed=t_sstorage->nsSpeeds[val].get(&d_now);
+    speed=t_sstorage.nsSpeeds[val].get(&d_now);
     speeds[val]=speed;
   }
   random_shuffle(rnameservers.begin(),rnameservers.end(), dns_random);
@@ -1115,12 +1112,12 @@ vector<ComboAddress> SyncRes::retrieveAddressesForNS(const std::string& prefix,
 
 bool SyncRes::throttledOrBlocked(const std::string& prefix, const ComboAddress& remoteIP, const DNSName& qname, const QType& qtype, bool pierceDontQuery)
 {
-  if(t_sstorage->throttle.shouldThrottle(d_now.tv_sec, boost::make_tuple(remoteIP, "", 0))) {
+  if(t_sstorage.throttle.shouldThrottle(d_now.tv_sec, boost::make_tuple(remoteIP, "", 0))) {
     LOG(prefix<<qname<<": server throttled "<<endl);
     s_throttledqueries++; d_throttledqueries++;
     return true;
   }
-  else if(t_sstorage->throttle.shouldThrottle(d_now.tv_sec, boost::make_tuple(remoteIP, qname, qtype.getCode()))) {
+  else if(t_sstorage.throttle.shouldThrottle(d_now.tv_sec, boost::make_tuple(remoteIP, qname, qtype.getCode()))) {
     LOG(prefix<<qname<<": query throttled "<<endl);
     s_throttledqueries++; d_throttledqueries++;
     return true;
@@ -1185,11 +1182,11 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(const std::string& prefix, LWResu
       }
       else {
         bool haveLogged = false;
-        if (!t_sstorage->domainmap->empty()) {
+        if (!t_sstorage.domainmap->empty()) {
           // Check if we are authoritative for a zone in this answer
           DNSName tmp_qname(rec.d_name);
           auto auth_domain_iter=getBestAuthZone(&tmp_qname);
-          if(auth_domain_iter!=t_sstorage->domainmap->end() &&
+          if(auth_domain_iter!=t_sstorage.domainmap->end() &&
              auth.countLabels() <= auth_domain_iter->first.countLabels()) {
             if (auth_domain_iter->first != auth) {
               LOG("NO! - we are authoritative for the zone "<<auth_domain_iter->first<<endl);
@@ -1269,10 +1266,10 @@ bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, co
         ne.d_qtype = QType(0); // this encodes 'whole record'
         ne.d_auth = rec.d_name;
         harvestNXRecords(lwr.d_records, ne);
-        t_sstorage->negcache.add(ne);
+        t_sstorage.negcache.add(ne);
         if(s_rootNXTrust && ne.d_auth.isRoot() && auth.isRoot()) {
           ne.d_name = ne.d_name.getLastLabel();
-          t_sstorage->negcache.add(ne);
+          t_sstorage.negcache.add(ne);
         }
       }
 
@@ -1335,7 +1332,7 @@ bool SyncRes::processRecords(const std::string& prefix, const DNSName& qname, co
           ne.d_qtype = qtype;
           harvestNXRecords(lwr.d_records, ne);
           if(qtype.getCode()) {  // prevents us from blacking out a whole domain
-            t_sstorage->negcache.add(ne);
+            t_sstorage.negcache.add(ne);
           }
         }
         negindic=true;
@@ -1488,16 +1485,16 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con
               }
 
               if(resolveret!=-2) { // don't account for resource limits, they are our own fault
-               t_sstorage->nsSpeeds[*tns].submit(*remoteIP, 1000000, &d_now); // 1 sec
+               t_sstorage.nsSpeeds[*tns].submit(*remoteIP, 1000000, &d_now); // 1 sec
 
                // code below makes sure we don't filter COM or the root
-                if (s_serverdownmaxfails > 0 && (auth != g_rootdnsname) && t_sstorage->fails.incr(*remoteIP) >= s_serverdownmaxfails) {
+                if (s_serverdownmaxfails > 0 && (auth != g_rootdnsname) && t_sstorage.fails.incr(*remoteIP) >= s_serverdownmaxfails) {
                   LOG(prefix<<qname<<": Max fails reached resolving on "<< remoteIP->toString() <<". Going full throttle for "<< s_serverdownthrottletime <<" seconds" <<endl);
-                  t_sstorage->throttle.throttle(d_now.tv_sec, boost::make_tuple(*remoteIP, "", 0), s_serverdownthrottletime, 10000); // mark server as down
+                  t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(*remoteIP, "", 0), s_serverdownthrottletime, 10000); // mark server as down
                 } else if(resolveret==-1)
-                  t_sstorage->throttle.throttle(d_now.tv_sec, boost::make_tuple(*remoteIP, qname, qtype.getCode()), 60, 100); // unreachable, 1 minute or 100 queries
+                  t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(*remoteIP, qname, qtype.getCode()), 60, 100); // unreachable, 1 minute or 100 queries
                 else
-                  t_sstorage->throttle.throttle(d_now.tv_sec, boost::make_tuple(*remoteIP, qname, qtype.getCode()), 10, 5);  // timeout
+                  t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(*remoteIP, qname, qtype.getCode()), 10, 5);  // timeout
               }
               continue;
             }
@@ -1506,17 +1503,17 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con
 
             if(lwr.d_rcode==RCode::ServFail || lwr.d_rcode==RCode::Refused) {
               LOG(prefix<<qname<<": "<<*tns<<" ("<<remoteIP->toString()<<") returned a "<< (lwr.d_rcode==RCode::ServFail ? "ServFail" : "Refused") << ", trying sibling IP or NS"<<endl);
-              t_sstorage->throttle.throttle(d_now.tv_sec,boost::make_tuple(*remoteIP, qname, qtype.getCode()),60,3); // servfail or refused
+              t_sstorage.throttle.throttle(d_now.tv_sec,boost::make_tuple(*remoteIP, qname, qtype.getCode()),60,3); // servfail or refused
               continue;
             }
 
             if(s_serverdownmaxfails > 0)
-              t_sstorage->fails.clear(*remoteIP);
+              t_sstorage.fails.clear(*remoteIP);
 
             break;  // this IP address worked!
           wasLame:; // well, it didn't
             LOG(prefix<<qname<<": status=NS "<<*tns<<" ("<< remoteIP->toString() <<") is lame for '"<<auth<<"', trying sibling IP or NS"<<endl);
-            t_sstorage->throttle.throttle(d_now.tv_sec, boost::make_tuple(*remoteIP, qname, qtype.getCode()), 60, 100); // lame
+            t_sstorage.throttle.throttle(d_now.tv_sec, boost::make_tuple(*remoteIP, qname, qtype.getCode()), 60, 100); // lame
           }
         }
 
@@ -1540,7 +1537,7 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con
         */
         //        cout<<"msec: "<<lwr.d_usec/1000.0<<", "<<g_avgLatency/1000.0<<'\n';
 
-        t_sstorage->nsSpeeds[*tns].submit(*remoteIP, lwr.d_usec, &d_now);
+        t_sstorage.nsSpeeds[*tns].submit(*remoteIP, lwr.d_usec, &d_now);
       }
 
       if(s_minimumTTL) {
@@ -1599,8 +1596,8 @@ int SyncRes::doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, con
       else if(realreferral) {
         LOG(prefix<<qname<<": status=did not resolve, got "<<(unsigned int)nsset.size()<<" NS, ");
        if(sawDS) {
-         t_sstorage->dnssecmap[newauth]=true;
-         /*      for(const auto& e : t_sstorage->dnssecmap)
+         //s_dnssecmap[newauth]=true;
+         /*      for(const auto& e : s_dnssecmap)
            cout<<e.first<<' ';
            cout<<endl;*/
        }
index 4965c53bdfa80b5c400fd2b248a7227bfdf3b59d..83f6dddf3aaa6573864257618aac0985acf11cf6 100644 (file)
@@ -156,20 +156,9 @@ public:
   {
   }
 
-  struct timeval getOrMakeTime(struct timeval* tv)
+  void submit(int val, const struct timeval* tv)
   {
-    if(tv)
-      return *tv;
-    else {
-      struct timeval ret;
-      Utility::gettimeofday(&ret, 0);
-      return ret;
-    }
-  }
-
-  void submit(int val, struct timeval* tv)
-  {
-    struct timeval now=getOrMakeTime(tv);
+    struct timeval now=*tv;
 
     if(d_needinit) {
       d_last=now;
@@ -186,9 +175,9 @@ public:
     }
   }
 
-  double get(struct timeval* tv)
+  double get(const struct timeval* tv)
   {
-    struct timeval now=getOrMakeTime(tv);
+    struct timeval now=*tv;
     float diff=makeFloat(d_lastget-now);
     d_lastget=now;
     float factor=exp(diff/60.0f); // is 1.0 or less
@@ -279,6 +268,98 @@ public:
   enum LogMode { LogNone, Log, Store};
   typedef std::function<int(const ComboAddress& ip, const DNSName& qdomain, int qtype, bool doTCP, bool sendRDQuery, int EDNS0Level, struct timeval* now, boost::optional<Netmask>& srcmask, boost::optional<const ResolveContext&> context, std::shared_ptr<RemoteLogger> outgoingLogger, LWResult *lwr)> asyncresolve_t;
 
+  struct EDNSStatus
+  {
+    EDNSStatus() : mode(UNKNOWN), modeSetAt(0) {}
+    enum EDNSMode { UNKNOWN=0, EDNSOK=1, EDNSIGNORANT=2, NOEDNS=3 } mode;
+    time_t modeSetAt;
+  };
+
+    //! This represents a number of decaying Ewmas, used to store performance per nameserver-name.
+  /** Modelled to work mostly like the underlying DecayingEwma. After you've called get,
+      d_best is filled out with the best address for this collection */
+  struct DecayingEwmaCollection
+  {
+    void submit(const ComboAddress& remote, int usecs, const struct timeval* now)
+    {
+      collection_t::iterator pos;
+      for(pos=d_collection.begin(); pos != d_collection.end(); ++pos)
+        if(pos->first==remote)
+          break;
+      if(pos!=d_collection.end()) {
+        pos->second.submit(usecs, now);
+      }
+      else {
+        DecayingEwma de;
+        de.submit(usecs, now);
+        d_collection.push_back(make_pair(remote, de));
+      }
+    }
+
+    double get(const struct timeval* now)
+    {
+      if(d_collection.empty())
+        return 0;
+      double ret=std::numeric_limits<double>::max();
+      double tmp;
+      for(collection_t::iterator pos=d_collection.begin(); pos != d_collection.end(); ++pos) {
+        if((tmp=pos->second.get(now)) < ret) {
+          ret=tmp;
+          d_best=pos->first;
+        }
+      }
+
+      return ret;
+    }
+
+    bool stale(time_t limit) const
+    {
+      for(collection_t::const_iterator pos=d_collection.begin(); pos != d_collection.end(); ++pos)
+        if(!pos->second.stale(limit))
+          return false;
+      return true;
+    }
+
+    typedef vector<pair<ComboAddress, DecayingEwma> > collection_t;
+    collection_t d_collection;
+    ComboAddress d_best;
+  };
+
+  typedef map<DNSName, DecayingEwmaCollection> nsspeeds_t;
+  typedef map<ComboAddress, EDNSStatus> ednsstatus_t;
+
+  struct AuthDomain
+  {
+    vector<ComboAddress> d_servers;
+    bool d_rdForward;
+    typedef multi_index_container <
+      DNSRecord,
+      indexed_by <
+        ordered_non_unique<
+          composite_key< DNSRecord,
+                         member<DNSRecord, DNSName, &DNSRecord::d_name>,
+                         member<DNSRecord, uint16_t, &DNSRecord::d_type>
+                       >,
+          composite_key_compare<std::less<DNSName>, std::less<uint16_t> >
+        >
+      >
+    > records_t;
+    records_t d_records;
+  };
+
+  typedef map<DNSName, AuthDomain> domainmap_t;
+  typedef Throttle<boost::tuple<ComboAddress,DNSName,uint16_t> > throttle_t;
+  typedef Counters<ComboAddress> fails_t;
+
+  struct ThreadLocalStorage {
+    NegCache negcache;
+    nsspeeds_t nsSpeeds;
+    throttle_t throttle;
+    ednsstatus_t ednsstatus;
+    fails_t fails;
+    std::shared_ptr<domainmap_t> domainmap;
+  };
+
   static void setDefaultLogMode(LogMode lm)
   {
     s_lm = lm;
@@ -329,6 +410,107 @@ public:
   {
     s_ednsdomains = SuffixMatchNode();
   }
+  static void pruneNSSpeeds(time_t limit)
+  {
+    for(auto i = t_sstorage.nsSpeeds.begin(), end = t_sstorage.nsSpeeds.end(); i != end; ) {
+      if(i->second.stale(limit)) {
+        i = t_sstorage.nsSpeeds.erase(i);
+      }
+      else {
+        ++i;
+      }
+    }
+  }
+  static uint64_t getNSSpeedsSize()
+  {
+    return t_sstorage.nsSpeeds.size();
+  }
+  static void submitNSSpeed(const DNSName& server, const ComboAddress& ca, uint32_t usec, const struct timeval* now)
+  {
+    t_sstorage.nsSpeeds[server].submit(ca, usec, now);
+  }
+  static void clearNSSpeeds()
+  {
+    t_sstorage.nsSpeeds.clear();
+  }
+  static EDNSStatus::EDNSMode getEDNSStatus(const ComboAddress& server)
+  {
+    const auto& it = t_sstorage.ednsstatus.find(server);
+    if (it == t_sstorage.ednsstatus.end())
+      return EDNSStatus::UNKNOWN;
+
+    return it->second.mode;
+  }
+  static uint64_t getEDNSStatusesSize()
+  {
+    return t_sstorage.ednsstatus.size();
+  }
+  static void clearEDNSStatuses()
+  {
+    t_sstorage.ednsstatus.clear();
+  }
+  static uint64_t getThrottledServersSize()
+  {
+    return t_sstorage.throttle.size();
+  }
+  static void clearThrottle()
+  {
+    t_sstorage.throttle.clear();
+  }
+  static bool isThrottled(time_t now, const ComboAddress& server, const DNSName& target, uint16_t qtype)
+  {
+    return t_sstorage.throttle.shouldThrottle(now, boost::make_tuple(server, target, qtype));
+  }
+  static bool isThrottled(time_t now, const ComboAddress& server)
+  {
+    return t_sstorage.throttle.shouldThrottle(now, boost::make_tuple(server, "", 0));
+  }
+  static void doThrottle(time_t now, const ComboAddress& server, time_t duration, unsigned int tries)
+  {
+    t_sstorage.throttle.throttle(now, boost::make_tuple(server, "", 0), duration, tries);
+  }
+  static uint64_t getFailedServersSize()
+  {
+    return t_sstorage.fails.size();
+  }
+  static void clearFailedServers()
+  {
+    t_sstorage.fails.clear();
+  }
+  static unsigned long getServerFailsCount(const ComboAddress& server)
+  {
+    return t_sstorage.fails.value(server);
+  }
+
+  static void clearNegCache()
+  {
+    t_sstorage.negcache.clear();
+  }
+
+  static uint64_t getNegCacheSize()
+  {
+    return t_sstorage.negcache.size();
+  }
+
+  static void pruneNegCache(unsigned int maxEntries)
+  {
+    t_sstorage.negcache.prune(maxEntries);
+  }
+
+  static uint64_t wipeNegCache(const DNSName& name, bool subtree = false)
+  {
+    return t_sstorage.negcache.wipe(name, subtree);
+  }
+
+  static void setDomainMap(std::shared_ptr<domainmap_t> newMap)
+  {
+    t_sstorage.domainmap = newMap;
+  }
+
+  static const std::shared_ptr<domainmap_t> getDomainMap()
+  {
+    return t_sstorage.domainmap;
+  }
 
   explicit SyncRes(const struct timeval& now);
 
@@ -430,6 +612,8 @@ public:
     d_asyncResolve = func;
   }
 
+  static thread_local ThreadLocalStorage t_sstorage;
+
   static std::atomic<uint64_t> s_queries;
   static std::atomic<uint64_t> s_outgoingtimeouts;
   static std::atomic<uint64_t> s_outgoing4timeouts;
@@ -441,103 +625,6 @@ public:
   static std::atomic<uint64_t> s_nodelegated;
   static std::atomic<uint64_t> s_unreachables;
 
-  std::unordered_map<std::string,bool> d_discardedPolicies;
-  DNSFilterEngine::Policy d_appliedPolicy;
-  unsigned int d_outqueries;
-  unsigned int d_tcpoutqueries;
-  unsigned int d_throttledqueries;
-  unsigned int d_timeouts;
-  unsigned int d_unreachables;
-  unsigned int d_totUsec;
-  ComboAddress d_requestor;
-
-  //! This represents a number of decaying Ewmas, used to store performance per nameserver-name.
-  /** Modelled to work mostly like the underlying DecayingEwma. After you've called get,
-      d_best is filled out with the best address for this collection */
-  struct DecayingEwmaCollection
-  {
-    void submit(const ComboAddress& remote, int usecs, struct timeval* now)
-    {
-      collection_t::iterator pos;
-      for(pos=d_collection.begin(); pos != d_collection.end(); ++pos)
-        if(pos->first==remote)
-          break;
-      if(pos!=d_collection.end()) {
-        pos->second.submit(usecs, now);
-      }
-      else {
-        DecayingEwma de;
-        de.submit(usecs, now);
-        d_collection.push_back(make_pair(remote, de));
-      }
-    }
-
-    double get(struct timeval* now)
-    {
-      if(d_collection.empty())
-        return 0;
-      double ret=std::numeric_limits<double>::max();
-      double tmp;
-      for(collection_t::iterator pos=d_collection.begin(); pos != d_collection.end(); ++pos) {
-        if((tmp=pos->second.get(now)) < ret) {
-          ret=tmp;
-          d_best=pos->first;
-        }
-      }
-
-      return ret;
-    }
-
-    bool stale(time_t limit) const
-    {
-      for(collection_t::const_iterator pos=d_collection.begin(); pos != d_collection.end(); ++pos)
-        if(!pos->second.stale(limit))
-          return false;
-      return true;
-    }
-
-    typedef vector<pair<ComboAddress, DecayingEwma> > collection_t;
-    collection_t d_collection;
-    ComboAddress d_best;
-  };
-
-  typedef map<DNSName, DecayingEwmaCollection> nsspeeds_t;  
-
-  struct EDNSStatus
-  {
-    EDNSStatus() : mode(UNKNOWN), modeSetAt(0) {}
-    enum EDNSMode { UNKNOWN=0, EDNSOK=1, EDNSIGNORANT=2, NOEDNS=3 } mode;
-    time_t modeSetAt;
-  };
-
-  typedef map<ComboAddress, EDNSStatus> ednsstatus_t;
-
-  struct AuthDomain
-  {
-    vector<ComboAddress> d_servers;
-    bool d_rdForward;
-    typedef multi_index_container <
-      DNSRecord,
-      indexed_by <
-        ordered_non_unique<
-          composite_key< DNSRecord,
-                        member<DNSRecord, DNSName, &DNSRecord::d_name>,
-                        member<DNSRecord, uint16_t, &DNSRecord::d_type>
-                       >,
-          composite_key_compare<std::less<DNSName>, std::less<uint16_t> >
-        >
-      >
-    > records_t;
-    records_t d_records;
-  };
-
-
-  typedef map<DNSName, AuthDomain> domainmap_t;
-
-  typedef Throttle<boost::tuple<ComboAddress,DNSName,uint16_t> > throttle_t;
-
-  typedef Counters<ComboAddress> fails_t;
-
   static string s_serverID;
   static unsigned int s_minimumTTL;
   static unsigned int s_maxqperq;
@@ -557,17 +644,18 @@ public:
   static bool s_rootNXTrust;
   static bool s_nopacketcache;
 
-  struct StaticStorage {
-    nsspeeds_t nsSpeeds;
-    ednsstatus_t ednsstatus;
-    throttle_t throttle;
-    fails_t fails;
-    std::shared_ptr<domainmap_t> domainmap;
-    map<DNSName, bool> dnssecmap;
-    NegCache negcache;
-  };
+  std::unordered_map<std::string,bool> d_discardedPolicies;
+  DNSFilterEngine::Policy d_appliedPolicy;
+  unsigned int d_outqueries;
+  unsigned int d_tcpoutqueries;
+  unsigned int d_throttledqueries;
+  unsigned int d_timeouts;
+  unsigned int d_unreachables;
+  unsigned int d_totUsec;
+  ComboAddress d_requestor;
 
 private:
+
   static std::unordered_set<DNSName> s_delegationOnly;
   static NetmaskGroup s_ednssubnets;
   static SuffixMatchNode s_ednsdomains;
@@ -642,7 +730,6 @@ private:
 
   LogMode d_lm;
 };
-extern thread_local std::unique_ptr<SyncRes::StaticStorage> t_sstorage;
 
 class Socket;
 /* external functions, opaque to us */
index 7b284fd89c8b53d10ce718d4543ff7d502c0ee16..92d5494c44e7439714672902ab891a57b7e26e9f 100644 (file)
@@ -116,8 +116,8 @@ static void apiServerConfigAllowFrom(HttpRequest* req, HttpResponse* resp)
 
 static void fillZone(const DNSName& zonename, HttpResponse* resp)
 {
-  auto iter = t_sstorage->domainmap->find(zonename);
-  if (iter == t_sstorage->domainmap->end())
+  auto iter = SyncRes::t_sstorage.domainmap->find(zonename);
+  if (iter == SyncRes::t_sstorage.domainmap->end())
     throw ApiException("Could not find domain '"+zonename.toString()+"'");
 
   const SyncRes::AuthDomain& zone = iter->second;
@@ -251,8 +251,8 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp)
 
     DNSName zonename = apiNameToDNSName(stringFromJson(document, "name"));
 
-    auto iter = t_sstorage->domainmap->find(zonename);
-    if (iter != t_sstorage->domainmap->end())
+    auto iter = SyncRes::t_sstorage.domainmap->find(zonename);
+    if (iter != SyncRes::t_sstorage.domainmap->end())
       throw ApiException("Zone already exists");
 
     doCreateZone(document);
@@ -266,7 +266,7 @@ static void apiServerZones(HttpRequest* req, HttpResponse* resp)
     throw HttpMethodNotAllowedException();
 
   Json::array doc;
-  for(const SyncRes::domainmap_t::value_type& val :  *t_sstorage->domainmap) {
+  for(const SyncRes::domainmap_t::value_type& val :  *SyncRes::t_sstorage.domainmap) {
     const SyncRes::AuthDomain& zone = val.second;
     Json::array servers;
     for(const ComboAddress& server : zone.d_servers) {
@@ -290,8 +290,8 @@ static void apiServerZoneDetail(HttpRequest* req, HttpResponse* resp)
 {
   DNSName zonename = apiZoneIdToName(req->parameters["id"]);
 
-  SyncRes::domainmap_t::const_iterator iter = t_sstorage->domainmap->find(zonename);
-  if (iter == t_sstorage->domainmap->end())
+  SyncRes::domainmap_t::const_iterator iter = SyncRes::t_sstorage.domainmap->find(zonename);
+  if (iter == SyncRes::t_sstorage.domainmap->end())
     throw ApiException("Could not find domain '"+zonename.toString()+"'");
 
   if(req->method == "PUT" && !::arg().mustDo("api-readonly")) {
@@ -328,7 +328,7 @@ static void apiServerSearchData(HttpRequest* req, HttpResponse* resp) {
     throw ApiException("Query q can't be blank");
 
   Json::array doc;
-  for(const SyncRes::domainmap_t::value_type& val : *t_sstorage->domainmap) {
+  for(const SyncRes::domainmap_t::value_type& val : *SyncRes::t_sstorage.domainmap) {
     string zoneId = apiZoneNameToId(val.first);
     string zoneName = val.first.toString();
     if (pdns_ci_find(zoneName, q) != string::npos) {