]> git.ipfire.org Git - thirdparty/pdns.git/blobdiff - pdns/rec_channel_rec.cc
Merge pull request #8777 from omoerbeek/rec-wip-qname-vs-ds
[thirdparty/pdns.git] / pdns / rec_channel_rec.cc
index 432b8a22e7c87c5d3487237edc01db2e9150d6ad..5eccb7583bd81bbca48c040b57f49475f927c419 100644 (file)
@@ -231,6 +231,11 @@ static uint64_t* pleaseDumpThrottleMap(int fd)
   return new uint64_t(SyncRes::doDumpThrottleMap(fd));
 }
 
+static uint64_t* pleaseDumpFailedServers(int fd)
+{
+  return new uint64_t(SyncRes::doDumpFailedServers(fd));
+}
+
 template<typename T>
 static string doDumpNSSpeeds(T begin, T end)
 {
@@ -367,14 +372,36 @@ static string doDumpThrottleMap(T begin, T end)
   return "dumped "+std::to_string(total)+" records\n";
 }
 
-uint64_t* pleaseWipeCache(const DNSName& canon, bool subtree)
+template<typename T>
+static string doDumpFailedServers(T begin, T end)
 {
-  return new uint64_t(t_RC->doWipeCache(canon, subtree));
+  T i=begin;
+  string fname;
+
+  if(i!=end)
+    fname=*i;
+
+  int fd=open(fname.c_str(), O_CREAT | O_EXCL | O_WRONLY, 0660);
+  if(fd < 0)
+    return "Error opening dump file for writing: "+stringerror()+"\n";
+  uint64_t total = 0;
+  try {
+    total = broadcastAccFunction<uint64_t>(boost::bind(pleaseDumpFailedServers, fd));
+  }
+  catch(...){}
+
+  close(fd);
+  return "dumped "+std::to_string(total)+" records\n";
 }
 
-uint64_t* pleaseWipePacketCache(const DNSName& canon, bool subtree)
+uint64_t* pleaseWipeCache(const DNSName& canon, bool subtree, uint16_t qtype)
 {
-  return new uint64_t(t_packetCache->doWipePacketCache(canon,0xffff, subtree));
+  return new uint64_t(t_RC->doWipeCache(canon, subtree, qtype));
+}
+
+uint64_t* pleaseWipePacketCache(const DNSName& canon, bool subtree, uint16_t qtype)
+{
+  return new uint64_t(t_packetCache->doWipePacketCache(canon, qtype, subtree));
 }
 
 
@@ -386,7 +413,7 @@ uint64_t* pleaseWipeAndCountNegCache(const DNSName& canon, bool subtree)
 
 
 template<typename T>
-static string doWipeCache(T begin, T end)
+static string doWipeCache(T begin, T end, uint16_t qtype)
 {
   vector<pair<DNSName, bool> > toWipe;
   for(T i=begin; i != end; ++i) {
@@ -408,8 +435,8 @@ static string doWipeCache(T begin, T end)
 
   int count=0, pcount=0, countNeg=0;
   for (auto wipe : toWipe) {
-    count+= broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, wipe.first, wipe.second));
-    pcount+= broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, wipe.first, wipe.second));
+    count+= broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, wipe.first, wipe.second, qtype));
+    pcount+= broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, wipe.first, wipe.second, qtype));
     countNeg+=broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, wipe.first, wipe.second));
   }
 
@@ -511,8 +538,8 @@ static string doAddNTA(T begin, T end)
   g_luaconfs.modify([who, why](LuaConfigItems& lci) {
       lci.negAnchors[who] = why;
       });
-  broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, who, true));
-  broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, who, true));
+  broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, who, true, 0xffff));
+  broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, who, true, 0xffff));
   broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, who, true));
   return "Added Negative Trust Anchor for " + who.toLogString() + " with reason '" + why + "'\n";
 }
@@ -559,8 +586,8 @@ static string doClearNTA(T begin, T end)
     g_luaconfs.modify([entry](LuaConfigItems& lci) {
         lci.negAnchors.erase(entry);
       });
-    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, entry, true));
-    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, entry, true));
+    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, entry, true, 0xffff));
+    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, entry, true, 0xffff));
     broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, entry, true));
     if (!first) {
       first = false;
@@ -616,8 +643,8 @@ static string doAddTA(T begin, T end)
       auto ds=std::dynamic_pointer_cast<DSRecordContent>(DSRecordContent::make(what));
       lci.dsAnchors[who].insert(*ds);
       });
