]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
revamp dynamic block syntax, you now insert blocks per x seconds, and we display...
authorbert hubert <bert.hubert@netherlabs.nl>
Sat, 5 Dec 2015 21:23:06 +0000 (22:23 +0100)
committerbert hubert <bert.hubert@netherlabs.nl>
Sat, 5 Dec 2015 21:23:06 +0000 (22:23 +0100)
pdns/dnsdist-lua2.cc
pdns/dnsdist-tcp.cc
pdns/dnsdist-web.cc
pdns/dnsdist.cc
pdns/dnsdist.hh
pdns/dnsdistdist/html/index.html
pdns/dnsdistdist/html/local.js

index d6b0325353a221c5e7c63ed33afa912c134ecdca..389b41ad181d4d01e1252c5d5c55d045956f433d 100644 (file)
@@ -104,13 +104,17 @@ map<ComboAddress,int> exceedRespByterate(int rate, int seconds)
 
 void moreLua()
 {
-  typedef NetmaskTree<string> nmts_t;
+  typedef NetmaskTree<DynBlock> nmts_t;
   g_lua.writeFunction("newCA", [](const std::string& name) { return ComboAddress(name); });
   g_lua.writeFunction("newNMG", []() { return nmts_t(); });
-  g_lua.registerFunction<void(nmts_t::*)(const ComboAddress&, const std::string&)>("add", 
-                                                              [](nmts_t& s, const ComboAddress& ca, const std::string& msg
+  g_lua.registerFunction<void(nmts_t::*)(const ComboAddress&, const std::string&, boost::optional<int> seconds)>("add", 
+                                                                                                                [](nmts_t& s, const ComboAddress& ca, const std::string& msg, boost::optional<int> seconds
                                                               { 
-                                                                s.insert(Netmask(ca)).second=msg; 
+                                                                struct timespec until;
+                                                                clock_gettime(CLOCK_MONOTONIC, &until);
+                                                                until.tv_sec += seconds ? *seconds : 10;
+                                                                
+                                                                s.insert(Netmask(ca)).second={msg, until};
                                                               });
 
   g_lua.writeFunction("setDynBlockNMG", [](const nmts_t& nmg) {
@@ -119,16 +123,42 @@ void moreLua()
 
   g_lua.writeFunction("showDynBlocks", []() {
       auto slow = g_dynblockNMG.getCopy();
+      struct timespec now;
+      clock_gettime(CLOCK_MONOTONIC, &now);
+      boost::format fmt("%-24s %8d %s\n");
+      g_outputBuffer = (fmt % "Netmask" % "Seconds" % "Reason").str();
       for(const auto& e: slow) {
-       g_outputBuffer+=e->first.toString()+"\t"+e->second+"\n";
+       if(now < e->second.until)
+         g_outputBuffer+= (fmt % e->first.toString() % (e->second.until.tv_sec - now.tv_sec) % e->second.reason).str();
       }
     });
 
-  g_lua.registerFunction<void(nmts_t::*)(const map<ComboAddress,int>&, const std::string&)>("add", 
-                                                                       [](nmts_t& s, const map<ComboAddress,int>& m, const std::string& msg) { 
-                                                                               for(const auto& capair : m)
-                                                                                 s.insert(Netmask(capair.first)).second=msg;
-                                                                             });
+  g_lua.writeFunction("clearDynBlocks", []() {
+      nmts_t nmg;
+      g_dynblockNMG.setState(nmg);
+    });
+
+  g_lua.writeFunction("addDynBlocks", 
+                         [](const map<ComboAddress,int>& m, const std::string& msg, boost::optional<int> seconds) { 
+                          auto slow = g_dynblockNMG.getCopy();
+                          struct timespec until;
+                          clock_gettime(CLOCK_MONOTONIC, &until);
+                          until.tv_sec += seconds ? *seconds : 10;
+                          for(const auto& capair : m)
+                            slow.insert(Netmask(capair.first)).second={msg, until};
+                          g_dynblockNMG.setState(slow);
+                        });
+
+
+
+  g_lua.registerFunction<void(nmts_t::*)(const map<ComboAddress,int>&, const std::string&, boost::optional<int>)>("add", 
+                                                                                           [](nmts_t& s, const map<ComboAddress,int>& m, const std::string& msg, boost::optional<int> seconds) { 
+                                                                                             struct timespec until;
+                                                                                             clock_gettime(CLOCK_MONOTONIC, &until);
+                                                                                             until.tv_sec += seconds ? *seconds : 10;
+                                                                                             for(const auto& capair : m)
+                                                                                               s.insert(Netmask(capair.first)).second={msg, until};
+                                                                                           });
 
 
   g_lua.registerFunction<bool(nmts_t::*)(const ComboAddress&)>("match", 
index efdba5a14a9d8b42b6279f38c8c38df5a2052cf1..9d6a0b81ee19a0a3603b3f7b3d4c740a439066a5 100644 (file)
@@ -176,10 +176,13 @@ void* tcpClientThread(int pipefd)
          ci.cs->queries++;
        }
 
-       if(localDynBlockNMG->match(ci.remote)) {
-         vinfolog("Query from %s dropped because of dynamic block", ci.remote.toStringWithPort());
-         g_stats.dynBlocked++;
-         goto drop;
+       if(auto got=localDynBlockNMG->lookup(ci.remote)) {
+         if(now < got->second.until) {
+           vinfolog("Query from %s dropped because of dynamic block", ci.remote.toStringWithPort());
+           g_stats.dynBlocked++;
+           got->second.blocks++;
+           goto drop;
+         }
        }
 
         if (dh->rd) {
index 0a38d2a271f2d9199530dcad701f3322e0db06a4..72ee3d06b0f9fe76290fb9c1e6327a86ad719ed3 100644 (file)
@@ -105,8 +105,14 @@ static void connectionThread(int sock, ComboAddress remote, string password)
  
       Json::object obj;
       auto slow = g_dynblockNMG.getCopy();
+      struct timespec now;
+      clock_gettime(CLOCK_MONOTONIC, &now);
       for(const auto& e: slow) {
-       obj.insert({e->first.toString(), e->second});
+       if(now < e->second.until ) {
+         Json::object thing{{"reason", e->second.reason}, {"seconds", (double)(e->second.until.tv_sec - now.tv_sec)},
+                                                            {"blocks", (double)e->second.blocks} };
+         obj.insert({e->first.toString(), thing});
+       }
       }
       Json my_json=obj;
 
index 4dd205a59d3316408b009ea7d5709db4cbaf6d7d..9d1a9f0c2b024983c54fb83274159beeca7f3c18 100644 (file)
@@ -103,7 +103,7 @@ GlobalStateHolder<vector<pair<std::shared_ptr<DNSRule>, std::shared_ptr<DNSActio
 Rings g_rings;
 
 GlobalStateHolder<servers_t> g_dstates;
-GlobalStateHolder<NetmaskTree<string>> g_dynblockNMG;
+GlobalStateHolder<NetmaskTree<DynBlock>> g_dynblockNMG;
 int g_tcpRecvTimeout{2};
 int g_tcpSendTimeout{2};
 
@@ -476,10 +476,13 @@ try
         g_rings.queryRing.push_back({now,remote,qname,qtype});
       }
       
-      if(localDynBlock->match(remote)) {
-       vinfolog("Query from %s dropped because of dynamic block", remote.toStringWithPort());
-       g_stats.dynBlocked++;
-       continue;
+      if(auto got=localDynBlock->lookup(remote)) {
+       if(now < got->second.until) {
+         vinfolog("Query from %s dropped because of dynamic block", remote.toStringWithPort());
+         g_stats.dynBlocked++;
+         got->second.blocks++;
+         continue;
+       }
       }
 
       if(blockFilter) {
@@ -699,6 +702,9 @@ void* maintThread()
     auto f =g_lua.readVariable<boost::optional<std::function<void()> > >("maintenance");
     if(f)
       (*f)();
+    
+
+    // ponder pruning g_dynblocks of expired entries here
   }
   return 0;
 }
index d4314d5e362e44fa386029658256fa75effec505..1aaef1da3d672918eabc7a9236859e5dc7af19f5 100644 (file)
 void* carbonDumpThread();
 uint64_t uptimeOfProcess(const std::string& str);
 
-extern GlobalStateHolder<NetmaskTree<string>> g_dynblockNMG;
+struct DynBlock
+{
+  DynBlock& operator=(const DynBlock& rhs)
+  {
+    reason=rhs.reason;
+    until=rhs.until;
+    blocks.store(rhs.blocks);
+    return *this;
+  }
+  
+  string reason;
+  struct timespec until;
+  mutable std::atomic<unsigned int> blocks;
+};
+
+extern GlobalStateHolder<NetmaskTree<DynBlock>> g_dynblockNMG;
 struct DNSDistStats
 {
   using stat_t=std::atomic<uint64_t>; // aww yiss ;-)
index 13504442052dcb56215c39e8b4304c9ef7f618d1..dcc6977b3eef6cf6e8881ef1e6088ab1d838cdd7 100644 (file)
@@ -69,7 +69,7 @@
                   <div id="qpschart"></div>
                 </div>
             </td></tr>
-            <tr><td align="center">CPU</td></tr>
+            <tr><td align="center">CPU %</td></tr>
             <tr><td>
                 <div id="chart_container">
                   <div id="cpuy_axis"></div>
index 62a199e65016215cb52c1b88f21360d48b53a555..1fae3bf5a3f0b4fc0a5f408c71ec5b69a58e767e 100644 (file)
@@ -208,20 +208,21 @@ $(document).ready(function() {
                });
 
 
-        if((intervalcount++)%5)
-            return;
+//        if((intervalcount++)%5)
+  //          return;
         //      updateRingBuffers();
 
         $.ajax({ url: 'jsonstat?command=dynblocklist', type: 'GET', dataType: 'json',
                  success: function(data) {
-                     var bouw='<table width="100%"><tr align=left><th>Dyn blocked netmask</th><th align=left>Reason</th></tr>';
-                     if(data.length) {
-                         $.each(data, function(a,b) {
-                             bouw=bouw+("<tr><td>"+a+"</td><td>"+b+"</td></tr>");
-                         });
-                     }
-                     else 
-                         bouw = bouw + '<tr><td align="center" colspan="2"><font color="#aaaaaa">No dynamic blocks active</font></td></tr>';
+                     var bouw='<table width="100%"><tr align=left><th>Dyn blocked netmask</th><th>Seconds</th><th>Blocks</th><th align=left>Reason</th></tr>';
+                    var gotsome=false;
+                     $.each(data, function(a,b) {
+                         bouw=bouw+("<tr><td>"+a+"</td><td>"+b.seconds+"</td><td>"+b.blocks+"</td><td>"+b.reason+"</td></tr>");
+                        gotsome=true;
+                     });
+                     
+                    if(!gotsome)
+                         bouw = bouw + '<tr><td align="center" colspan="4"><font color="#aaaaaa">No dynamic blocks active</font></td></tr>';
 
                      bouw=bouw+"</table>";
                      $("#dynblock").html(bouw);