From fd010ca3ddeeab40d1b933305822bcc247204a05 Mon Sep 17 00:00:00 2001 From: bert hubert Date: Mon, 13 Apr 2015 22:19:03 +0200 Subject: [PATCH] add addQPSPoolRule based on suggestion by Matt Singh, and document it --- pdns/README-dnsdist.md | 8 ++++++++ pdns/dnsdist-lua.cc | 31 +++++++++++++++++++++++++++++++ pdns/dnsdistconf.lua | 1 + pdns/dnsrulactions.hh | 24 ++++++++++++++++++++++++ 4 files changed, 64 insertions(+) diff --git a/pdns/README-dnsdist.md b/pdns/README-dnsdist.md index 76e5e4432d..99e2d8e7e1 100644 --- a/pdns/README-dnsdist.md +++ b/pdns/README-dnsdist.md @@ -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 diff --git a/pdns/dnsdist-lua.cc b/pdns/dnsdist-lua.cc index 853d473792..0d764dbaab 100644 --- a/pdns/dnsdist-lua.cc +++ b/pdns/dnsdist-lua.cc @@ -301,6 +301,37 @@ vector> setupLua(bool client, const std::string& confi }); }); + g_lua.writeFunction("addQPSPoolRule", [](boost::variant> > 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(&var)) + add(*src); + else { + for(auto& a : boost::get>>(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(smn), + std::make_shared(limit, pool) }); + }); + else + g_rulactions.modify([nmg,pool,limit](decltype(g_rulactions)::value_type& rulactions) { + rulactions.push_back({std::make_shared(nmg), + std::make_shared(limit, pool)}); + }); + + }); g_lua.writeFunction("setDNSSECPool", [](const std::string& pool) { g_rulactions.modify([pool](decltype(g_rulactions)::value_type& rulactions) { diff --git a/pdns/dnsdistconf.lua b/pdns/dnsdistconf.lua index ea219e138d..ce69fd3803 100644 --- a/pdns/dnsdistconf.lua +++ b/pdns/dnsdistconf.lua @@ -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.") diff --git a/pdns/dnsrulactions.hh b/pdns/dnsrulactions.hh index 623f345f6d..49d11690bc 100644 --- a/pdns/dnsrulactions.hh +++ b/pdns/dnsrulactions.hh @@ -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: -- 2.47.2