});
- g_lua.writeFunction("MaxQPSIPRule", [](unsigned int qps) {
- return std::shared_ptr<DNSRule>(new MaxQPSIPRule(qps));
+ g_lua.writeFunction("MaxQPSIPRule", [](unsigned int qps, boost::optional<int> ipv4trunc, boost::optional<int> ipv6trunc) {
+ return std::shared_ptr<DNSRule>(new MaxQPSIPRule(qps, ipv4trunc.get_value_or(32), ipv6trunc.get_value_or(64)));
});
end
addLuaAction("192.168.1.0/24", luarule)
+addAction(MaxQPSIPRule(5, 24, 64), DropAction())
+
topRule()
addDomainBlock("powerdns.org.")
class MaxQPSIPRule : public DNSRule
{
public:
- MaxQPSIPRule(unsigned int qps) : d_qps(qps) {}
+ MaxQPSIPRule(unsigned int qps, unsigned int ipv4trunc=32, unsigned int ipv6trunc=64) :
+ d_qps(qps), d_ipv4trunc(ipv4trunc), d_ipv6trunc(ipv6trunc)
+ {}
bool matches(const ComboAddress& remote, const DNSName& qname, uint16_t qtype, dnsheader* dh, int len) const override
{
ComboAddress zeroport(remote);
zeroport.sin4.sin_port=0;
+ zeroport.truncate(zeroport.sin4.sin_family == AF_INET ? d_ipv4trunc : d_ipv6trunc);
auto iter = d_limits.find(zeroport);
if(iter == d_limits.end()) {
iter=d_limits.insert({zeroport,QPSLimiter(d_qps, d_qps)}).first;
string toString() const override
{
- return "per IP match for QPS over " + std::to_string(d_qps);
+ return "IP (/"+std::to_string(d_ipv4trunc)+", /"+std::to_string(d_ipv6trunc)+") match for QPS over " + std::to_string(d_qps);
}
private:
mutable std::map<ComboAddress, QPSLimiter> d_limits;
- unsigned int d_qps;
+ unsigned int d_qps, d_ipv4trunc, d_ipv6trunc;
};