浏览代码

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 年之前
父节点
当前提交
81ee9cdfdd

+ 32 - 20
modules_k/ratelimit/README

@@ -80,10 +80,12 @@ Hendrik Scholz
    1.2. Set queue parameter
    1.2. Set queue parameter
    1.3. Set pipe parameter
    1.3. Set pipe parameter
    1.4. Set reply_code 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
 Chapter 1. Admin Guide
 
 
@@ -345,24 +347,34 @@ modparam("ratelimit", "pipe", "4:NETWORK:10000")
 modparam("ratelimit", "reply_code", 505)
 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)
 6.5. reply_reason (string)
 
 
    The reason of the reply sent by Kamailio while limiting.
    The reason of the reply sent by Kamailio while limiting.
 
 
    Default value is "Server Unavailable".
    Default value is "Server Unavailable".
 
 
-   Example 1.5. Set reply_reason parameter
+   Example 1.6. Set reply_reason parameter
 ...
 ...
 modparam("ratelimit", "reply_reason", "Limiting")
 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. Exported Functions
 
 
    7.1. rl_check([pvar])
    7.1. rl_check([pvar])
    7.2. rl_check_pipe([pipe_no])
    7.2. rl_check_pipe([pipe_no])
    7.3. rl_drop([[min ], max])
    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
    Check the current request against the matched ratelimit algorithm. If
    no parameter is provided, the queue will be matched based on method
    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.
    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
         # perform queue/pipe match for current method
         if (!rl_check()) {
         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
    Check the current request against the matched ratelimit algorithm. If
    no parameter is provided, the queue will be matched based on method
    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.
    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
         # perform queue/pipe match for current method
         if (!rl_check_pipe()) {
         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
    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
    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.
    This function can be used from REQUEST_ROUTE.
 
 
-   Example 1.8. rl_drop usage
+   Example 1.10. rl_drop usage
 ...
 ...
         if (!rl_check()) {
         if (!rl_check()) {
                 # send back a "503 - Server Unavailable"
                 # send back a "503 - Server Unavailable"
@@ -475,7 +487,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
    8.8. rl_push_load
    8.8. rl_push_load
    8.9. rl_set_dbg
    8.9. rl_set_dbg
 
 
-8.1. rl_stats
+8.1.  rl_stats
 
 
    Lists the parameters and variabiles in the ratelimit module.
    Lists the parameters and variabiles in the ratelimit module.
 
 
@@ -487,7 +499,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 :rl_stats:_reply_fifo_file_
                 :rl_stats:_reply_fifo_file_
                 _empty_line_
                 _empty_line_
 
 
-8.2. rl_set_pipe
+8.2.  rl_set_pipe
 
 
    Sets the pipe parameters for the given pipe id.
    Sets the pipe parameters for the given pipe id.
 
 
@@ -505,7 +517,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 10
                 10
                 _empty_line_
                 _empty_line_
 
 
-8.3. rl_get_pipes
+8.3.  rl_get_pipes
 
 
    Gets the list of in use pipes.
    Gets the list of in use pipes.
 
 
@@ -517,7 +529,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 :rl_get_pipes:_reply_fifo_file_
                 :rl_get_pipes:_reply_fifo_file_
                 _empty_line_
                 _empty_line_
 
 
-8.4. rl_set_queue
+8.4.  rl_set_queue
 
 
    Sets the queue parameters for the given queue id.
    Sets the queue parameters for the given queue id.
 
 
@@ -535,7 +547,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 2
                 2
                 _empty_line_
                 _empty_line_
 
 
-8.5. rl_get_queues
+8.5.  rl_get_queues
 
 
    Gets the list of in use queues.
    Gets the list of in use queues.
 
 
@@ -547,7 +559,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 :rl_get_queues:_reply_fifo_file_
                 :rl_get_queues:_reply_fifo_file_
                 _empty_line_
                 _empty_line_
 
 
-8.6. rl_set_pid
+8.6.  rl_set_pid
 
 
    Sets the PID Controller parameters for the Feedback Algorithm.
    Sets the PID Controller parameters for the Feedback Algorithm.
 
 
@@ -565,7 +577,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 0.5
                 0.5
                 _empty_line_
                 _empty_line_
 
 
-8.7. rl_get_pid
+8.7.  rl_get_pid
 
 
    Gets the list of in use PID Controller parameters.
    Gets the list of in use PID Controller parameters.
 
 
@@ -577,7 +589,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 :rl_get_pid:_reply_fifo_file_
                 :rl_get_pid:_reply_fifo_file_
                 _empty_line_
                 _empty_line_
 
 
-8.8. rl_push_load
+8.8.  rl_push_load
 
 
    Force the value of the load parameter. This methos is usefull for
    Force the value of the load parameter. This methos is usefull for
    testing the Feedback algorithm.
    testing the Feedback algorithm.
@@ -593,7 +605,7 @@ modparam("ratelimit", "reply_reason", "Limiting")
                 0.85
                 0.85
                 _empty_line_
                 _empty_line_
 
 
-8.9. rl_set_dbg
+8.9.  rl_set_dbg
 
 
    This MI function will enable/disable a WARNING debug log exposing the
    This MI function will enable/disable a WARNING debug log exposing the
    internal counters for each pipe (useful in monitoring the ratelimit
    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>
 		<emphasis>
 			Default value is 503.
 			Default value is 503.
 		</emphasis>
 		</emphasis>
+
 		</para>
 		</para>
 		<example>
 		<example>
 		<title>Set <varname>reply_code</varname> parameter</title>
 		<title>Set <varname>reply_code</varname> parameter</title>
@@ -282,6 +283,17 @@ modparam("ratelimit", "reply_code", 505)
 ...
 ...
 </programlisting>
 </programlisting>
 		</example>
 		</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>
 	<section>
 	<section>
 		<title><varname>reply_reason</varname> (string)</title>
 		<title><varname>reply_reason</varname> (string)</title>
@@ -301,6 +313,17 @@ modparam("ratelimit", "reply_reason", "Limiting")
 ...
 ...
 </programlisting>
 </programlisting>
 		</example>
 		</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>
 	</section>
 	<section>
 	<section>
@@ -700,4 +723,3 @@ modparam("ratelimit", "reply_reason", "Limiting")
 	</para>
 	</para>
 	</section>
 	</section>
 </chapter>
 </chapter>
-

+ 25 - 10
modules_k/ratelimit/ratelimit.c

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