Explorar o código

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 %!s(int64=15) %!d(string=hai) anos
pai
achega
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");