I am reading https://kamailio.org/docs/modules/devel/modules/ratelimit.html and I want Kamailio, before an avalanche of calls (INVITE), to start discarding calls that exceed a threshold in 1 second, for example. So in summary I have prepared the module as follows:
loadmodule "ratelimit.so" modparam("ratelimit", "timer_interval",1) modparam("ratelimit", "pipe", "1:TAILDROP:10")
request_route { . . if (is_method("INVITE")) { if (!rl_check_pipe("1")) { sl_send_reply("503","Limiting"); exit; } } . . }
As I understand from the documentation, this gives me a counter (one per INVITE) equal to 10, which resets after 1 second. In other words, if I receive 30 INVITES in 1 second, it will discard 20.
From here, I have two questions between what I understand and what I see in the logs.
FIRST QUESTION: I've made several SIPP calls in one second. I've run several tests, and the first reset of the counter always happens approximately timer_interval/2. From then on, the counter resets exactly every timer_interval. Am I doing something wrong?
########## RUNNING LOGS ########## 2025-03-26T18:59:20.509696381Z 0(1) DEBUG: <core> [core/cfg.y:2165]: yyparse(): loading module ratelimit.so 2025-03-26T18:59:20.509698675Z 0(1) DEBUG: <core> [core/sr_module.c:533]: ksr_locate_module(): found module to load </usr/lib/kamailio/modules/ratelimit.so> 2025-03-26T18:59:20.509702249Z 0(1) DEBUG: <core> [core/sr_module.c:587]: ksr_load_module(): trying to load </usr/lib/kamailio/modules/ratelimit.so> 2025-03-26T18:59:20.509704682Z 0(1) DEBUG: <core> [core/kemi.c:3463]: sr_kemi_modules_add(): adding module: ratelimit 2025-03-26T18:59:20.509707031Z 0(1) DEBUG: <core> [core/cfg.lex:2095]: pp_define(): defining id: MOD_ratelimit 2025-03-26T18:59:20.509815384Z 0(1) DEBUG: <core> [core/modparam.c:112]: set_mod_param_regex(): 'ratelimit' matches module 'ratelimit' 2025-03-26T18:59:20.509817770Z 0(1) DEBUG: <core> [core/sr_module.c:850]: find_param_export(): found <timer_interval> in module ratelimit [/usr/lib/kamailio/modules/ratelimit.so] 2025-03-26T18:59:20.509820319Z 0(1) DEBUG: <core> [core/modparam.c:135]: set_mod_param_regex(): found <timer_interval> in module ratelimit [/usr/lib/kamailio/modules/ratelimit.so] 2025-03-26T18:59:20.509822755Z 0(1) DEBUG: <core> [core/modparam.c:112]: set_mod_param_regex(): 'ratelimit' matches module 'ratelimit' 2025-03-26T18:59:20.509825068Z 0(1) DEBUG: <core> [core/sr_module.c:850]: find_param_export(): found <pipe> in module ratelimit [/usr/lib/kamailio/modules/ratelimit.so] 2025-03-26T18:59:20.509827468Z 0(1) DEBUG: <core> [core/modparam.c:135]: set_mod_param_regex(): found <pipe> in module ratelimit [/usr/lib/kamailio/modules/ratelimit.so] 2025-03-26T18:59:20.509829943Z 0(1) DEBUG: ratelimit [ratelimit.c:925]: parse_pipe_params(): pipe: [1|TAILDROP|10] 2025-03-26T18:59:20.510800378Z 0(1) DEBUG: <core> [core/sr_module.c:758]: find_mod_export_record(): found export of <rl_check_pipe> in module ratelimit [/usr/lib/kamailio/modules/ratelimit.so] 2025-03-26T18:59:20.519776933Z 0(1) DEBUG: <core> [core/sr_module.c:1031]: init_mod(): ratelimit
########## LOGS WHEN APPLY RATELIMIT ########## 2025-03-26T19:01:02.095676663Z 1(7) DEBUG: {1 1 INVITE 1-1@192.168.100.15} ratelimit [ratelimit.c:861]: w_rl_check_forced_pipe(): trying pipe 1 2025-03-26T19:01:02.095679040Z 1(7) DEBUG: {1 1 INVITE 1-1@192.168.100.15} ratelimit [ratelimit.c:830]: rl_check(): meth=INVITE queue=0 pipe=1 algo=2 limit=10 pkg_load=0 counter=1 load=0.0 network_load=0 => ACCEPT . . 2025-03-26T19:01:02.272879226Z 2(8) DEBUG: {1 1 INVITE 10-1@192.168.100.15} ratelimit [ratelimit.c:861]: w_rl_check_forced_pipe(): trying pipe 1 2025-03-26T19:01:02.272881671Z 2(8) DEBUG: {1 1 INVITE 10-1@192.168.100.15} ratelimit [ratelimit.c:830]: rl_check(): meth=INVITE queue=0 pipe=1 algo=2 limit=10 pkg_load=0 counter=10 load=0.0 network_load=0 => ACCEPT 2025-03-26T19:01:02.292599816Z 2(8) DEBUG: {1 1 INVITE 11-1@192.168.100.15} ratelimit [ratelimit.c:861]: w_rl_check_forced_pipe(): trying pipe 1 2025-03-26T19:01:02.292602425Z 2(8) DEBUG: {1 1 INVITE 11-1@192.168.100.15} ratelimit [ratelimit.c:830]: rl_check(): meth=INVITE queue=0 pipe=1 algo=2 limit=10 pkg_load=0 counter=11 load=0.0 network_load=0 => DROP . . 2025-03-26T19:01:02.492680874Z 1(7) DEBUG: {1 1 INVITE 21-1@192.168.100.15} ratelimit [ratelimit.c:861]: w_rl_check_forced_pipe(): trying pipe 1 2025-03-26T19:01:02.492694107Z 1(7) DEBUG: {1 1 INVITE 21-1@192.168.100.15} ratelimit [ratelimit.c:830]: rl_check(): meth=INVITE queue=0 pipe=1 algo=2 limit=10 pkg_load=0 counter=21 load=0.0 network_load=0 => DROP 2025-03-26T19:01:02.513079779Z 2(8) DEBUG: {1 1 INVITE 22-1@192.168.100.15} ratelimit [ratelimit.c:861]: w_rl_check_forced_pipe(): trying pipe 1 2025-03-26T19:01:02.513088852Z 2(8) DEBUG: {1 1 INVITE 22-1@192.168.100.15} ratelimit [ratelimit.c:830]: rl_check(): meth=INVITE queue=0 pipe=1 algo=2 limit=10 pkg_load=0 counter=22 load=0.0 network_load=0 => DROP 2025-03-26T19:01:02.532804253Z 1(7) DEBUG: {1 1 INVITE 23-1@192.168.100.15} ratelimit [ratelimit.c:861]: w_rl_check_forced_pipe(): trying pipe 1 2025-03-26T19:01:02.532808087Z 1(7) DEBUG: {1 1 INVITE 23-1@192.168.100.15} ratelimit [ratelimit.c:830]: rl_check(): meth=INVITE queue=0 pipe=1 algo=2 limit=10 pkg_load=2 counter=1 load=0.1 network_load=0 => ACCEPT
When the countdown restarts, it's "19:01:02.53" hours, and when it started, it was "19:01:02.09" hours. It doesn't reach the second. The drop system works well, but if my limit was 25 calls, I would have accepted the 22 I counted in the first second, plus the other 25 from the second number 2.
Second question:
There's a warning about a performance penalty in Kamailio when timer_interval is too small, so I've decided to set it to 2 just for practical purposes.
So what should happen is that the counter would accept up to 10 calls in 2 seconds. But in the logs, what I see is the opposite: it accepts 20 calls in 2 seconds. Maybe it's supposed to work that way, and I'm misunderstanding the documentation?
As optional information: Kamailio is running on a Google virtual machine, 12MB of RAM, 3 processors, 2 of which are dedicated. I'm using SIPP for load testing, and different call rates have been validated before testing the module.
Sorry if my first post in this community was too long or is there more information missing :) . Thanks in advance