]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
rec: Cleanup global variables usage in `SyncRes`
authorRemi Gacogne <remi.gacogne@powerdns.com>
Mon, 3 Apr 2017 15:10:08 +0000 (17:10 +0200)
committerRemi Gacogne <remi.gacogne@powerdns.com>
Sun, 14 May 2017 12:30:52 +0000 (14:30 +0200)
pdns/ednssubnet.hh
pdns/pdns_recursor.cc
pdns/rec_channel_rec.cc
pdns/recursor_cache.cc
pdns/recursor_cache.hh
pdns/recursordist/Makefile.am
pdns/recursordist/ecs.cc [deleted file]
pdns/recursordist/test-syncres_cc.cc
pdns/reczones.cc
pdns/syncres.cc
pdns/syncres.hh

index 0220bd0f52e76f255d83dcbfee19053bc1ffa6dd..eb87b488e6fa65daa8af49ae51c7f8845bdb95b3 100644 (file)
 #include "iputils.hh"
 #include "dnsname.hh"
 
-extern NetmaskGroup g_ednssubnets;
-extern SuffixMatchNode g_ednsdomains;
-extern bool g_useIncomingECS;
-
 struct EDNSSubnetOpts
 {
        Netmask source;
index 868a229813d428e10657bb2acdce8f12a5f1830a..07faff5d576b3990b43423ef369451024f8bfd9f 100644 (file)
@@ -99,7 +99,7 @@ typedef map<ComboAddress, uint32_t, ComboAddress::addressOnlyLessThan> tcpClient
 
 static __thread shared_ptr<RecursorLua4>* t_pdl;
 static __thread unsigned int t_id;
-static __thread shared_ptr<Regex>* t_traceRegex;
+static __thread std::shared_ptr<Regex>* t_traceRegex;
 static __thread tcpClientCounts_t* t_tcpClientCounts;
 
 __thread MT_t* MT; // the big MTasker
@@ -135,7 +135,7 @@ static std::unordered_map<unsigned int, deferredAdd_t> deferredAdds;
 static set<int> g_fromtosockets; // listen sockets that use 'sendfromto()' mechanism
 static vector<ComboAddress> g_localQueryAddresses4, g_localQueryAddresses6;
 static AtomicCounter counter;
-static SyncRes::domainmap_t* g_initialDomainMap; // new threads needs this to be setup
+static std::shared_ptr<SyncRes::domainmap_t> g_initialDomainMap; // new threads needs this to be setup
 static NetmaskGroup* g_initialAllowFrom; // new thread needs to be setup with this
 static size_t g_tcpMaxQueriesPerConn;
 static uint64_t g_latencyStatSize;
@@ -156,11 +156,10 @@ static bool g_reusePort{false};
 static bool g_useOneSocketPerThread;
 static bool g_gettagNeedsEDNSOptions{false};
 static time_t g_statisticsInterval;
+static bool g_useIncomingECS;
 
-std::unordered_set<DNSName> g_delegationOnly;
 RecursorControlChannel s_rcc; // only active in thread 0
 RecursorStats g_stats;
-NetmaskGroup* g_dontQuery;
 string s_programname="pdns_recursor";
 string s_pidfname;
 unsigned int g_numThreads;
@@ -2067,7 +2066,7 @@ static void houseKeeping(void *)
        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))
-           t_sstorage->nsSpeeds.erase(i++);
+           i = t_sstorage->nsSpeeds.erase(i);
          else
            ++i;
       }
@@ -2527,7 +2526,7 @@ try
     return new string("unset\n");
   }
   else {
-    (*t_traceRegex) = shared_ptr<Regex>(new Regex(newRegex));
+    (*t_traceRegex) = std::make_shared<Regex>(newRegex);
     return new string("ok\n");
   }
 }
@@ -2669,7 +2668,7 @@ static void setupDelegationOnly()
   vector<string> parts;
   stringtok(parts, ::arg()["delegation-only"], ", \t");
   for(const auto& p : parts) {
-    g_delegationOnly.insert(DNSName(p));
+    SyncRes::addDelegationOnly(DNSName(p));
   }
 }
 
