commit 53e5502: [Minor] Do not block rate limit elements in fuzzy forever

Vsevolod Stakhov vsevolod at rspamd.com
Sat Jul 1 15:49:04 UTC 2023


Author: Vsevolod Stakhov
Date: 2023-07-01 14:28:43 +0100
URL: https://github.com/rspamd/rspamd/commit/53e550245b27cdcd156f03593c7e0e083c0616bc

[Minor] Do not block rate limit elements in fuzzy forever

---
 src/fuzzy_storage.c | 21 +++++++++++++++++----
 1 file 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 */


More information about the Commits mailing list