diff options
author | Lennart Poettering <lennart@poettering.net> | 2023-04-20 10:31:44 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2023-04-20 13:39:06 +0200 |
commit | ed6a6bac45e2674d5834510390cb2e5121bbb444 (patch) | |
tree | 2fe25d7f3a5b82d8b6b4904a70dcfc3ccf2ae61b /src/basic/ratelimit.c | |
parent | man: try to make clearer that /var/ is generally not available in /usr/lib/sy... (diff) | |
download | systemd-ed6a6bac45e2674d5834510390cb2e5121bbb444.tar.xz systemd-ed6a6bac45e2674d5834510390cb2e5121bbb444.zip |
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.
Diffstat (limited to 'src/basic/ratelimit.c')
-rw-r--r-- | src/basic/ratelimit.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/src/basic/ratelimit.c b/src/basic/ratelimit.c index a0260bfe1c..5675ec2f46 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) { |