Blob Blame Raw
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);