Selaa lähdekoodia

modules_k/ratelimit Using ser's cfg framework for modifying module parameters at runtime(reply_code and reply_reason).

The patch allow reply_code and reply_reason to be modified using sercmd (modules/ctl/ctl.so and
modules/cfg_rpc/cfg_rpc.so must be loaded).Check module documentation for example.
Also it is interesting if we can modify at runtime other parameters of the module, like queue and pipe
Marius Zbihlei 15 vuotta sitten
vanhempi
commit
81ee9cdfdd

+ 32 - 20
modules_k/ratelimit/README

@@ -80,10 +80,12 @@ Hendrik Scholz
    1.2. Set queue parameter
    1.3. Set pipe parameter
    1.4. Set reply_code parameter
-   1.5. Set reply_reason parameter
-   1.6. rl_check usage
-   1.7. rl_check_pipe usage
-   1.8. rl_drop usage
+   1.5. Set reply_code parameter at runtime
+   1.6. Set reply_reason parameter
+   1.7. Set reply_reason parameter at runtime
+   1.8. rl_check usage
+   1.9. rl_check_pipe usage
+   1.10. rl_drop usage
 
 Chapter 1. Admin Guide
 
@@ -345,24 +347,34 @@ modparam("ratelimit", "pipe", "4:NETWORK:10000")
 modparam("ratelimit", "reply_code", 505)
 ...
 
+   This value cant be modified at runtime using sercmd
+
+   Example 1.5.  Set reply_code parameter at runtime
+sercmd cfg.set_now_int ratelimit reply_code 505
+
 6.5. reply_reason (string)
 
    The reason of the reply sent by Kamailio while limiting.
 
    Default value is "Server Unavailable".
 
-   Example 1.5. Set reply_reason parameter
+   Example 1.6. Set reply_reason parameter
 ...
 modparam("ratelimit", "reply_reason", "Limiting")
 ...
 
+   This value cant be modified at runtime using sercmd
+
+   Example 1.7.  Set reply_reason parameter at runtime
+sercmd cfg.set_now_string ratelimit reply_reason "Limiting"
+
 7. Exported Functions
 
    7.1. rl_check([pvar])
    7.2. rl_check_pipe([pipe_no])
    7.3. rl_drop([[min ], max])
 
-7.1. rl_check([pvar])
+7.1.  rl_check([pvar])
 
    Check the current request against the matched ratelimit algorithm. If
    no parameter is provided, the queue will be matched based on method
@@ -381,7 +393,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.6. rl_check usage
+   Example 1.8. rl_check usage
 ...
         # perform queue/pipe match for current method
         if (!rl_check()) {
@@ -406,7 +418,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
         };
 ...
 
-7.2. rl_check_pipe([pipe_no])
+7.2.  rl_check_pipe([pipe_no])
 
    Check the current request against the matched ratelimit algorithm. If
    no parameter is provided, the queue will be matched based on method
@@ -422,7 +434,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.7. rl_check_pipe usage
+   Example 1.9. rl_check_pipe usage
 ...
         # perform queue/pipe match for current method
         if (!rl_check_pipe()) {
@@ -437,7 +449,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
         };
 ...
 
-7.3. rl_drop([[min ], max])
+7.3.  rl_drop([[min ], max])
 
    For the current request, a "503 - Server Unavailable" reply is sent
    back. The reply may or may not have a "Retry-After" header. If no