@@ -2748,7 +2747,6 @@ static int serviceMain(int argc, char*argv[])
   sortPublicSuffixList();
 
   if(!::arg()["dont-query"].empty()) {
-    g_dontQuery=new NetmaskGroup;
     vector<string> ips;
     stringtok(ips, ::arg()["dont-query"], ", ");
     ips.push_back("0.0.0.0");
@@ -2756,7 +2754,7 @@ static int serviceMain(int argc, char*argv[])
 
     L<<Logger::Warning<<"Will not send queries to: ";
     for(vector<string>::const_iterator i = ips.begin(); i!= ips.end(); ++i) {
-      g_dontQuery->addMask(*i);
+      SyncRes::addDontQuery(*i);
       if(i!=ips.begin())
         L<<Logger::Warning<<", ";
       L<<Logger::Warning<<*i;
@@ -2848,7 +2846,7 @@ static int serviceMain(int argc, char*argv[])
     makeTCPServerSockets(0);
   }
 
-  parseEDNSSubnetWhitelist(::arg()["edns-subnet-whitelist"]);
+  SyncRes::parseEDNSSubnetWhitelist(::arg()["edns-subnet-whitelist"]);
   g_useIncomingECS = ::arg().mustDo("use-incoming-edns-subnet");
 
   int forks;
@@ -2978,7 +2976,7 @@ try
     _exit(99);
   }
 
