From: Lennart Poettering Date: Thu, 20 Apr 2023 08:31:44 +0000 (+0200) Subject: ratelimit: handle counter overflows somewhat sanely X-Git-Tag: v254-rc1~675 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed6a6bac45e2674d5834510390cb2e5121bbb444;p=thirdparty%2Fsystemd.git ratelimit: handle counter overflows somewhat sanely An overflow here (i.e. the counter reaching 2^32 within a ratelimit time window) is not so unlikely. Let's handle this somewhat sanely and simply stop counting, while remaining in the "limit is hit" state until the time window has passed. --- diff --git a/src/basic/ratelimit.c b/src/basic/ratelimit.c index a0260bfe1c4..5675ec2f46b 100644 --- a/src/basic/ratelimit.c +++ b/src/basic/ratelimit.c @@ -10,7 +10,6 @@ bool ratelimit_below(RateLimit *r) { usec_t ts; - bool good = false; assert(r); @@ -21,22 +20,25 @@ bool ratelimit_below(RateLimit *r) { if (r->begin <= 0 || usec_sub_unsigned(ts, r->begin) > r->interval) { - r->begin = ts; + r->begin = ts; /* Start a new time window */ + r->num = 1; /* Reset counter */ + return true; + } - /* Reset counter */ - r->num = 0; - good = true; - } else if (r->num < r->burst) - good = true; + if (_unlikely_(r->num == UINT_MAX)) + return false; r->num++; - return good; + return r->num <= r->burst; } unsigned ratelimit_num_dropped(RateLimit *r) { assert(r); - return r->num > r->burst ? r->num - r->burst : 0; + if (r->num == UINT_MAX) /* overflow, return as special case */ + return UINT_MAX; + + return LESS_BY(r->num, r->burst); } usec_t ratelimit_end(const RateLimit *rl) {