@@ -453,7 +465,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.8. rl_drop usage
+   Example 1.10. rl_drop usage
 ...
         if (!rl_check()) {
                 # send back a "503 - Server Unavailable"
@@ -475,7 +487,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
    8.8. rl_push_load
    8.9. rl_set_dbg
 
-8.1. rl_stats
+8.1.  rl_stats
 
    Lists the parameters and variabiles in the ratelimit module.
 
@@ -487,7 +499,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 :rl_stats:_reply_fifo_file_
                 _empty_line_
 
-8.2. rl_set_pipe
+8.2.  rl_set_pipe
 
    Sets the pipe parameters for the given pipe id.
 
@@ -505,7 +517,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 10
                 _empty_line_
 
-8.3. rl_get_pipes
+8.3.  rl_get_pipes
 
    Gets the list of in use pipes.
 
@@ -517,7 +529,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 :rl_get_pipes:_reply_fifo_file_
                 _empty_line_
 
-8.4. rl_set_queue
+8.4.  rl_set_queue
 
    Sets the queue parameters for the given queue id.
 
@@ -535,7 +547,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 2
                 _empty_line_
 
-8.5. rl_get_queues
+8.5.  rl_get_queues
 
    Gets the list of in use queues.
 
@@ -547,7 +559,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 :rl_get_queues:_reply_fifo_file_
                 _empty_line_
 
-8.6. rl_set_pid
+8.6.  rl_set_pid
 
    Sets the PID Controller parameters for the Feedback Algorithm.
 
@@ -565,7 +577,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 0.5
                 _empty_line_
 
-8.7. rl_get_pid
+8.7.  rl_get_pid
 
    Gets the list of in use PID Controller parameters.
 
@@ -577,7 +589,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 :rl_get_pid:_reply_fifo_file_
                 _empty_line_
 
-8.8. rl_push_load
+8.8.  rl_push_load
 
    Force the value of the load parameter. This methos is usefull for
    testing the Feedback algorithm.
@@ -593,7 +605,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 0.85
                 _empty_line_
 
-8.9. rl_set_dbg
+8.9.  rl_set_dbg
 
    This MI function will enable/disable a WARNING debug log exposing the
    internal counters for each pipe (useful in monitoring the ratelimit

+ 52 - 0
modules_k/ratelimit/config.c

@@ -0,0 +1,52 @@
+/*
+ * $Id$
+ *
+ * Copyright (C) 2008 iptelorg GmbH
+ *
+ * This file is part of SIP-router, a free SIP server.
+ *
+ * SIP-router is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version
+ *
+ * SIP-router is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ *
+ * History
+ * -------
+ *  2008-02-05	adapting tm module for the configuration framework (Miklos)
+ */
+
+/*!
+ * \file 
+ * \brief TM :: Configuration
+ * \ingroup tm
+ */
+
+
+#include "../../cfg/cfg.h"
+#include "../../parser/msg_parser.h" /* method types */
+
+#include "config.h"
+
+struct cfg_group_ratelimit	default_ratelimit_cfg = {
+		DEFAULT_REPLY_CODE,
+		DEFAULT_REPLY_REASON
+};
+
+void	*ratelimit_cfg = &default_ratelimit_cfg;
+
+cfg_def_t	ratelimit_cfg_def[] = {
+	{"reply_code",	CFG_VAR_INT | CFG_ATOMIC,	400, 699, 0, 0,
+		"The code of the reply sent by Kamailio while limiting." },
+	{"reply_reason",	CFG_VAR_STRING,	0, 0, 0, 0,
+		"The reason of the reply sent by Kamailio while limiting."},
+	{0, 0, 0, 0, 0, 0}
+};

+ 41 - 0
modules_k/ratelimit/config.h

@@ -0,0 +1,41 @@
+/*
+ * $Id$
+ *
+ * SIP-router is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License 
+ * along with this program; if not, write to the Free Software 
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ */
+
+/*!
+ * \file 
+ * \brief Ratelimit :: Configuration
+ * \ingroup ratelimit
+ */
+
+
+#ifndef _RATELIMIT_CONFIG_H
+#define _RATELIMIT_CONFIG_H
+
+
+#include "../../cfg/cfg.h"
+#include "../../str.h"
+
+
+#define DEFAULT_REPLY_CODE 503
+#define DEFAULT_REPLY_REASON "Server Unavailable"
+
+struct cfg_group_ratelimit {
+	unsigned int	reply_code;
+	char*		reply_reason;
+};
+
+extern struct cfg_group_ratelimit	default_ratelimit_cfg;
+extern void	*ratelimit_cfg;
+extern cfg_def_t	ratelimit_cfg_def[];
+
+#endif

+ 23 - 1
modules_k/ratelimit/doc/ratelimit_admin.xml

@@ -273,6 +273,7 @@ modparam("ratelimit", "pipe", "4:NETWORK:10000")
 		<emphasis>
 			Default value is 503.
 		</emphasis>
+
 		</para>
 		<example>
 		<title>Set <varname>reply_code</varname> parameter</title>
@@ -282,6 +283,17 @@ modparam("ratelimit", "reply_code", 505)
 ...
 </programlisting>
 		</example>
+		<para>
+		This value cant be modified at runtime using sercmd
+		</para>
+		<example>
+		<title> Set <varname>reply_code</varname> parameter at runtime </title>
+		<programlisting format="linespecific">
+
+sercmd cfg.set_now_int ratelimit reply_code 505
+
+		</programlisting>
+		</example>
 	</section>
 	<section>
 		<title><varname>reply_reason</varname> (string)</title>
@@ -301,6 +313,17 @@ modparam("ratelimit", "reply_reason", "Limiting")
 ...
 </programlisting>
 		</example>
+		<para>
+		This value cant be modified at runtime using sercmd
+		</para>
+		<example>
+		<title> Set <varname>reply_reason</varname> parameter at runtime </title>
+		<programlisting format="linespecific">
+
+sercmd cfg.set_now_string ratelimit reply_reason "Limiting"
+
+		</programlisting>
+		</example>
 	</section>
 	</section>
 	<section>
@@ -700,4 +723,3 @@ modparam("ratelimit", "reply_reason", "Limiting")
 	</para>
 	</section>
 </chapter>
-

+ 25 - 10
modules_k/ratelimit/ratelimit.c

@@ -35,6 +35,7 @@
 #include <regex.h>
 #include <math.h>
 
+
 #include "../../mem/mem.h"
 #include "../../mem/shm_mem.h"
 #include "../../sr_module.h"
@@ -51,6 +52,8 @@
 #include "../../lib/kcore/km_ut.h"
 #include "../../lib/kmi/mi.h"
 
+#include "config.h"
+
 MODULE_VERSION
 
 #define MAX_PIPES       16
@@ -101,6 +104,7 @@ str_map_t algo_names[] = {
 	{{0, 0},		0},
 };
 
+
 /* at [email protected]'s suggestion:
  *
  * set this to 'cpu' to have openser look at /proc/stat every time_interval
@@ -118,8 +122,6 @@ str_map_t source_names[] = {
 	{{0, 0},		0},
 };
 
-static int rl_drop_code = 503;
-static str rl_drop_reason = str_init("Server Unavailable");
 
 typedef struct pipe {
 	/* stuff that gets read as a modparam or set via fifo */
@@ -231,8 +233,8 @@ static param_export_t params[]={
 	{"timer_interval", INT_PARAM,                &timer_interval},
 	{"queue",          STR_PARAM|USE_FUNC_PARAM, (void *)add_queue_params},
 	{"pipe",           STR_PARAM|USE_FUNC_PARAM, (void *)add_pipe_params},
-	{"reply_code",     INT_PARAM,                &rl_drop_code},
-	{"reply_reason",   STR_PARAM,                &rl_drop_reason.s},
+	{"reply_code",     INT_PARAM,                &default_ratelimit_cfg.reply_code},
+	{"reply_reason",   STR_PARAM,                &default_ratelimit_cfg.reply_reason},
 	/* RESERVED for future use
 	{"load_source",    STR_PARAM|USE_FUNC_PARAM, (void *)set_load_source},
 	*/
@@ -516,6 +518,13 @@ static int mod_init(void)
 		return -1;
 	}
 
+	/* load configurations*/
+	if( cfg_declare("ratelimit", ratelimit_cfg_def, &default_ratelimit_cfg, cfg_sizeof(ratelimit), 
+		&ratelimit_cfg )){
+		LM_ERR("failed to declare the configuration");
+		return -1;
+	}
+	
 	*network_load_value = 0;
 	*load_value = 0.0;
 	*load_source = load_source_mp;
@@ -587,8 +596,6 @@ static int mod_init(void)
 		queues[i].method_mp.len = 0;
 	}
 
-	rl_drop_reason.len = strlen(rl_drop_reason.s);
-
 	return 0;
 }
 