-  t_traceRegex = new shared_ptr<Regex>();
+  t_traceRegex = new std::shared_ptr<Regex>();
   unsigned int ringsize=::arg().asNum("stats-ringbuffer-entries") / g_numWorkerThreads;
   if(ringsize) {
     t_remotes = new addrringbuf_t();
index e7d1731ce0c7b4eb905039c734147629fe5a9e2d..c9f37df019807876ea348305fb4b70b3a3e99ba5 100644 (file)
@@ -196,7 +196,7 @@ static uint64_t* pleaseDump(int fd)
 
 static uint64_t* pleaseDumpNSSpeeds(int fd)
 {
-  return new uint64_t(t_RC->doDumpNSSpeeds(fd));
+  return new uint64_t(SyncRes::doDumpNSSpeeds(fd));
 }
 
 template<typename T>
index 9dcfe0c68f7218666542d35d692cffac48c3ba44..80aca7a7744bfd59933f2e7bc248fa765f5f0895 100644 (file)
@@ -249,29 +249,6 @@ bool MemRecursorCache::doAgeCache(time_t now, const DNSName& name, uint16_t qtyp
   return false;
 }
 
-uint64_t MemRecursorCache::doDumpNSSpeeds(int fd)
-{
-  FILE* fp=fdopen(dup(fd), "w");
-  if(!fp)
-    return 0;
-  fprintf(fp, "; nsspeed dump from thread follows\n;\n");
-  uint64_t count=0;
-
-  for(SyncRes::nsspeeds_t::iterator i = t_sstorage->nsSpeeds.begin() ; i!= t_sstorage->nsSpeeds.end(); ++i)
-  {
-    count++;
-    fprintf(fp, "%s -> ", i->first.toString().c_str());
-    for(SyncRes::DecayingEwmaCollection::collection_t::iterator j = i->second.d_collection.begin(); j!= i->second.d_collection.end(); ++j)
-    {
-      // typedef vector<pair<ComboAddress, DecayingEwma> > collection_t;
-      fprintf(fp, "%s/%f ", j->first.toString().c_str(), j->second.peek());
-    }
-    fprintf(fp, "\n");
-  }
-  fclose(fp);
-  return count;
-}
-
 uint64_t MemRecursorCache::doDump(int fd)
 {
   FILE* fp=fdopen(dup(fd), "w");
index 48c1803f29648c7c9b9f7ce58d554fa8f0f50111..6bfe31636fe4d82dd877f06c7a19818d3999e963 100644 (file)
@@ -59,7 +59,6 @@ public:
   void doPrune(void);
   void doSlash(int perc);
   uint64_t doDump(int fd);
-  uint64_t doDumpNSSpeeds(int fd);
 
   int doWipeCache(const DNSName& name, bool sub, uint16_t qtype=0xffff);
   bool doAgeCache(time_t now, const DNSName& name, uint16_t qtype, uint32_t newTTL);
index 03694b1cb5da642a6c1cdddc1e0a91b573d64736..b8e0a4260586a19abef204720cef36c7e7e69644 100644 (file)
@@ -92,7 +92,6 @@ pdns_recursor_SOURCES = \
        dnssecinfra.hh dnssecinfra.cc \
        dnsseckeeper.hh \
        dnswriter.cc dnswriter.hh \
-       ecs.cc \
        ednsoptions.cc ednsoptions.hh \
        ednssubnet.cc ednssubnet.hh \
        filterpo.cc filterpo.hh \
@@ -189,7 +188,6 @@ testrunner_SOURCES = \
        dnssecinfra.cc \
        dnswriter.cc dnswriter.hh \
        ednscookies.cc ednscookies.hh \
-       ecs.cc \
        ednsoptions.cc ednsoptions.hh \
        ednssubnet.cc ednssubnet.hh \
        filterpo.cc filterpo.hh \
diff --git a/pdns/recursordist/ecs.cc b/pdns/recursordist/ecs.cc
deleted file mode 100644 (file)
index 7e9b717..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-#include "syncres.hh"
-#include "arguments.hh"
-
-NetmaskGroup g_ednssubnets;
-SuffixMatchNode g_ednsdomains;
-bool g_useIncomingECS;
-
-void  parseEDNSSubnetWhitelist(const std::string& wlist)
-{
-  vector<string> parts;
-  stringtok(parts, wlist, ",; ");
-  for(const auto& a : parts) {
-    try {
-      Netmask nm(a);
-      g_ednssubnets.addMask(nm);
-    }
-    catch(...) {
-      g_ednsdomains.add(DNSName(a));
-    }
-  }
-}
index 7761a47ad62055258600c4b6838fb322621f0d9e..28e187e6ac0cf5b6422e8e60551842d2523f1e58 100644 (file)
 #include "syncres.hh"
 #include "validate-recursor.hh"
 
-std::unordered_set<DNSName> g_delegationOnly;
 RecursorStats g_stats;
 GlobalStateHolder<LuaConfigItems> g_luaconfs;
-NetmaskGroup* g_dontQuery{nullptr};
 __thread MemRecursorCache* t_RC{nullptr};
-SyncRes::domainmap_t* g_initialDomainMap{nullptr};
 unsigned int g_numThreads = 1;
 
 /* Fake some required functions we didn't want the trouble to
@@ -108,18 +105,10 @@ static void init(bool debug=false)
   seedRandom("/dev/urandom");
   reportAllTypes();
 
-  if (g_dontQuery)
-    delete g_dontQuery;
-  g_dontQuery = new NetmaskGroup();
-
   if (t_RC)
     delete t_RC;
   t_RC = new MemRecursorCache();
 
-  if (g_initialDomainMap)
-    delete g_initialDomainMap;
-  g_initialDomainMap = new SyncRes::domainmap_t(); // new threads needs this to be setup
-
   SyncRes::s_maxqperq = 50;
   SyncRes::s_maxtotusec = 1000*7000;
   SyncRes::s_maxdepth = 40;
@@ -135,11 +124,10 @@ static void init(bool debug=false)
   SyncRes::s_rootNXTrust = true;
   SyncRes::s_minimumTTL = 0;
   SyncRes::s_serverID = "PowerDNS Unit Tests Server ID";
-
-  g_ednssubnets = NetmaskGroup();
-  g_ednsdomains = SuffixMatchNode();
-  g_useIncomingECS = false;
-  g_delegationOnly.clear();
+  SyncRes::clearEDNSSubnets();
+  SyncRes::clearEDNSDomains();
+  SyncRes::clearDelegationOnly();
+  SyncRes::clearDontQuery();
 
   auto luaconfsCopy = g_luaconfs.getCopy();
   luaconfsCopy.dfe.clear();
@@ -163,7 +151,7 @@ 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 = g_initialDomainMap;
+  t_sstorage->domainmap = std::make_shared<SyncRes::domainmap_t>();
   t_sstorage->negcache.clear();
   t_sstorage->nsSpeeds.clear();
   t_sstorage->ednsstatus.clear();
@@ -701,8 +689,7 @@ BOOST_AUTO_TEST_CASE(test_edns_submask_by_domain) {
   primeHints();
 
   const DNSName target("powerdns.com.");
-  g_useIncomingECS = true;
-  g_ednsdomains.add(target);
+  SyncRes::addEDNSDomain(target);
 
   EDNSSubnetOpts incomingECS;
   incomingECS.source = Netmask("192.0.2.128/32");
@@ -729,8 +716,7 @@ BOOST_AUTO_TEST_CASE(test_edns_submask_by_addr) {
   primeHints();
 
   const DNSName target("powerdns.com.");
-  g_useIncomingECS = true;
-  g_ednssubnets.addMask("192.0.2.1/32");
+  SyncRes::addEDNSSubnet(Netmask("192.0.2.1/32"));
 
   EDNSSubnetOpts incomingECS;
   incomingECS.source = Netmask("2001:DB8::FF/128");
@@ -1209,7 +1195,7 @@ BOOST_AUTO_TEST_CASE(test_dont_query_server) {
     });
 
   /* prevent querying this NS */
-  g_dontQuery->addMask(Netmask(ns));
+  SyncRes::addDontQuery(Netmask(ns));
 
   vector<DNSRecord> ret;
   int res = sr->beginResolve(target, QType(QType::A), QClass::IN, ret);
@@ -1412,8 +1398,7 @@ BOOST_AUTO_TEST_CASE(test_skip_negcache_for_variable_response) {
   const DNSName target("www.powerdns.com.");
   const DNSName cnameTarget("cname.powerdns.com.");
 
-  g_useIncomingECS = true;
-  g_ednsdomains.add(DNSName("powerdns.com."));
+  SyncRes::addEDNSDomain(DNSName("powerdns.com."));
 
   EDNSSubnetOpts incomingECS;
   incomingECS.source = Netmask("192.0.2.128/32");
@@ -1729,8 +1714,8 @@ BOOST_AUTO_TEST_CASE(test_delegation_only) {
   primeHints();
 
   /* Thanks, Verisign */
-  g_delegationOnly.insert(DNSName("com."));
-  g_delegationOnly.insert(DNSName("net."));
+  SyncRes::addDelegationOnly(DNSName("com."));
+  SyncRes::addDelegationOnly(DNSName("net."));
 
   const DNSName target("nx-powerdns.com.");
 
index 845155b77581fa33690a1ba96a88cc1ecac98756..8bfedcedf5ea7b6983ee63b65f3f375e25cc0871 100644 (file)
@@ -97,7 +97,7 @@ void primeHints(void)
   t_RC->replace(time(0), g_rootdnsname, QType(QType::NS), nsset, vector<std::shared_ptr<RRSIGRecordContent>>(), false); // and stuff in the cache
 }
 
-static void makeNameToIPZone(SyncRes::domainmap_t* newMap, const DNSName& hostname, const string& ip)
+static void makeNameToIPZone(std::shared_ptr<SyncRes::domainmap_t> newMap, const DNSName& hostname, const string& ip)
 {
   SyncRes::AuthDomain ad;
   ad.d_rdForward=false;
@@ -131,7 +131,7 @@ static void makeNameToIPZone(SyncRes::domainmap_t* newMap, const DNSName& hostna
 }
 
 //! parts[0] must be an IP address, the rest must be host names
-static void makeIPToNamesZone(SyncRes::domainmap_t* newMap, const vector<string>& parts) 
+static void makeIPToNamesZone(std::shared_ptr<SyncRes::domainmap_t> newMap, const vector<string>& parts)
 {
   string address=parts[0];
   vector<string> ipparts;
@@ -233,7 +233,7 @@ void* pleaseWipeNegCache()
   return 0;
 }
 
-void* pleaseUseNewSDomainsMap(SyncRes::domainmap_t* newmap)
+void* pleaseUseNewSDomainsMap(std::shared_ptr<SyncRes::domainmap_t> newmap)
 {
   t_sstorage->domainmap = newmap;
   return 0;
@@ -241,14 +241,14 @@ void* pleaseUseNewSDomainsMap(SyncRes::domainmap_t* newmap)
 
 string reloadAuthAndForwards()
 {
-  SyncRes::domainmap_t* original=t_sstorage->domainmap;  
+  std::shared_ptr<SyncRes::domainmap_t> original=t_sstorage->domainmap;
   
   try {
     L<<Logger::Warning<<"Reloading zones, purging data from cache"<<endl;
   
-    for(SyncRes::domainmap_t::const_iterator i = t_sstorage->domainmap->begin(); i != t_sstorage->domainmap->end(); ++i) {
-      for(SyncRes::AuthDomain::records_t::const_iterator j = i->second.d_records.begin(); j != i->second.d_records.end(); ++j) 
-        broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, j->d_name, false));
+    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));
     }
 
     string configname=::arg()["config-dir"]+"/recursor.conf";
@@ -285,17 +285,16 @@ string reloadAuthAndForwards()
     ::arg().preParse(g_argc, g_argv, "export-etc-hosts");
     ::arg().preParse(g_argc, g_argv, "serve-rfc1918");
 
-    SyncRes::domainmap_t* newDomainMap = parseAuthAndForwards();
+    std::shared_ptr<SyncRes::domainmap_t> newDomainMap = parseAuthAndForwards();
     
     // purge again - new zones need to blank out the cache
-    for(SyncRes::domainmap_t::const_iterator i = newDomainMap->begin(); i != newDomainMap->end(); ++i) {
-        broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, i->first, true));
-        broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, i->first, true));
-        broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, i->first, true));
+    for(const auto& i : *newDomainMap) {
+        broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, i.first, true));
+        broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, i.first, true));
+        broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, i.first, true));
     }
 