-    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, who, true));
-    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, who, true));
+    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, who, true, 0xffff));
+    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, who, true, 0xffff));
     broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, who, true));
     g_log<<Logger::Warning<<endl;
     return "Added Trust Anchor for " + who.toStringRootDot() + " with data " + what + "\n";
@@ -662,8 +689,8 @@ static string doClearTA(T begin, T end)
     g_luaconfs.modify([entry](LuaConfigItems& lci) {
         lci.dsAnchors.erase(entry);
       });
-    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, entry, true));
-    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, entry, true));
+    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeCache, entry, true, 0xffff));
+    broadcastAccFunction<uint64_t>(boost::bind(pleaseWipePacketCache, entry, true, 0xffff));
     broadcastAccFunction<uint64_t>(boost::bind(pleaseWipeAndCountNegCache, entry, true));
     if (!first) {
       first = false;
@@ -780,7 +807,7 @@ static ThreadTimes* pleaseGetThreadCPUMsec()
   ret = (ru.ru_utime.tv_sec*1000ULL + ru.ru_utime.tv_usec/1000);
   ret += (ru.ru_stime.tv_sec*1000ULL + ru.ru_stime.tv_usec/1000);
 #endif
-  return new ThreadTimes{ret};
+  return new ThreadTimes{ret, vector<uint64_t>()};
 }
 
 /* Next up, when you want msec data for a specific thread, we check
@@ -885,6 +912,16 @@ static uint64_t getNsSpeedsSize()
   return broadcastAccFunction<uint64_t>(pleaseGetNsSpeedsSize);
 }
 
+uint64_t* pleaseGetFailedServersSize()
+{
+  return new uint64_t(SyncRes::getFailedServersSize());
+}
+
+uint64_t* pleaseGetEDNSStatusesSize()
+{
+  return new uint64_t(SyncRes::getEDNSStatusesSize());
+}
+
 uint64_t* pleaseGetConcurrentQueries()
 {
   return new uint64_t(getMT() ? getMT()->numProcesses() : 0);
@@ -1089,6 +1126,7 @@ void registerAllStats()
   addGetStat("ipv6-outqueries", &g_stats.ipv6queries);
   addGetStat("throttled-outqueries", &SyncRes::s_throttledqueries);
   addGetStat("dont-outqueries", &SyncRes::s_dontqueries);
+  addGetStat("qname-min-fallback-success", &SyncRes::s_qnameminfallbacksuccess);
   addGetStat("throttled-out", &SyncRes::s_throttledqueries);
   addGetStat("unreachables", &SyncRes::s_unreachables);
   addGetStat("ecs-queries", &SyncRes::s_ecsqueries);
@@ -1124,6 +1162,11 @@ void registerAllStats()
   addGetStat("user-msec", getUserTimeMsec);
   addGetStat("sys-msec", getSysTimeMsec);
 
+#ifdef __linux__
+  addGetStat("cpu-iowait", boost::bind(getCPUIOWait, string()));
+  addGetStat("cpu-steal", boost::bind(getCPUSteal, string()));
+#endif
+
   for(unsigned int n=0; n < g_numThreads; ++n)
     addGetStat("cpu-msec-thread-"+std::to_string(n), boost::bind(&doGetThreadCPUMsec, n));
 
@@ -1161,27 +1204,28 @@ void registerAllStats()
   }
 }
 
-static void doExitGeneric(bool nicely)
+void doExitGeneric(bool nicely)
 {
   g_log<<Logger::Error<<"Exiting on user request"<<endl;
   extern RecursorControlChannel s_rcc;
-  s_rcc.~RecursorControlChannel(); 
+  s_rcc.~RecursorControlChannel();
 
   extern string s_pidfname;
-  if(!s_pidfname.empty()) 
+  if(!s_pidfname.empty())
     unlink(s_pidfname.c_str()); // we can at least try..
-  if(nicely)
-    exit(1);
-  else
+  if(nicely) {
+    RecursorControlChannel::stop = 1;
+  } else {
     _exit(1);
+  }
 }
 
-static void doExit()
+void doExit()
 {
   doExitGeneric(false);
 }
 
-static void doExitNicely()
+void doExitNicely()
 {
   doExitGeneric(true);
 }
@@ -1437,7 +1481,7 @@ static string addDontThrottleNames(T begin, T end) {
     dnt.add(d);
   }
 
-  g_dontThrottleNames.setState(dnt);
+  g_dontThrottleNames.setState(std::move(dnt));
 
   ret += " to the list of nameservers that may not be throttled";
   g_log<<Logger::Info<<ret<<", requested via control channel"<<endl;
@@ -1476,7 +1520,7 @@ static string addDontThrottleNetmasks(T begin, T end) {
     dnt.addMask(t);
   }
 
-  g_dontThrottleNetmasks.setState(dnt);
+  g_dontThrottleNetmasks.setState(std::move(dnt));
 
   ret += " to the list of nameserver netmasks that may not be throttled";
   g_log<<Logger::Info<<ret<<", requested via control channel"<<endl;
@@ -1490,7 +1534,7 @@ static string clearDontThrottleNames(T begin, T end) {
 
   if (begin + 1 == end && *begin == "*"){
     SuffixMatchNode smn;
-    g_dontThrottleNames.setState(smn);
+    g_dontThrottleNames.setState(std::move(smn));
     string ret = "Cleared list of nameserver names that may not be throttled";
     g_log<<Logger::Warning<<ret<<", requested via control channel"<<endl;
     return ret + "\n";
@@ -1522,7 +1566,7 @@ static string clearDontThrottleNames(T begin, T end) {
     dnt.remove(name);
   }
 
-  g_dontThrottleNames.setState(dnt);
+  g_dontThrottleNames.setState(std::move(dnt));
 
   ret += " from the list of nameservers that may not be throttled";
   g_log<<Logger::Info<<ret<<", requested via control channel"<<endl;
@@ -1537,7 +1581,7 @@ static string clearDontThrottleNetmasks(T begin, T end) {
   if (begin + 1 == end && *begin == "*"){
     auto nmg = g_dontThrottleNetmasks.getCopy();
     nmg.clear();
-    g_dontThrottleNetmasks.setState(nmg);
+    g_dontThrottleNetmasks.setState(std::move(nmg));
 
     string ret = "Cleared list of nameserver addresses that may not be throttled";
     g_log<<Logger::Warning<<ret<<", requested via control channel"<<endl;
@@ -1574,7 +1618,7 @@ static string clearDontThrottleNetmasks(T begin, T end) {
     dnt.deleteMask(mask);
   }
 
-  g_dontThrottleNetmasks.setState(dnt);
+  g_dontThrottleNetmasks.setState(std::move(dnt));
 
   ret += " from the list of nameservers that may not be throttled";
   g_log<<Logger::Info<<ret<<", requested via control channel"<<endl;
@@ -1612,7 +1656,8 @@ string RecursorControlParser::getAnswer(const string& question, RecursorControlP
 "dump-edns [status] <filename>    dump EDNS status to the named file\n"
 "dump-nsspeeds <filename>         dump nsspeeds statistics to the named file\n"
 "dump-rpz <zone name> <filename>  dump the content of a RPZ zone to the named file\n"
-"dump-throttlemap <filename>      dump the contents of the throttle to the named file\n"
+"dump-throttlemap <filename>      dump the contents of the throttle map to the named file\n"
+"dump-failedservers <filename>    dump the failed servers to the named file\n"
 "get [key1] [key2] ..             get specific statistics\n"
 "get-all                          get all statistics\n"
 "get-dont-throttle-names          get the list of names that are not allowed to be throttled\n"
@@ -1650,7 +1695,8 @@ string RecursorControlParser::getAnswer(const string& question, RecursorControlP
 "top-bogus-remotes                show top remotes receiving bogus answers\n"
 "unload-lua-script                unload Lua script\n"
 "version                          return Recursor version number\n"
-"wipe-cache domain0 [domain1] ..  wipe domain data from cache\n";
+"wipe-cache domain0 [domain1] ..  wipe domain data from cache\n"
+"wipe-cache-typed type domain0 [domain1] ..  wipe domain data with qtype from cache\n";
 
   if(cmd=="get-all")
     return getAllStats();
@@ -1684,6 +1730,9 @@ string RecursorControlParser::getAnswer(const string& question, RecursorControlP
   if(cmd=="dump-nsspeeds")
     return doDumpNSSpeeds(begin, end);
 
+  if(cmd=="dump-failedservers")
+    return doDumpFailedServers(begin, end);
+
   if(cmd=="dump-rpz") {
     return doDumpRPZ(begin, end);
   }
@@ -1692,7 +1741,13 @@ string RecursorControlParser::getAnswer(const string& question, RecursorControlP
    return doDumpThrottleMap(begin, end);
 
   if(cmd=="wipe-cache" || cmd=="flushname")
-    return doWipeCache(begin, end);
+    return doWipeCache(begin, end, 0xffff);
+
+  if(cmd=="wipe-cache-typed") {
+    uint16_t qtype = QType::chartocode(begin->c_str());
+    ++begin;
+    return doWipeCache(begin, end, qtype);
+  }
 
   if(cmd=="reload-lua-script")
     return doQueueReloadLuaScript(begin, end);