@@ -703,10 +710,19 @@ static int rl_drop(struct sip_msg * msg, unsigned int low, unsigned int high)
 {
 	str hdr;
 	int ret;
-
+	int drop_code;
+	str drop_reason;
+	
 	LM_DBG("(%d, %d)\n", low, high);
 
 	if (slb.send_reply != 0) {
+		if ( (drop_code = cfg_get(ratelimit, ratelimit_cfg, reply_code)) == 0 )
+			drop_code = DEFAULT_REPLY_CODE;
+		
+		if ( (drop_reason.s = cfg_get(ratelimit, ratelimit_cfg, reply_reason)) == 0 )
+			drop_reason.s = DEFAULT_REPLY_REASON;
+		drop_reason.len = strlen(drop_reason.s);
+
 		if (low != 0 && high != 0) {
 			hdr.s = (char *)pkg_malloc(64);
 			if (hdr.s == 0) {
@@ -731,12 +747,11 @@ static int rl_drop(struct sip_msg * msg, unsigned int low, unsigned int high)
 				pkg_free(hdr.s);
 				return 0;
 			}
-
-			ret = slb.send_reply(msg, rl_drop_code, &rl_drop_reason);
+			ret = slb.send_reply(msg, drop_code, &drop_reason);
 
 			pkg_free(hdr.s);
 		} else {
-			ret = slb.send_reply(msg, rl_drop_code, &rl_drop_reason);
+			ret = slb.send_reply(msg, drop_code, &drop_reason);
 		}
 	} else {
 		LM_ERR("Can't send reply\n");