-    broadcastFunction(boost::bind(pleaseUseNewSDomainsMap, newDomainMap)); 
-    delete original;
+    broadcastFunction(boost::bind(pleaseUseNewSDomainsMap, newDomainMap));
     return "ok\n";
   }
   catch(std::exception& e) {
@@ -397,12 +396,12 @@ void RPZIXFRTracker(const ComboAddress& master, const DNSName& zoneName, boost::
   }
 }
 
-SyncRes::domainmap_t* parseAuthAndForwards()
+std::shared_ptr<SyncRes::domainmap_t> parseAuthAndForwards()
 {
   TXTRecordContent::report();
   OPTRecordContent::report();
 
-  SyncRes::domainmap_t* newMap = new SyncRes::domainmap_t();
+  auto newMap = std::make_shared<SyncRes::domainmap_t>();
 
   typedef vector<string> parts_t;
   parts_t parts;  
@@ -430,11 +429,9 @@ SyncRes::domainmap_t* parseAuthAndForwards()
            dr.d_place=DNSResourceRecord::ANSWER;
           }
           catch(std::exception &e) {
-            delete newMap;
             throw PDNSException("Error parsing record '"+rr.qname.toString()+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"': "+e.what());
           }
           catch(...) {
-            delete newMap;
             throw PDNSException("Error parsing record '"+rr.qname.toString()+"' of type "+rr.qtype.getName()+" in zone '"+headers.first+"' from file '"+headers.second+"'");
           }
 
