From: Razvan Crainea <razvan@opensips.org>
Date: Wed, 7 Feb 2018 10:32:51 +0200
Subject: [PATCH] ratelimit: create pipe in a generic manner
Fix pipe init by merging the pipe create in a single, common function.
(cherry picked from commit d6933ad99ccfa20edbd375155a4b8e06b4e495a5)
(cherry picked from commit 4b29ec62eff1af6e4a2222d40bfa5cee8c43a64f)
diff --git a/modules/ratelimit/ratelimit_helper.c b/modules/ratelimit/ratelimit_helper.c
index 104b4a9f4..b6ab6f08d 100644
--- a/modules/ratelimit/ratelimit_helper.c
+++ b/modules/ratelimit/ratelimit_helper.c
@@ -312,6 +312,35 @@ int w_rl_check_2(struct sip_msg *_m, char *_n, char *_l)
return w_rl_check_3(_m, _n, _l, NULL);
}
+rl_pipe_t *rl_create_pipe(int limit, rl_algo_t algo)
+{
+ rl_pipe_t *pipe;
+ int size = sizeof(rl_pipe_t);
+
+ if (algo == PIPE_ALGO_NOP)
+ algo = rl_default_algo;
+
+ if (algo == PIPE_ALGO_HISTORY)
+ size += (rl_window_size * 1000) / rl_slot_period * sizeof(long int);
+
+ pipe = shm_malloc(size);
+ if (!pipe) {
+ LM_ERR("no more shm memory!\n");
+ return NULL;
+ }
+ memset(pipe, 0, size);
+
+ pipe->algo = algo;
+ pipe->limit = limit;
+
+ if (algo == PIPE_ALGO_HISTORY) {
+ pipe->rwin.window = (long int *)(pipe + 1);
+ pipe->rwin.window_size = (rl_window_size * 1000) / rl_slot_period;
+ /* everything else is already cleared */
+ }
+ return pipe;
+}
+
int w_rl_check_3(struct sip_msg *_m, char *_n, char *_l, char *_a)
{
str name;
@@ -376,23 +405,13 @@ int w_rl_check_3(struct sip_msg *_m, char *_n, char *_l, char *_a)
if (!*pipe) {
/* allocate new pipe */
- *pipe = shm_malloc(sizeof(rl_pipe_t) +
- /* memory for the window */
- (rl_window_size*1000) / rl_slot_period * sizeof(long int));
- if (!*pipe) {
- LM_ERR("no more shm memory\n");
+ if (!(*pipe = rl_create_pipe(limit, algo)))
goto release;
- }
- memset(*pipe, 0, sizeof(rl_pipe_t));
+
LM_DBG("Pipe %.*s doesn't exist, but was created %p\n",
name.len, name.s, *pipe);
- if (algo == PIPE_ALGO_NETWORK)
+ if ((*pipe)->algo == PIPE_ALGO_NETWORK)
should_update = 1;
- (*pipe)->algo = (algo == PIPE_ALGO_NOP) ? rl_default_algo : algo;
- (*pipe)->rwin.window = (long int *)((*pipe) + 1);
- (*pipe)->rwin.window_size = rl_window_size * 1000 / rl_slot_period;
- memset((*pipe)->rwin.window, 0,
- (*pipe)->rwin.window_size * sizeof(long int));
} else {
LM_DBG("Pipe %.*s found: %p - last used %lu\n",
name.len, name.s, *pipe, (*pipe)->last_used);
@@ -400,11 +419,10 @@ int w_rl_check_3(struct sip_msg *_m, char *_n, char *_l, char *_a)
LM_WARN("algorithm %d different from the initial one %d for pipe "
"%.*s", algo, (*pipe)->algo, name.len, name.s);
}
+ /* update the limit */
+ (*pipe)->limit = limit;
}
- /* set/update the limit */
- (*pipe)->limit = limit;
-
/* set the last used time */
(*pipe)->last_used = time(0);
if (RL_USE_CDB(*pipe)) {
@@ -890,17 +908,12 @@ void rl_rcv_bin(int packet_type, struct receive_info *ri, int server_id)
}
if (!*pipe) {
- /* if the pipe does not exist, alocate it in case we need it later */
- *pipe = shm_malloc(sizeof(rl_pipe_t));
- if (!*pipe) {
- LM_ERR("no more shm memory\n");
+ /* if the pipe does not exist, allocate it in case we need it later */
+ if (!(*pipe = rl_create_pipe(limit, algo)))
goto release;
- }
- memset(*pipe, 0, sizeof(rl_pipe_t));
LM_DBG("Pipe %.*s doesn't exist, but was created %p\n",
name.len, name.s, *pipe);
- (*pipe)->algo = algo;
- (*pipe)->limit = limit;
+
} else {
LM_DBG("Pipe %.*s found: %p - last used %lu\n",
name.len, name.s, *pipe, (*pipe)->last_used);
@@ -919,6 +932,8 @@ void rl_rcv_bin(int packet_type, struct receive_info *ri, int server_id)
(*pipe)->last_used = time(0);
/* set the destination's counter */
destination = find_destination(*pipe, server_id);
+ if (!destination)
+ goto release;
destination->counter = counter;
destination->update = now;
RL_RELEASE_LOCK(hash_idx);