From 377ba7fe295f22d8c7d0ab13c2239b8eab29f3cb Mon Sep 17 00:00:00 2001 From: Liviu Chircu Date: Fri, 13 Sep 2024 15:51:59 +0300 Subject: [PATCH] ratelimit: Avoid replicating "zero" pipes excessively This patch makes it so any time a pipe's `.counter` value reaches 0, it will only get broadcasted to neighbouring cluster nodes exactly 3 more times, after which it will be completely skipped from being included in the replication packet. This counter is then reset to 3 as soon as the pipe's value is incremented locally. --- modules/ratelimit/ratelimit.h | 1 + modules/ratelimit/ratelimit_helper.c | 12 +++++++----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/ratelimit/ratelimit.h b/modules/ratelimit/ratelimit.h index 50efd98e803..e36a3e45bdd 100644 --- a/modules/ratelimit/ratelimit.h +++ b/modules/ratelimit/ratelimit.h @@ -95,6 +95,7 @@ typedef struct rl_pipe { time_t last_used; /* timestamp when the pipe was last accessed */ time_t last_local_used; /* timestamp when the pipe was last locally accessed */ rl_repl_counter_t *dsts; /* counters per destination */ + int repl_zero_cnt; /* only broadcast a zero counter N times */ rl_window_t rwin; /* window of requests */ } rl_pipe_t; diff --git a/modules/ratelimit/ratelimit_helper.c b/modules/ratelimit/ratelimit_helper.c index 65aaaa8dea2..ae4653b1a33 100644 --- a/modules/ratelimit/ratelimit_helper.c +++ b/modules/ratelimit/ratelimit_helper.c @@ -486,6 +486,7 @@ int w_rl_check(struct sip_msg *_m, str *name, int *limit, str *algorithm) } } else { pipe->counter++; + pipe->repl_zero_cnt = 3; } ret = rl_pipe_check(pipe); @@ -1057,11 +1058,12 @@ void rl_timer_repl(utime_t ticks, void *param) LM_ERR("[BUG] bogus map[%d] state\n", i); goto next_pipe; } - if (!RL_USE_BIN(pipe)) - goto next_pipe; - - /* do not replicate if about to expire */ - if (pipe->last_local_used + rl_expire_time < now) + /* ignore cachedb replicated stuff */ + if (!RL_USE_BIN(pipe) + /* ... or pipes with value: 0 after 'cnt' broadcasts */ + || (pipe->counter == 0 && pipe->repl_zero_cnt-- <= 0) + /* ... and do not replicate if about to expire */ + || pipe->last_local_used + rl_expire_time < now) goto next_pipe; key = iterator_key(&it);