@@ -466,7 +463,6 @@ SyncRes::domainmap_t* parseAuthAndForwards()
     FILE *rfp=fopen(::arg()["forward-zones-file"].c_str(), "r");
 
     if(!rfp) {
-      delete newMap;
       throw PDNSException("Error opening forward-zones-file '"+::arg()["forward-zones-file"]+"': "+stringerror());
     }
 
@@ -494,7 +490,6 @@ SyncRes::domainmap_t* parseAuthAndForwards()
       else
         ad.d_rdForward = false;
       if(domain.empty()) {
-        delete newMap;
         throw PDNSException("Error parsing line "+std::to_string(linenum)+" of " +::arg()["forward-zones-file"]);
       }
 
@@ -502,7 +497,6 @@ SyncRes::domainmap_t* parseAuthAndForwards()
         convertServersForAD(instructions, ad, ",; ", false);
       }
       catch(...) {
-        delete newMap;
         throw PDNSException("Conversion error parsing line "+std::to_string(linenum)+" of " +::arg()["forward-zones-file"]);
       }
 
index 1fa95b0bad8721f36d787e69dab3bcae27d39277..3cea08afac1040ccf282e60ee909ef6e81880604 100644 (file)
@@ -78,6 +78,10 @@ unsigned int SyncRes::s_maxtotusec;
 unsigned int SyncRes::s_maxdepth;
 string SyncRes::s_serverID;
 SyncRes::LogMode SyncRes::s_lm;
+std::unordered_set<DNSName> SyncRes::s_delegationOnly;
+std::unique_ptr<NetmaskGroup> SyncRes::s_dontQuery{nullptr};
+NetmaskGroup SyncRes::s_ednssubnets;
+SuffixMatchNode SyncRes::s_ednsdomains;
 
 #define LOG(x) if(d_lm == Log) { L <<Logger::Warning << x; } else if(d_lm == Store) { d_trace << x; }
 
