{ "leastOutstanding", false, "", "Send traffic to downstream server with least outstanding queries, with the lowest 'order', and within that the lowest recent latency"},
{ "LogAction", true, "[filename], [binary], [append], [buffered]", "Log a line for each query, to the specified file if any, to the console (require verbose) otherwise. When logging to a file, the `binary` optional parameter specifies whether we log in binary form (default) or in textual form, the `append` optional parameter specifies whether we open the file for appending or truncate each time (default), and the `buffered` optional parameter specifies whether writes to the file are buffered (default) or not." },
{ "makeKey", true, "", "generate a new server access key, emit configuration line ready for pasting" },
- { "MaxQPSIPRule", true, "qps, v4Mask=32, v6Mask=64", "matches traffic exceeding the qps limit per subnet" },
+ { "MaxQPSIPRule", true, "qps, v4Mask=32, v6Mask=64, burst=qps", "matches traffic exceeding the qps limit per subnet" },
{ "MaxQPSRule", true, "qps", "matches traffic **not** exceeding this qps limit" },
{ "mvCacheHitResponseRule", true, "from, to", "move cache hit response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule" },
{ "mvResponseRule", true, "from, to", "move response rule 'from' to a position where it is in front of 'to'. 'to' can be one larger than the largest rule" },
return std::shared_ptr<DNSAction>(new SkipCacheAction);
});
- 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)));
+ g_lua.writeFunction("MaxQPSIPRule", [](unsigned int qps, boost::optional<int> ipv4trunc, boost::optional<int> ipv6trunc, boost::optional<int> burst) {
+ return std::shared_ptr<DNSRule>(new MaxQPSIPRule(qps, burst.get_value_or(qps), ipv4trunc.get_value_or(32), ipv6trunc.get_value_or(64)));
});
Matches queries with the DO flag set
-.. function:: MaxQPSIPRule(qps[, v4Mask[, v6Mask]])
+.. function:: MaxQPSIPRule(qps[, v4Mask[, v6Mask[, burst]]])
- Matches traffic for a subnet specified by ``v4Mask`` or ``v6Mask`` exceeding ``qps`` queries per second
+ Matches traffic for a subnet specified by ``v4Mask`` or ``v6Mask`` exceeding ``qps`` queries per second upto ``burst`` allowed
:param int qps: The number of queries per second allowed, above this number traffic is matched
:param int v4Mask: The IPv4 netmask to match on. Default is 32 (the whole address)
:param int v6Mask: The IPv6 netmask to match on. Default is 64
+ :param int burst: The number of burstable queries per second allowed. Default is same as qps
.. function:: MaxQPSRule(qps)
class MaxQPSIPRule : public DNSRule
{
public:
- MaxQPSIPRule(unsigned int qps, unsigned int ipv4trunc=32, unsigned int ipv6trunc=64) :
- d_qps(qps), d_ipv4trunc(ipv4trunc), d_ipv6trunc(ipv6trunc)
+ MaxQPSIPRule(unsigned int qps, unsigned int burst, unsigned int ipv4trunc=32, unsigned int ipv6trunc=64) :
+ d_qps(qps), d_burst(burst), d_ipv4trunc(ipv4trunc), d_ipv6trunc(ipv6trunc)
{
pthread_rwlock_init(&d_lock, 0);
}
WriteLock w(&d_lock);
auto iter = d_limits.find(zeroport);
if(iter == d_limits.end()) {
- iter=d_limits.insert({zeroport,QPSLimiter(d_qps, d_qps)}).first;
+ iter=d_limits.insert({zeroport,QPSLimiter(d_qps, d_burst)}).first;
}
return !iter->second.check();
}
string toString() const override
{
- return "IP (/"+std::to_string(d_ipv4trunc)+", /"+std::to_string(d_ipv6trunc)+") 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) + " burst "+ std::to_string(d_burst);
}
private:
mutable pthread_rwlock_t d_lock;
mutable std::map<ComboAddress, QPSLimiter> d_limits;
- unsigned int d_qps, d_ipv4trunc, d_ipv6trunc;
+ unsigned int d_qps, d_burst, d_ipv4trunc, d_ipv6trunc;
};