]> git.ipfire.org Git - thirdparty/pdns.git/commitdiff
add addQPSPoolRule based on suggestion by Matt Singh, and document it
authorbert hubert <bert.hubert@netherlabs.nl>
Mon, 13 Apr 2015 20:19:03 +0000 (22:19 +0200)
committerbert hubert <bert.hubert@netherlabs.nl>
Mon, 13 Apr 2015 20:19:03 +0000 (22:19 +0200)
pdns/README-dnsdist.md
pdns/dnsdist-lua.cc
pdns/dnsdistconf.lua
pdns/dnsrulactions.hh

index 76e5e4432da202337bcb77b4800ad15d8aa0709f..99e2d8e7e1cc67efa349ffab29aa10dc8fb8dd43 100644 (file)
@@ -164,6 +164,13 @@ We can similarly add clients to the abuse server:
 > addPoolRule({"192.168.12.0/24", "192.168.13.14"}, "abuse")
 ```
 
+To define a pool that should receive a QPS-limited amount of traffic, do:
+
+```
+> addQPSPoolRule("com.", 10000, "gtld-cluster")
+```
+
+
 Both `addDomainBlock` and `addPoolRule` end up the list of Rules 
 and Actions (for which see below).
 
@@ -463,6 +470,7 @@ Here are all functions:
    * `addPoolRule({domain, domain}, pool)`: send queries to these domains to that pool
    * `addPoolRule(netmask, pool)`: send queries to this netmask to that pool
    * `addPoolRule({netmask, netmask}, pool)`: send queries to these netmasks to that pool  
+   * `addQPsPoolRule(x, limit, pool)`: like `addPoolRule`, but only select at most 'limit' queries/s for this pool
    * `getPoolServers(pool)`: return servers part of this pool
  * Server selection policy related:
    * `setServerPolicy(policy)`: set server selection policy to that policy
index 853d473792e91f11e266e6099c310cad38eb895a..0d764dbaab92d2ee28a2b9762be09d2098e371da 100644 (file)
@@ -301,6 +301,37 @@ vector<std::function<void(void)>> setupLua(bool client, const std::string& confi
          });
 
     });
+  g_lua.writeFunction("addQPSPoolRule", [](boost::variant<string,vector<pair<int, string>> > var, int limit, string pool) {
+      SuffixMatchNode smn;
+      NetmaskGroup nmg;
+
+      auto add=[&](string src) {
+       try {
+         smn.add(DNSName(src));
+       } catch(...) {
+         nmg.addMask(src);
+       }
+      };
+      if(auto src = boost::get<string>(&var))
+       add(*src);
+      else {
+       for(auto& a : boost::get<vector<pair<int, string>>>(var)) {
+         add(a.second);
+       }
+      }
+      if(nmg.empty())
+       g_rulactions.modify([smn, pool,limit](decltype(g_rulactions)::value_type& rulactions) {
+           rulactions.push_back({
+                                  std::make_shared<SuffixMatchNodeRule>(smn), 
+                                    std::make_shared<QPSPoolAction>(limit, pool)  });
+         });
+      else
+       g_rulactions.modify([nmg,pool,limit](decltype(g_rulactions)::value_type& rulactions) {
+           rulactions.push_back({std::make_shared<NetmaskGroupRule>(nmg), 
+                 std::make_shared<QPSPoolAction>(limit, pool)}); 
+         });
+
+    });
 
   g_lua.writeFunction("setDNSSECPool", [](const std::string& pool) {
       g_rulactions.modify([pool](decltype(g_rulactions)::value_type& rulactions) {
index ea219e138dd0c0f99ba80b3a73ff7d4f7d9be667..ce69fd3803de692346eaf55f4f544831c63a3fa6 100644 (file)
@@ -21,6 +21,7 @@ newServer{address="192.168.1.30:5300", pool="abuse"}
 
 addPoolRule({"ezdns.it.", "xxx."}, "abuse")
 addPoolRule("192.168.1.0/24", "abuse")
+addQPSPoolRule("com.", 100, "abuse")
 
 addDomainBlock("powerdns.org.")
 addDomainBlock("spectre.")
index 623f345f6d29e1356b09489a2e40deb2b2ab7514..49d11690bcf04accb0ee20092f789858de9411f2 100644 (file)
@@ -128,6 +128,30 @@ private:
   string d_pool;
 };
 
+
+class QPSPoolAction : public DNSAction
+{
+public:
+  QPSPoolAction(unsigned int limit, const std::string& pool) : d_qps(limit, limit), d_pool(pool) {}
+  DNSAction::Action operator()(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len, string* ruleresult) const override
+  {
+    if(d_qps.check()) {
+      *ruleresult=d_pool;
+      return Action::Pool;
+    }
+    else 
+      return Action::None;
+  }
+  string toString() const override
+  {
+    return "max " +std::to_string(d_qps.getRate())+" to pool "+d_pool;
+  }
+
+private:
+  QPSLimiter d_qps;
+  string d_pool;
+};
+
 class RCodeAction : public DNSAction
 {
 public: