From: Remi Gacogne Date: Fri, 10 Feb 2023 15:17:56 +0000 (+0100) Subject: dnsdist: Prevent duplicated cleanup in MaxQPSIPRule() X-Git-Tag: dnsdist-1.8.0-rc1~24^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e87c68608117846a91e7d275394458f343fe304d;p=thirdparty%2Fpdns.git dnsdist: Prevent duplicated cleanup in MaxQPSIPRule() --- diff --git a/pdns/dnsdistdist/dnsdist-rules.hh b/pdns/dnsdistdist/dnsdist-rules.hh index 13ffe52318..c452f9d346 100644 --- a/pdns/dnsdistdist/dnsdist-rules.hh +++ b/pdns/dnsdistdist/dnsdist-rules.hh @@ -40,6 +40,7 @@ public: MaxQPSIPRule(unsigned int qps, unsigned int burst, unsigned int ipv4trunc=32, unsigned int ipv6trunc=64, unsigned int expiration=300, unsigned int cleanupDelay=60, unsigned int scanFraction=10): d_qps(qps), d_burst(burst), d_ipv4trunc(ipv4trunc), d_ipv6trunc(ipv6trunc), d_cleanupDelay(cleanupDelay), d_expiration(expiration), d_scanFraction(scanFraction) { + d_cleaningUp.clear(); gettime(&d_lastCleanup, true); } @@ -83,13 +84,23 @@ public: cutOff.tv_sec += d_cleanupDelay; if (cutOff < now) { - /* the QPS Limiter doesn't use realtime, be careful! */ - gettime(&cutOff, false); - cutOff.tv_sec -= d_expiration; - - cleanup(cutOff); - - d_lastCleanup = now; + try { + if (d_cleaningUp.test_and_set()) { + return; + } + + d_lastCleanup = now; + /* the QPS Limiter doesn't use realtime, be careful! */ + gettime(&cutOff, false); + cutOff.tv_sec -= d_expiration; + + cleanup(cutOff); + d_cleaningUp.clear(); + } + catch (...) { + d_cleaningUp.clear(); + throw; + } } } } @@ -148,6 +159,7 @@ private: mutable struct timespec d_lastCleanup; unsigned int d_qps, d_burst, d_ipv4trunc, d_ipv6trunc, d_cleanupDelay, d_expiration; unsigned int d_scanFraction{10}; + mutable std::atomic_flag d_cleaningUp; }; class MaxQPSRule : public DNSRule