aboutsummaryrefslogtreecommitdiffstats
path: root/src/fuzzy_storage.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rspamd.com>2023-07-01 14:28:43 +0100
committerVsevolod Stakhov <vsevolod@rspamd.com>2023-07-01 14:28:43 +0100
commit53e550245b27cdcd156f03593c7e0e083c0616bc (patch)
treec3bfb3e3d4f4b8155bedfba97c1dfe6c1f2d4a5f /src/fuzzy_storage.c
parent845ae26f6ae5c1bac83fdf49ad7b9ef34482a9a5 (diff)
downloadrspamd-53e550245b27cdcd156f03593c7e0e083c0616bc.tar.gz
rspamd-53e550245b27cdcd156f03593c7e0e083c0616bc.zip
[Minor] Do not block rate limit elements in fuzzy forever
Diffstat (limited to 'src/fuzzy_storage.c')
-rw-r--r--src/fuzzy_storage.c21
1 files changed, 17 insertions, 4 deletions
diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c
index 31a2c46e6..7747f6342 100644
--- a/src/fuzzy_storage.c
+++ b/src/fuzzy_storage.c
@@ -276,11 +276,23 @@ rspamd_fuzzy_check_ratelimit (struct fuzzy_session *session)
gboolean ratelimited = FALSE, new_ratelimit = FALSE;
if (isnan (elt->cur)) {
- /* Ratelimit exceeded, preserve it for the whole ttl */
- ratelimited = TRUE;
+ /* There is an issue with the previous logic: the TTL is updated each time
+ * we see that new bucket. Hence, we need to check the `last` and act accordingly
+ */
+ if (elt->last < session->timestamp && session->timestamp - elt->last >= session->ctx->leaky_bucket_ttl) {
+ /*
+ * We reset bucket to it's 90% capacity to allow some requests
+ * This should cope with the issue when we block an IP network for some burst and never unblock it
+ */
+ elt->cur = session->ctx->leaky_bucket_burst * 0.9;
+ elt->last = session->timestamp;
+ }
+ else {
+ ratelimited = TRUE;
+ }
}
else {
- /* Update bucket */
+ /* Update bucket: leak some elements */
if (elt->last < session->timestamp) {
elt->cur -= session->ctx->leaky_bucket_rate * (session->timestamp - elt->last);
elt->last = session->timestamp;
@@ -293,7 +305,7 @@ rspamd_fuzzy_check_ratelimit (struct fuzzy_session *session)
elt->last = session->timestamp;
}
- /* Check bucket */
+ /* Check the bucket */
if (elt->cur >= session->ctx->leaky_bucket_burst) {
msg_info ("ratelimiting %s (%s), %.1f max elts",
@@ -302,6 +314,7 @@ rspamd_fuzzy_check_ratelimit (struct fuzzy_session *session)
session->ctx->leaky_bucket_burst);
elt->cur = NAN;
new_ratelimit = TRUE;
+ ratelimited = TRUE;
}
else {
elt->cur ++; /* Allow one more request */