@@ -335,6 +339,29 @@ void SyncRes::doEDNSDumpAndClose(int fd)
   fclose(fp);
 }
 
+uint64_t SyncRes::doDumpNSSpeeds(int fd)
+{
+  FILE* fp=fdopen(dup(fd), "w");
+  if(!fp)
+    return 0;
+  fprintf(fp, "; nsspeed dump from thread follows\n;\n");
+  uint64_t count=0;
+
+  for(const auto& i : t_sstorage->nsSpeeds)
+  {
+    count++;
+    fprintf(fp, "%s -> ", i.first.toString().c_str());
+    for(const auto& j : i.second.d_collection)
+    {
+      // typedef vector<pair<ComboAddress, DecayingEwma> > collection_t;
+      fprintf(fp, "%s/%f ", j.first.toString().c_str(), j.second.peek());
+    }
+    fprintf(fp, "\n");
+  }
+  fclose(fp);
+  return count;
+}
+
 /* so here is the story. First we complete the full resolution process for a domain name. And only THEN do we decide
    to also do DNSSEC validation, which leads to new queries. To make this simple, we *always* ask for DNSSEC records
    so that if there are RRSIGs for a name, we'll have them.
@@ -1088,8 +1115,6 @@ 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)
 {
-  extern NetmaskGroup* g_dontQuery;
-
   if(t_sstorage->throttle.shouldThrottle(d_now.tv_sec, boost::make_tuple(remoteIP, "", 0))) {
     LOG(prefix<<qname<<": server throttled "<<endl);
     s_throttledqueries++; d_throttledqueries++;
@@ -1100,7 +1125,7 @@ bool SyncRes::throttledOrBlocked(const std::string& prefix, const ComboAddress&
     s_throttledqueries++; d_throttledqueries++;
     return true;
   }
-  else if(!pierceDontQuery && g_dontQuery && g_dontQuery->match(&remoteIP)) {
+  else if(!pierceDontQuery && s_dontQuery && s_dontQuery->match(&remoteIP)) {
     LOG(prefix<<qname<<": not sending query to " << remoteIP.toString() << ", blocked by 'dont-query' setting" << endl);
     s_dontqueries++;
     return true;
@@ -1153,7 +1178,7 @@ RCode::rcodes_ SyncRes::updateCacheFromRecords(const std::string& prefix, LWResu
       if(rec.d_type == QType::RRSIG) {
         LOG("RRSIG - separate"<<endl);
       }
-      else if(lwr.d_aabit && lwr.d_rcode==RCode::NoError && rec.d_place==DNSResourceRecord::ANSWER && (rec.d_type != QType::DNSKEY || rec.d_name != auth) && g_delegationOnly.count(auth)) {
+      else if(lwr.d_aabit && lwr.d_rcode==RCode::NoError && rec.d_place==DNSResourceRecord::ANSWER && (rec.d_type != QType::DNSKEY || rec.d_name != auth) && s_delegationOnly.count(auth)) {
         LOG("NO! Is from delegation-only zone"<<endl);
         s_nodelegated++;
         return RCode::NXDomain;
@@ -1625,7 +1650,7 @@ boost::optional<Netmask> SyncRes::getEDNSSubnetMask(const ComboAddress& local, c
     return result;
   }
 
-  if(g_ednsdomains.check(dn) || g_ednssubnets.match(rem)) {
+  if(s_ednsdomains.check(dn) || s_ednssubnets.match(rem)) {
     bits = std::min(bits, (trunc.isIPv4() ? s_ecsipv4limit : s_ecsipv6limit));
     trunc.truncate(bits);
     return boost::optional<Netmask>(Netmask(trunc, bits));
@@ -1634,6 +1659,20 @@ boost::optional<Netmask> SyncRes::getEDNSSubnetMask(const ComboAddress& local, c
   return result;
 }
 
+void SyncRes::parseEDNSSubnetWhitelist(const std::string& wlist)
+{
+  vector<string> parts;
+  stringtok(parts, wlist, ",; ");
+  for(const auto& a : parts) {
+    try {
+      s_ednssubnets.addMask(Netmask(a));
+    }
+    catch(...) {
+      s_ednsdomains.add(DNSName(a));
+    }
+  }
+}
+
 // used by PowerDNSLua - note that this neglects to add the packet count & statistics back to pdns_ercursor.cc
 int directResolve(const DNSName& qname, const QType& qtype, int qclass, vector<DNSRecord>& ret)
 {
index e0d110178dd14f99aad83587ef86a24c0c8f6549..1b14687538f09c47da0fb0fd246ef22be9fa49b1 100644 (file)
@@ -59,8 +59,6 @@
 #include <boost/uuid/uuid_generators.hpp>
 #endif
 
-void primeHints(void);
-
 class RecursorLua4;
 
 typedef map<
@@ -279,10 +277,60 @@ class SyncRes : public boost::noncopyable
 {
 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;
 
-  explicit SyncRes(const struct timeval& now);
+  static void setDefaultLogMode(LogMode lm)
+  {
+    s_lm = lm;
+  }
+  static void doEDNSDumpAndClose(int fd);
+  static uint64_t doDumpNSSpeeds(int fd);
+  static int getRootNS(struct timeval now, asyncresolve_t asyncCallback);
+  static void clearDelegationOnly()
+  {
+    s_delegationOnly.clear();
+  }
+  static void addDelegationOnly(const DNSName& name)
+  {
+    s_delegationOnly.insert(name);
+  }
+  static void addDontQuery(const std::string& mask)
+  {
+    if (!s_dontQuery)
+      s_dontQuery = std::unique_ptr<NetmaskGroup>(new NetmaskGroup());
 
-  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;
+    s_dontQuery->addMask(mask);
+  }
+  static void addDontQuery(const Netmask& mask)
+  {
+    if (!s_dontQuery)
+      s_dontQuery = std::unique_ptr<NetmaskGroup>(new NetmaskGroup());
+
+    s_dontQuery->addMask(mask);
+  }
+  static void clearDontQuery()
+  {
+    s_dontQuery = nullptr;
+  }
+  static void parseEDNSSubnetWhitelist(const std::string& wlist);
+  static void addEDNSSubnet(const Netmask& subnet)
+  {
+    s_ednssubnets.addMask(subnet);
+  }
+  static void addEDNSDomain(const DNSName& domain)
+  {
+    s_ednsdomains.add(domain);
+  }
+  static void clearEDNSSubnets()
+  {
+    s_ednssubnets.clear();
+  }
+  static void clearEDNSDomains()
+  {
+    s_ednsdomains = SuffixMatchNode();
+  }
+
+  explicit SyncRes(const struct timeval& now);
 
   int beginResolve(const DNSName &qname, const QType &qtype, uint16_t qclass, vector<DNSRecord>&ret);
   void setId(int id)
@@ -290,10 +338,6 @@ public:
     if(doLog())
       d_prefix="["+itoa(id)+"] ";
   }
-  static void setDefaultLogMode(LogMode lm)
-  {
-    s_lm = lm;
-  }
 
   void setLogMode(LogMode lm)
   {
@@ -386,9 +430,6 @@ public:
     d_asyncResolve = func;
   }
 
-  static void doEDNSDumpAndClose(int fd);
-  static int getRootNS(struct timeval now, asyncresolve_t asyncCallback);
-
   static std::atomic<uint64_t> s_queries;
   static std::atomic<uint64_t> s_outgoingtimeouts;
   static std::atomic<uint64_t> s_outgoing4timeouts;
@@ -399,11 +440,7 @@ public:
   static std::atomic<uint64_t> s_tcpoutqueries;
   static std::atomic<uint64_t> s_nodelegated;
   static std::atomic<uint64_t> s_unreachables;
-  static unsigned int s_minimumTTL;
-  static bool s_doIPv6;
-  static unsigned int s_maxqperq;
-  static unsigned int s_maxtotusec;
-  static unsigned int s_maxdepth;
+
   std::unordered_map<std::string,bool> d_discardedPolicies;
   DNSFilterEngine::Policy d_appliedPolicy;
   unsigned int d_outqueries;
@@ -475,9 +512,6 @@ public:
 
   typedef map<ComboAddress, EDNSStatus> ednsstatus_t;
 
-  static bool s_noEDNSPing;
-  static bool s_noEDNS;
-  static bool s_rootNXTrust;
   struct AuthDomain
   {
     vector<ComboAddress> d_servers;
@@ -500,11 +534,15 @@ public:
 
   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;
+  static unsigned int s_maxtotusec;
+  static unsigned int s_maxdepth;
   static unsigned int s_maxnegttl;
   static unsigned int s_maxcachettl;
   static unsigned int s_packetcachettl;
@@ -513,21 +551,41 @@ public:
   static unsigned int s_serverdownthrottletime;
   static uint8_t s_ecsipv4limit;
   static uint8_t s_ecsipv6limit;
+  static bool s_doIPv6;
+  static bool s_noEDNSPing;
+  static bool s_noEDNS;
+  static bool s_rootNXTrust;
   static bool s_nopacketcache;
-  static string s_serverID;
 
   struct StaticStorage {
     nsspeeds_t nsSpeeds;
     ednsstatus_t ednsstatus;
     throttle_t throttle;
     fails_t fails;
-    domainmap_t* domainmap;
+    std::shared_ptr<domainmap_t> domainmap;
     map<DNSName, bool> dnssecmap;
     NegCache negcache;
   };
 
 private:
-  struct GetBestNSAnswer;
+  static std::unordered_set<DNSName> s_delegationOnly;
+  static NetmaskGroup s_ednssubnets;
+  static SuffixMatchNode s_ednsdomains;
+  static LogMode s_lm;
+  static std::unique_ptr<NetmaskGroup> s_dontQuery;
+
+  struct GetBestNSAnswer
+  {
+    DNSName qname;
+    set<pair<DNSName,DNSName> > bestns;
+    uint8_t qtype; // only A and AAAA anyhow
+    bool operator<(const GetBestNSAnswer &b) const
+    {
+      return boost::tie(qname, qtype, bestns) <
+       boost::tie(b.qname, b.qtype, b.bestns);
+    }
+  };
+
   int doResolveAt(NsSet &nameservers, DNSName auth, bool flawedNSSet, const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret,
                   unsigned int depth, set<GetBestNSAnswer>&beenthere);
   int doResolve(const DNSName &qname, const QType &qtype, vector<DNSRecord>&ret, unsigned int depth, set<GetBestNSAnswer>& beenthere);
@@ -582,21 +640,7 @@ private:
   bool d_wasOutOfBand{false};
   bool d_wasVariable{false};
 
-  static LogMode s_lm;
   LogMode d_lm;
-
-  struct GetBestNSAnswer
-  {
-    DNSName qname;
-    set<pair<DNSName,DNSName> > bestns; 
-    uint8_t qtype; // only A and AAAA anyhow
-    bool operator<(const GetBestNSAnswer &b) const
-    {
-      return boost::tie(qname, qtype, bestns) <
-       boost::tie(b.qname, b.qtype, b.bestns);
-    }
-  };
-
 };
 extern __thread SyncRes::StaticStorage* t_sstorage;
 
@@ -750,7 +794,6 @@ string doTraceRegex(vector<string>::const_iterator begin, vector<string>::const_
 void parseACLs();
 extern RecursorStats g_stats;
 extern unsigned int g_numThreads;
-extern std::unordered_set<DNSName> g_delegationOnly;
 extern uint16_t g_outgoingEDNSBufsize;
 
 
@@ -765,7 +808,7 @@ int directResolve(const DNSName& qname, const QType& qtype, int qclass, vector<D
 
 template<class T> T broadcastAccFunction(const boost::function<T*()>& func, bool skipSelf=false);
 
-SyncRes::domainmap_t* parseAuthAndForwards();
+std::shared_ptr<SyncRes::domainmap_t> parseAuthAndForwards();
 uint64_t* pleaseGetNsSpeedsSize();
 uint64_t* pleaseGetCacheSize();
 uint64_t* pleaseGetNegCacheSize();
@@ -779,13 +822,10 @@ uint64_t* pleaseWipeCache(const DNSName& canon, bool subtree=false);
 uint64_t* pleaseWipePacketCache(const DNSName& canon, bool subtree);
 uint64_t* pleaseWipeAndCountNegCache(const DNSName& canon, bool subtree=false);
 void doCarbonDump(void*);
-void  parseEDNSSubnetWhitelist(const std::string& wlist);
+void primeHints(void);
 
 extern __thread struct timeval g_now;
 
-extern NetmaskGroup g_ednssubnets;
-extern SuffixMatchNode g_ednsdomains;
-
 #ifdef HAVE_PROTOBUF
 extern __thread boost::uuids::random_generator* t_uuidGenerator;
 #endif