浏览代码

Merge branch 'master' of ssh://git.sip-router.org/sip-router into 32plus

* 'master' of ssh://git.sip-router.org/sip-router:
  dialog(k): Note dependency between dlg_manage() and transactions in docs.
  snmpstats: control exporting registrar records
  ctl: used flavour's NAME in path of default ctl socket
  modules_k/(auth|misc)_radius: added cast
  kamailio.cfg: added storage of src ip to extra acc example
  kamailio.cfg: load cfg_rpc module to allow runtime updates
  cfg_rpc: improved documentation
  modules_k/osp, modules_k/siputils: The bind_siputils function takes 1 parameter, but the bind command in here (and as used in osp) was specified as taking 0 parameters.
  modules_k/presence_xml: The presentity activities check wasn't quite right.
  modules_k/dispatcher: Fixes to handling of empty DB and hostnames that cannot be resolved
  modules/app_lua: Fix to lua_sr_pv_is_null()
  modules:sipcapture: fixed uint types and IPPROTO_IPIP on Solaris.
  core: auto_bind_ipv6 : changed param from cfg framework to normal global parameter as setting it at run time doesn't change anything
  core: added parameter to enable/disable automatic binding of ipv6 interfaces TODO: documentation
  core:socket_info Added automatic discovery of IPv6 interfaces on Linux using RT_NETLINK socks
  dialog(k): Fix typos.
  Revert "message shooter module added"
Juha Heinanen 14 年之前
父节点
当前提交
bee7574aed

+ 4 - 0
cfg.lex

@@ -370,6 +370,8 @@ DNS_CACHE_MAX_TTL	dns_cache_max_ttl
 DNS_CACHE_MEM		dns_cache_mem
 DNS_CACHE_GC_INT	dns_cache_gc_interval
 DNS_CACHE_DEL_NONEXP	dns_cache_del_nonexp|dns_cache_delete_nonexpired
+/* ipv6 auto bind */
+AUTO_BIND_IPV6		auto_bind_ipv6
 /* blacklist */
 DST_BLST_INIT	dst_blacklist_init
 USE_DST_BLST		use_dst_blacklist
@@ -751,6 +753,8 @@ IMPORTFILE      "import_file"
 								return DNS_CACHE_GC_INT; }
 <INITIAL>{DNS_CACHE_DEL_NONEXP}	{ count(); yylval.strval=yytext;
 								return DNS_CACHE_DEL_NONEXP; }
+<INITIAL>{AUTO_BIND_IPV6}	{ count(); yylval.strval=yytext;
+								return AUTO_BIND_IPV6; }
 <INITIAL>{DST_BLST_INIT}	{ count(); yylval.strval=yytext;
 								return DST_BLST_INIT; }
 <INITIAL>{USE_DST_BLST}	{ count(); yylval.strval=yytext;

+ 11 - 0
cfg.y

@@ -164,6 +164,11 @@
 		if (rt!=ONSEND_ROUTE) yyerror( s " allowed only in onsend_routes");\
 	}while(0)
 
+#ifdef USE_IPV6
+	#define IF_AUTO_BIND_IPV6(x) x
+#else
+	#define IF_AUTO_BIND_IPV6(x) warn("IPV6 support not compiled");
+#endif
 
 #ifdef USE_DNS_CACHE
 	#define IF_DNS_CACHE(x) x
@@ -419,6 +424,10 @@ extern char *finame;
 %token DNS_CACHE_MEM
 %token DNS_CACHE_GC_INT
 %token DNS_CACHE_DEL_NONEXP
+
+/* ipv6 auto bind */
+%token AUTO_BIND_IPV6
+
 /*blacklist*/
 %token DST_BLST_INIT
 %token USE_DST_BLST
@@ -877,6 +886,8 @@ assign_stm:
 	| DNS_CACHE_GC_INT error { yyerror("boolean value expected"); }
 	| DNS_CACHE_DEL_NONEXP EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_del_nonexp=$3); }
 	| DNS_CACHE_DEL_NONEXP error { yyerror("boolean value expected"); }
+	| AUTO_BIND_IPV6 EQUAL NUMBER {IF_AUTO_BIND_IPV6(auto_bind_ipv6 = $3);}
+	| AUTO_BIND_IPV6 error { yyerror("boolean value expected"); }
 	| DST_BLST_INIT EQUAL NUMBER   { IF_DST_BLACKLIST(dst_blacklist_init=$3); }
 	| DST_BLST_INIT error { yyerror("boolean value expected"); }
 	| USE_DST_BLST EQUAL NUMBER {

+ 11 - 5
etc/kamailio.cfg

@@ -87,11 +87,13 @@
 #!ifdef ACCDB_COMMENT
   ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
+  ALTER TABLE acc ADD COLUMN src_ip varchar(64) NOT NULL default '';
   ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
   ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
+  ALTER TABLE missed_calls ADD COLUMN src_ip varchar(64) NOT NULL default '';
   ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE missed_calls ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
@@ -196,8 +198,8 @@ voicemail.srv_port = "5060" desc "VoiceMail Port"
 
 ####### Modules Section ########
 
-# set paths to location of modules
-#!ifdef LOCAL_TEST_RUN
+# set paths to location of modules (to sources or installation folders)
+#!ifdef WITH_SRCPATH
 mpath="modules_k:modules"
 #!else
 mpath="/usr/local/lib/kamailio/modules_k/:/usr/local/lib/kamailio/modules/"
@@ -222,6 +224,7 @@ loadmodule "siputils.so"
 loadmodule "xlog.so"
 loadmodule "sanity.so"
 loadmodule "ctl.so"
+loadmodule "cfg_rpc.so"
 loadmodule "mi_rpc.so"
 loadmodule "acc.so"
 
@@ -318,7 +321,8 @@ modparam("acc", "detect_direction", 0)
 modparam("acc", "log_flag", FLT_ACC)
 modparam("acc", "log_missed_flag", FLT_ACCMISSED)
 modparam("acc", "log_extra", 
-	"src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
+	"src_user=$fU;src_domain=$fd;src_ip=$si;"
+	"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
 modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)
 /* enhanced DB accounting */
 #!ifdef WITH_ACCDB
@@ -326,7 +330,8 @@ modparam("acc", "db_flag", FLT_ACC)
 modparam("acc", "db_missed_flag", FLT_ACCMISSED)
 modparam("acc", "db_url", DBURL)
 modparam("acc", "db_extra",
-	"src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
+	"src_user=$fU;src_domain=$fd;src_ip=$si;"
+	"dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
 #!endif
 
 
@@ -438,7 +443,8 @@ modparam("debugger", "cfgtrace", 1)
 
 # Main SIP request routing logic
 # - processing of any incoming SIP request starts with this route
-route {
+# - note: this is the same as route { ... }
+request_route {
 
 	# per request initial checks
 	route(REQINIT);

+ 4 - 0
globals.h

@@ -137,6 +137,10 @@ extern int stun_allow_stun;
 extern int stun_allow_fp;
 #endif
 
+#ifdef USE_IPV6
+extern int auto_bind_ipv6;
+#endif
+
 extern int tos;
 extern int pmtu_discovery;
 

+ 4 - 0
main.c

@@ -421,6 +421,10 @@ int mcast_ttl = -1; /* if -1, don't touch it, use the default (usually 1) */
 int tos = IPTOS_LOWDELAY;
 int pmtu_discovery = 0;
 
+#ifdef USE_IPV6
+int auto_bind_ipv6 = 0;
+#endif
+
 #if 0
 char* names[MAX_LISTEN];              /* our names */
 int names_len[MAX_LISTEN];            /* lengths of the names*/

+ 3 - 2
modules/app_lua/app_lua_sr.c

@@ -1081,8 +1081,9 @@ static int lua_sr_pv_is_null (lua_State *L)
 	memset(&val, 0, sizeof(pv_value_t));
 	if(pv_get_spec_value(env_L->msg, &pvs, &val) != 0)
 	{
-		LM_ERR("unable to get pv value for [%s]\n", pvn.s);
-		return 0;
+		LM_NOTICE("unable to get pv value for [%s]\n", pvn.s);
+		lua_pushboolean(L, 1);
+		return 1;
 	}
 	if(val.flags&PV_VAL_NULL)
 	{

+ 182 - 70
modules/cfg_rpc/README

@@ -4,80 +4,192 @@ Miklos Tirpak
 
    <[email protected]>
 
-   Copyright © 2007 iptelorg GmbH
+   Copyright © 2007 iptelorg GmbH
      __________________________________________________________________
 
    1.1. Overview
-   1.2. RPC Interface
+   1.2. Dependencies
+
+        1.2.1. SIP Router Modules
+        1.2.2. External Libraries or Applications
+
+   1.3. RPC Interface
+
+        1.3.1. cfg.list
+        1.3.2. cfg.get
+        1.3.3. cfg.seti
+        1.3.4. cfg.set_now_int
+        1.3.5. cfg.sets
+        1.3.6. cfg.set_now_string
+        1.3.7. cfg.set
+        1.3.8. cfg.del
+        1.3.9. cfg.set_delayed_int
+        1.3.10. cfg.set_delayed_string
+        1.3.11. cfg.set_delayed
+        1.3.12. cfg.del_delayed
+        1.3.13. cfg.commit
+        1.3.14. cfg.rollback
+        1.3.15. cfg.help
+        1.3.16. cfg.diff
+        1.3.17. cfg.add_group_inst
+        1.3.18. cfg.del_group_inst
 
 1.1. Overview
 
-   The module implements RPC functions to set and get configuration
+   The module implements RPC commands to set and get configuration
    variables on-the-fly, that are declared by SIP Router core and by the
-   modules. It can be used to fine-tune or debug SIP Router without the
-   need of restart.
-
-1.2. RPC Interface
-
-   The module implements the following RPC interface commands:
-     * cfg.set_now_int - Set the value of a configuration variable and
-       commit the change immediately. The function accepts three
-       parameters: group name, variable name, integer value. The group
-       name can optionally contain the group instance id, for example
-       foo[5].
-     * cfg.set_now_string - Set the value of a configuration variable and
-       commit the change immediately. The function accepts three
-       parameters: group name, variable name, string value. The group name
-       can optionally contain the group instance id, for example foo[5].
-     * cfg.set - Set the value of a configuration variable and commit the
-       change immediately. This is a wrapper command for cfg.set_now_int
-       and cfg.set_now_string depending on the type of the value provided.
-       The function accepts three parameters: group name, variable name,
-       int/string value. The group name can optionally contain the group
-       instance id, for example foo[5].
-     * cfg.del - Delete the value of a configuration variable from a group
-       instance and commit the change immediately. The value is reset to
-       the default value and it follows the changes of that. The function
-       accepts two parameters: group name, variable name. The group name
-       must contain the group instance id, for example foo[5].
-     * cfg.set_delayed_int - Prepare the change of a configuration
-       variable, but does not commit the new value yet. The function
-       accepts three parameters: group name, variable name, integer value.
-       The group name can optionally contain the group instance id, for
-       example foo[5].
-     * cfg.set_delayed_string - Prepare the change of a configuration
-       variable, but does not commit the new value yet. The function
-       accepts three parameters: group name, variable name, string value.
-       The group name can optionally contain the group instance id, for
-       example foo[5].
-     * cfg.set_delayed - Prepare the change of a configuration variable,
-       but does not commit the new value yet. This is a wrapper command
-       for cfg.set_delayed_int and cfg.set_delayed_string depending on the
-       type of the value provided. The function accepts three parameters:
-       group name, variable name, int/string value. The group name can
-       optionally contain the group instance id, for example foo[5].
-     * cfg.del_delayed - Prepare the deletion of the value of a
-       configuration variable from a group instance, but does not commit
-       the change yet. The value is reset to the default value and it
-       follows the changes of that. The function accepts two parameters:
-       group name, variable name. The group name must contain the group
-       instance id, for example foo[5].
-     * cfg.commit - Commit the previously prepared configuration changes.
-       The function does not have any parameters.
-     * cfg.rollback - Drop the prepared configuration changes. The
-       function does not have any parameters.
-     * cfg.get - Get the value of a configuration variable. The function
-       accepts two parameters: group name, variable name. The group name
-       can optionally contain the group instance id, for example foo[5].
-     * cfg.help - Print the description of a configuration variable. The
-       function accepts two parameters: group name, variable name.
-     * cfg.list - List the configuration variables. The function has one
-       optional parameter: group name.
-     * cfg.diff - List the pending configuration changes that have not
-       been committed yet. The function does not have any parameters.
-     * cfg.add_group_inst - Add a new instance to an existing
-       configuration group. The function accepts one parameter: group
-       name[instance id], for example foo[5].
-     * cfg.del_group_inst - Delete an instance of an existing
-       configuration group. The function accepts one parameter: group
-       name[instance id], for example foo[5].
+   modules.
+
+   For example, it can be used to fine-tune values for global parameters
+   such as debug, tcp/sctp/dns attributes, a.s.o. without the need of
+   restart.
+
+   RPC connector modules, such as ctl or xmlrpc, although not a dependecy,
+   should be loaded in order to execute the RPC commands exported by this
+   module. When ctl module is loaded, the tool 'sercmd' can be used to
+   execute the RPC commands implemented in this module.
+
+1.2. Dependencies
+
+1.2.1. SIP Router Modules
+
+   The following modules must be loaded before this module:
+     * No dependencies on other SIP Router modules.
+
+1.2.2. External Libraries or Applications
+
+   The following libraries or applications must be installed before
+   running SIP Router with this module loaded:
+     * None.
+
+1.3. RPC Interface
+
+   The module implements the RPC commands documented in the next sections.
+
+1.3.1. cfg.list
+
+   cfg.list - List the configuration variables. The function has one
+   optional parameter: group name.
+
+   Example 1. Use cfg.get RPC command
+...
+# sercmd cfg.list
+...
+
+1.3.2. cfg.get
+
+   cfg.get - Get the value of a configuration variable. The function
+   accepts two parameters: group name, variable name. The group name can
+   optionally contain the group instance id, for example foo[5].
+
+   Example 2. Use cfg.get RPC command
+...
+# sercmd cfg.get core debug
+...
+
+1.3.3. cfg.seti
+
+   cfg.seti - Set the value of a configuration variable and commit the
+   change immediately. The function accepts three parameters: group name,
+   variable name, integer value. The group name can optionally contain the
+   group instance id, for example foo[5].
+
+   Example 3. Use cfg.seti RPC command
+...
+# sercmd cfg.seti core debug 1
+...
+
+1.3.4. cfg.set_now_int
+
+   cfg.set_now_int - This is an alias to the command cfg.seti.
+
+1.3.5. cfg.sets
+
+   cfg.sets - Set the value of a configuration variable and commit the
+   change immediately. The function accepts three parameters: group name,
+   variable name, string value. The group name can optionally contain the
+   group instance id, for example foo[5].
+
+1.3.6. cfg.set_now_string
+
+   cfg.set_now_string - This is an alias to the command cfg.sets.
+
+1.3.7. cfg.set
+
+   cfg.set - Set the value of a configuration variable and commit the
+   change immediately. This is a wrapper command for cfg.set_now_int and
+   cfg.set_now_string depending on the type of the value provided. The
+   function accepts three parameters: group name, variable name,
+   int/string value. The group name can optionally contain the group
+   instance id, for example foo[5].
+
+1.3.8. cfg.del
+
+   cfg.del - Delete the value of a configuration variable from a group
+   instance and commit the change immediately. The value is reset to the
+   default value and it follows the changes of that. The function accepts
+   two parameters: group name, variable name. The group name must contain
+   the group instance id, for example foo[5].
+
+1.3.9. cfg.set_delayed_int
+
+   cfg.set_delayed_int - Prepare the change of a configuration variable,
+   but does not commit the new value yet. The function accepts three
+   parameters: group name, variable name, integer value. The group name
+   can optionally contain the group instance id, for example foo[5].
+
+1.3.10. cfg.set_delayed_string
+
+   cfg.set_delayed_string - Prepare the change of a configuration
+   variable, but does not commit the new value yet. The function accepts
+   three parameters: group name, variable name, string value. The group
+   name can optionally contain the group instance id, for example foo[5].
+
+1.3.11. cfg.set_delayed
+
+   cfg.set_delayed - Prepare the change of a configuration variable, but
+   does not commit the new value yet. This is a wrapper command for
+   cfg.set_delayed_int and cfg.set_delayed_string depending on the type of
+   the value provided. The function accepts three parameters: group name,
+   variable name, int/string value. The group name can optionally contain
+   the group instance id, for example foo[5].
+
+1.3.12. cfg.del_delayed
+
+   cfg.del_delayed - Prepare the deletion of the value of a configuration
+   variable from a group instance, but does not commit the change yet. The
+   value is reset to the default value and it follows the changes of that.
+   The function accepts two parameters: group name, variable name. The
+   group name must contain the group instance id, for example foo[5].
+
+1.3.13. cfg.commit
+
+   cfg.commit - Commit the previously prepared configuration changes. The
+   function does not have any parameters.
+
+1.3.14. cfg.rollback
+
+   cfg.rollback - Drop the prepared configuration changes. The function
+   does not have any parameters.
+
+1.3.15. cfg.help
+
+   cfg.help - Print the description of a configuration variable. The
+   function accepts two parameters: group name, variable name.
+
+1.3.16. cfg.diff
+
+   cfg.diff - List the pending configuration changes that have not been
+   committed yet. The function does not have any parameters.
+
+1.3.17. cfg.add_group_inst
+
+   cfg.add_group_inst - Add a new instance to an existing configuration
+   group. The function accepts one parameter: group name[instance id], for
+   example foo[5].
+
+1.3.18. cfg.del_group_inst
+
+   cfg.del_group_inst - Delete an instance of an existing configuration
+   group. The function accepts one parameter: group name[instance id], for
+   example foo[5].

+ 2 - 0
modules/cfg_rpc/cfg_rpc.c

@@ -535,7 +535,9 @@ static void rpc_del_group_inst(rpc_t* rpc, void* c)
 static rpc_export_t rpc_calls[] = {
 	{"cfg.set",		rpc_set,		rpc_set_now_doc,	0},
 	{"cfg.set_now_int",	rpc_set_now_int,	rpc_set_now_doc,	0},
+	{"cfg.seti",	rpc_set_now_int,	rpc_set_now_doc,	0},
 	{"cfg.set_now_string",	rpc_set_now_string,	rpc_set_now_doc,	0},
+	{"cfg.sets",	rpc_set_now_string,	rpc_set_now_doc,	0},
 	{"cfg.del",		rpc_del,		rpc_del_now_doc,	0},
 	{"cfg.set_delayed",	rpc_set_delayed,	rpc_set_delayed_doc,	0},
 	{"cfg.set_delayed_int",	rpc_set_delayed_int,	rpc_set_delayed_doc,	0},

+ 45 - 3
modules/cfg_rpc/doc/cfg_rpc.xml

@@ -27,13 +27,55 @@
     <section id="cfg_rpc.overview">
 	<title>Overview</title>
 	<para>
-	    The module implements RPC functions to set and get
+	    The module implements RPC commands to set and get
 	    configuration variables on-the-fly, that are declared
-	    by &siprouter; core and by the modules. It can be used to fine-tune
-	    or debug &siprouter; without the need of restart.
+		by &siprouter; core and by the modules.
+	</para>
+	<para>
+		For example, it can be used to fine-tune values for
+		global parameters such as debug, tcp/sctp/dns attributes,
+	    a.s.o. without the need of restart.
+	</para>
+	<para>
+		RPC connector modules, such as ctl or xmlrpc, although
+		not a dependecy, should be loaded in order to execute
+		the RPC commands exported by this module. When ctl module
+		is loaded, the tool 'sercmd' can be used to execute
+		the RPC commands implemented in this module.
 	</para>
     </section>
 
+	<section id="cfg_rpc.dependencies">
+	<title>Dependencies</title>
+	<section id="cfg_rpc.depmods">
+		<title>&siprouter; Modules</title>
+		<para>
+		The following modules must be loaded before this module:
+			<itemizedlist>
+			<listitem>
+			<para>
+				<emphasis>No dependencies on other &siprouter; modules</emphasis>.
+			</para>
+			</listitem>
+			</itemizedlist>
+		</para>
+	</section>
+	<section id="cfg_rpc.deplibs">
+		<title>External Libraries or Applications</title>
+		<para>
+		The following libraries or applications must be installed before running
+		&siprouter; with this module loaded:
+			<itemizedlist>
+			<listitem>
+			<para>
+				<emphasis>None</emphasis>.
+			</para>
+			</listitem>
+			</itemizedlist>
+		</para>
+	</section>
+	</section>
+
     <xi:include href="rpc.xml"/>
 
 </section>

+ 102 - 50
modules/cfg_rpc/doc/rpc.xml

@@ -7,28 +7,85 @@
     <title>RPC Interface</title>
 
     <para>
-	The module implements the following RPC interface commands:
-    </para>
-    <itemizedlist>
-	<listitem>
+	The module implements the RPC commands documented in the next sections.
+	</para>
+	<section id="cfg_rpc.rpc.list">
+    <title>cfg.list</title>
 	    <para>
-		<emphasis>cfg.set_now_int</emphasis> - Set the value of
+		<emphasis>cfg.list</emphasis> - List the configuration
+		variables. The function has one optional parameter:
+		group name.
+		</para>
+		<example>
+		<title>Use <varname>cfg.get</varname> RPC command</title>
+		<programlisting format="linespecific">
+...
+# sercmd cfg.list
+...
+</programlisting>
+		</example>
+	</section>
+	<section id="cfg_rpc.rpc.get">
+    <title>cfg.get</title>
+	    <para>
+		<emphasis>cfg.get</emphasis> - Get the value of
+		a configuration variable. The function accepts two parameters:
+		group name, variable name. The group name can optionally contain the
+		group instance id, for example foo[5].
+	    </para>
+		<example>
+		<title>Use <varname>cfg.get</varname> RPC command</title>
+		<programlisting format="linespecific">
+...
+# sercmd cfg.get core debug
+...
+</programlisting>
+		</example>
+	</section>
+	<section id="cfg_rpc.rpc.seti">
+    <title>cfg.seti</title>
+	    <para>
+		<emphasis>cfg.seti</emphasis> - Set the value of
 		a configuration variable and commit the change immediately.
 		The function accepts three parameters: group name, variable
 		name, integer value. The group name can optionally contain the
 		group instance id, for example foo[5].
 	    </para>
-	</listitem>
-	<listitem>
-	    <para>
-		<emphasis>cfg.set_now_string</emphasis> - Set the value of
+		<example>
+		<title>Use <varname>cfg.seti</varname> RPC command</title>
+		<programlisting format="linespecific">
+...
+# sercmd cfg.seti core debug 1
+...
+</programlisting>
+		</example>
+	</section>
+	<section id="cfg_rpc.rpc.set_now_int">
+    <title>cfg.set_now_int</title>
+	    <para>
+		<emphasis>cfg.set_now_int</emphasis> - This is an alias to
+		the command <emphasis>cfg.seti</emphasis>.
+	    </para>
+	</section>
+	<section id="cfg_rpc.rpc.sets">
+    <title>cfg.sets</title>
+	    <para>
+		<emphasis>cfg.sets</emphasis> - Set the value of
 		a configuration variable and commit the change immediately.
 		The function accepts three parameters: group name, variable
 		name, string value. The group name can optionally contain the
 		group instance id, for example foo[5].
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.set_now_string">
+    <title>cfg.set_now_string</title>
+	    <para>
+		<emphasis>cfg.set_now_string</emphasis> - This is an alias to
+		the command <emphasis>cfg.sets</emphasis>.
+	    </para>
+	</section>
+	<section id="cfg_rpc.rpc.set">
+    <title>cfg.set</title>
 	    <para>
 		<emphasis>cfg.set</emphasis> - Set the value of
 		a configuration variable and commit the change immediately.
@@ -38,8 +95,9 @@
 		name, int/string value. The group name can optionally contain the
 		group instance id, for example foo[5].
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.del">
+    <title>cfg.del</title>
 	    <para>
 		<emphasis>cfg.del</emphasis> - Delete the value of
 		a configuration variable from a group instance and commit the change immediately.
@@ -49,8 +107,9 @@
 		name. The group name must contain the
 		group instance id, for example foo[5].
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.set_delayed_int">
+    <title>cfg.set_delayed_int</title>
 	    <para>
 		<emphasis>cfg.set_delayed_int</emphasis> - Prepare the change of
 		a configuration variable, but does not commit the new value yet.
@@ -58,8 +117,9 @@
 		name, integer value. The group name can optionally contain the
 		group instance id, for example foo[5].
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.set_delayed_string">
+    <title>cfg.set_delayed_string</title>
 	    <para>
 		<emphasis>cfg.set_delayed_string</emphasis> - Prepare the change of
 		a configuration variable, but does not commit the new value yet.
@@ -67,8 +127,9 @@
 		name, string value. The group name can optionally contain the
 		group instance id, for example foo[5].
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.set_delayed">
+    <title>cfg.set_delayed</title>
 	    <para>
 		<emphasis>cfg.set_delayed</emphasis> - Prepare the change of
 		a configuration variable, but does not commit the new value yet.
@@ -78,8 +139,9 @@
 		name, int/string value. The group name can optionally contain the
 		group instance id, for example foo[5].
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.del_delayed">
+    <title>cfg.del_delayed</title>
 	    <para>
 		<emphasis>cfg.del_delayed</emphasis> - Prepare the deletion of the value of
 		a configuration variable from a group instance, but does not commit the change yet.
@@ -89,63 +151,53 @@
 		name. The group name must contain the
 		group instance id, for example foo[5].
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.commit">
+    <title>cfg.commit</title>
 	    <para>
 		<emphasis>cfg.commit</emphasis> - Commit the previously
 		prepared configuration changes. The function does not have
 		any parameters.
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.rollback">
+    <title>cfg.rollback</title>
 	    <para>
 		<emphasis>cfg.rollback</emphasis> - Drop the prepared
 		configuration changes. The function does not have any
 		parameters.
 	    </para>
-	</listitem>
-	<listitem>
-	    <para>
-		<emphasis>cfg.get</emphasis> - Get the value of
-		a configuration variable. The function accepts two parameters:
-		group name, variable name. The group name can optionally contain the
-		group instance id, for example foo[5].
-	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.help">
+    <title>cfg.help</title>
 	    <para>
 		<emphasis>cfg.help</emphasis> - Print the description of
 		a configuration variable. The function accepts two parameters:
 		group name, variable name.
 	    </para>
-	</listitem>
-	<listitem>
-	    <para>
-		<emphasis>cfg.list</emphasis> - List the configuration
-		variables. The function has one optional parameter:
-		group name.
-	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.diff">
+    <title>cfg.diff</title>
 	    <para>
 		<emphasis>cfg.diff</emphasis> - List the pending
 		configuration changes that have not been committed yet.
 		The function does not have any parameters.
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.add_group_inst">
+    <title>cfg.add_group_inst</title>
 	    <para>
 		<emphasis>cfg.add_group_inst</emphasis> - Add a new instance
 		to an existing configuration group. The function accepts one parameter:
 		group name[instance id], for example foo[5].
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.del_group_inst">
+    <title>cfg.del_group_inst</title>
 	    <para>
 		<emphasis>cfg.del_group_inst</emphasis> - Delete an instance
 		of an existing configuration group. The function accepts one parameter:
 		group name[instance id], for example foo[5].
 	    </para>
-	</listitem>
-    </itemizedlist>
+	</section>
 </section>

+ 1 - 1
modules/ctl/ctl_defaults.h

@@ -4,7 +4,7 @@
 #ifndef __ctl_defaults_h
 #define __ctl_defaults_h
 /*listen by default on: */
-#define DEFAULT_CTL_SOCKET  "unixs:/tmp/ser_ctl"
+#define DEFAULT_CTL_SOCKET  "unixs:/tmp/" NAME "_ctl"
 /* port used by default for tcp/udp if no port is explicitely specified */
 #define DEFAULT_CTL_PORT 2049
 

+ 0 - 16
modules/msg_shooter/Makefile

@@ -1,16 +0,0 @@
-#
-# msg_shooter module Makefile
-#
-# WARNING: do not run this directly, it should be run by the master Makefile
-
-COREPATH ?= ../..
-include $(COREPATH)/Makefile.defs
-
-NAME=msg_shooter.so
-
-auto_gen=
-
-DEFS += -I$(COREPATH) -DSER_MOD_INTERFACE
-
-include $(COREPATH)/Makefile.modules
-

+ 0 - 125
modules/msg_shooter/README

@@ -1,125 +0,0 @@
-msg shooter module
-
-   Copyright (C) 2011 iptelorg GmbH
-   Created and maintained by Miklos Tirpak
-
-        1.1. Overview
-        1.2. Dependencies
-
-              1.2.1. SER Modules
-
-        1.3. Exported Parameters
-
-        1.4. Exported Functions
-
-              1.4.1. smsg_from_to(from, to)
-              1.4.2. smsg_create(method)
-              1.4.3. smsg_append_hdrs(headers, [body])
-              1.4.4. smsg_on_reply(route_name)
-              1.4.5. shoot_msg([ruri, [destination] ])
-
-        1.5. Example
-
-     _________________________________________________________
-
-1.1. Overview
-
-   The module can be used to send SIP requests outside of the
-   current transaction. For example it can send REGISTER requests
-   to another registrar server as notifications.
-
-   The module creates a UAC and may append additional headers
-   and body to it. Finaly the constructed request can be sent to
-   several destinations.
-
-     _________________________________________________________
-
-1.2. Dependencies
-
-1.2.1. SER Modules
-
-   The following modules must be loaded before this module:
-
-     * tm module
-     _________________________________________________________
-
-1.3. Exported Parameters
-
-   None
-
-   _________________________________________________________
-   
-1.4. Exported Functions
-
-1.4.1. smsg_from_to(from, to)
-
-   Sets the From and To URIs of the UAC, must be called before
-   smsg_create(). Parameters can be string, AVP or select call.
-
-   _________________________________________________________
-
-1.4.2. smsg_create(method)
-
-   Creates an UAC and sets the method of the request.
-   method must be static string.
-
-   Can be called multiple times, but destroys the previously
-   created UAC.
-
-   _________________________________________________________
-
-1.4.3. smsg_append_hdrs(headers, [body])
-
-   Appends additional headers and body to the request.
-   Parameters can be string, AVP or select call.
-
-   _________________________________________________________
-
-1.4.4. smsg_on_reply(route_name)
-
-   Sets onreply_route block which will be executed upon a reply
-   is received for the shooted request. Must be called before
-   every shoot_msg() function if required.
-
-   Note that failure_route is curretly not supported (neither for
-   negative responses nor for timer hit)!
-
-   Also note that the transaction created by the new request does not
-   contain the AVPs of the old transaction, thus onreply_route will
-   not have any AVPs.
-
-   _________________________________________________________
-
-1.4.5. shoot_msg([ruri, [destination] ])
-
-   Shoots the request with the previously created UAC.
-   ruri and destination can be string, AVP or select call.
-   To HF is used for ruri when ruri parameter is not defined.
-
-   Can be called multiple times with the same UAC.
-
-   _________________________________________________________
-
-1.5. Example
-
-   The following example creates 2 UACs and sends the requests
-   to 3 different destinations
-
-onreply_route[notification] {
-
-	smsg_from_to("@from.uri", "@to.uri");
-	smsg_create("REGISTER");
-	$hdrs = "Contact: sip:[email protected]\r\nP-info: created by msg_shooter\r\n";
-	smsg_append_hdrs("$hdrs");
-
-	smsg_on_reply("first");
-	shoot_msg("sip:[email protected]", "sip:192.168.1.1");
-
-	smsg_on_reply("second");
-	shoot_msg("sip:[email protected]");
-
-	smsg_create("NOTIFY");
-	smsg_append_hdrs("P-info: another request\r\n", "Fake body\r\n");
-	shoot_msg("sip:[email protected]");
-
-}

+ 0 - 303
modules/msg_shooter/msg_shooter.c

@@ -1,303 +0,0 @@
-/*$Id$
- *
- * Copyright (C) 2011 iptelorg GmbH
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "mem/mem.h"
-#include "str.h"
-#include "sr_module.h"
-#include "msg_shooter_mod.h"
-#include "smsg_routes.h"
-#include "msg_shooter.h"
-
-/* method points to a static char buffer, all of the others are
-dinamically allocated */
-static str	method = {0, 0};
-static str	from = {0, 0};
-static str	to = {0, 0};
-static str	hdrs = {0, 0};
-static str	body = {0, 0};
-static dlg_t	*UAC = 0;
-/* onreply route index */
-static int	onreply_idx = -1;
-
-/* get method of the request */
-int smsg_create(struct sip_msg *_msg, char *_param1, char *_param2)
-{
-	/* check the required information */
-	if (!from.len || !to.len) {
-		LOG(L_ERR, "ERROR: smsg_create(): mandatory headers are missing\n");
-		LOG(L_ERR, "ERROR: smsg_create(): have you forgot to call smsg_from_to() function?\n");
-		return -1;
-	}
-
-	if (get_str_fparam(&method, _msg, (fparam_t*)_param1)) {
-		LOG(L_ERR, "ERROR: smsg_create(): cannot get parameter\n");
-		return -1;
-	}
-	/* method is just a static char buffer, needless to copy it */
-
-	/* previous UAC still exists -- destroy it first */
-	if (UAC) {
-		LOG(L_DBG, "DEBUG: smsg_create(): destroying previous UAC\n");
-		tmb.free_dlg(UAC);
-		UAC = 0;
-		/* better to free also hdrs and body now */
-		if (hdrs.s) {
-			pkg_free(hdrs.s);
-			hdrs.s = 0;
-			hdrs.len = 0;
-		}
-		if (body.s) {
-			pkg_free(body.s);
-			body.s = 0;
-			body.len = 0;
-		}
-	}
-
-	/* create UAC */
-	if (tmb.new_dlg_uac(0, 0, 0, &from, &to, &UAC) < 0) {
-		LOG(L_ERR, "ERROR: smsg_create(): cannot create UAC\n");
-		return -1;
-	}
-	return 1;
-}
-
-/* free allocated memory */
-void smsg_destroy(void)
-{
-	method.s = 0;
-	method.len = 0;
-	if (from.s) {
-		pkg_free(from.s);
-		from.s = 0;
-		from.len = 0;
-	}
-	if (to.s) {
-		pkg_free(to.s);
-		to.s = 0;
-		to.len = 0;
-	}
-	if (hdrs.s) {
-		pkg_free(hdrs.s);
-		hdrs.s = 0;
-		hdrs.len = 0;
-	}
-	if (body.s) {
-		pkg_free(body.s);
-		body.s = 0;
-		body.len = 0;
-	}
-	if (UAC) {
-		tmb.free_dlg(UAC);
-		UAC = 0;
-	}
-	onreply_idx = -1;
-}
-
-/* clone an str structure */
-static int clone_str(str *_s, str *_d)
-{
-	if (_d->s) pkg_free(_d->s);
-
-	if (_s->len == 0) {
-		/* empty string */
-		_d->s = 0;
-		_d->len = 0;
-		return 0;
-	}
-
-	_d->s = (char *)pkg_malloc(_s->len * sizeof(char));
-	if (!_d->s) {
-		LOG(L_ERR, "ERROR: clone_str(): not enough memory\n");
-		return -1;
-	}
-	memcpy(_d->s, _s->s, _s->len);
-	_d->len = _s->len;
-
-	return 0;
-}
-
-/* set From and To headers of the request */
-int smsg_from_to(struct sip_msg *_msg, char *_param1, char *_param2)
-{
-	str	s;
-
-	if (get_str_fparam(&s, _msg, (fparam_t*)_param1)) {
-		LOG(L_ERR, "ERROR: smsg_from_to(): cannot get parameter\n");
-		return -1;
-	}
-	/* select and AVP result can change, we need a private copy of the buffer */
-	if (clone_str(&s, &from)) return -1;
-
-	if (get_str_fparam(&s, _msg, (fparam_t*)_param2)) {
-		LOG(L_ERR, "ERROR: smsg_from_to(): cannot get parameter\n");
-		return -1;
-	}
-	/* select and AVP result can change, we need a private copy of the buffer */
-	if (clone_str(&s, &to)) return -1;
-
-	return 1;
-}
-
-/* append headers and optionally body to the request */
-int smsg_append_hdrs(struct sip_msg *_msg, char *_param1, char *_param2)
-{
-	str	s;
-
-	if (get_str_fparam(&s, _msg, (fparam_t*)_param1)) {
-		LOG(L_ERR, "ERROR: smsg_append_hdrs(): cannot get parameter\n");
-		return -1;
-	}
-	/* select and AVP result can change, we need a private copy of the buffer */
-	if (clone_str(&s, &hdrs)) return -1;
-
-	if (_param2) {
-		if (get_str_fparam(&s, _msg, (fparam_t*)_param2)) {
-			LOG(L_ERR, "ERROR: smsg_append_hdrs(): cannot get parameter\n");
-			return -1;
-		}
-		/* select and AVP result can change, we need a private copy of the buffer */
-		if (clone_str(&s, &body)) return -1;
-	} else {
-		if (body.s) {
-			pkg_free(body.s);
-			body.s = 0;
-			body.len = 0;
-		}
-	}
-
-	return 1;
-}
-
-/*
- * callback function for TM module
- * it is called on TMCB_LOCAL_COMPLETED
- */
-static void tmcb_func(struct cell *_t, int _type, struct tmcb_params *_ps)
-{
-	int	index;
-
-	if (_type & (TMCB_LOCAL_COMPLETED)) {
-		if ((!_ps->rpl) || (_ps->rpl == FAKED_REPLY)) {
-			/* timer hit  -- on_failure route is not supported */
-			LOG(L_DBG, "DEBUG: tmcb_func(): transaction completed with failure (timer hit),"
-				" but msg_shooter module does not support failure_route currently\n");
-		} else {
-			/* reply received */
-			if (_ps->code >= 400) {
-				LOG(L_DBG, "DEBUG: tmcb_func(): transaction completed with failure (code=%d),"
-					" but msg_shooter module does not support failure_route currently\n",
-					_ps->code);
-			}
-			if (!_ps->param) {
-				LOG(L_ERR, "ERROR: tmcb_func(): parameter is missing\n");
-				return;		
-			}
-			index = (int)(long)(*_ps->param);
-			run_reply_route(_ps->rpl, _t, index);
-		}
-	}
-}
-
-
-static avp_list_t def_avp_list = 0;
-
-/* shoots a request to a destination outside of a dialog */
-int smsg(struct sip_msg *_msg, char *_param1, char *_param2)
-{
-	int	ret = 1;
-	str	ruri = {0, 0};
-	str	dst = {0, 0};
-	avp_list_t	*backup_uri_from, *backup_uri_to;
-	avp_list_t	*backup_user_from, *backup_user_to;
-	avp_list_t	*backup_domain_from, *backup_domain_to;
-	uac_req_t	uac_r;
-
-	/* check the required information */
-	if (!UAC) {
-		LOG(L_ERR, "ERROR: smsg(): UAC is missing\n");
-		LOG(L_ERR, "ERROR: smsg(): have you forgot to call smsg_from_to() and smsg_create() functions?\n");
-		return -1;
-	}
-
-	if (_param1 && get_str_fparam(&ruri, _msg, (fparam_t*)_param1)) {
-		LOG(L_ERR, "ERROR: smsg(): cannot get parameter\n");
-		return -1;
-	}
-
-	if (_param2 && get_str_fparam(&dst, _msg, (fparam_t*)_param2)) {
-		LOG(L_ERR, "ERROR: smsg(): cannot get parameter\n");
-		return -1;
-	}
-
-	LOG(L_DBG, "DEBUG: smsg(): sending %.*s request "
-			"(from=%.*s, to=%.*s, ruri=%.*s, dst=%.*s)\n",
-			method.len, method.s,
-			from.len, from.s,
-			to.len, to.s,
-			ruri.len, ruri.s,
-			dst.len, dst.s);
-
-
-	if (ruri.len) {
-		if (tmb.set_dlg_target(UAC, &ruri, &dst) < 0) {
-			LOG(L_ERR, "ERROR: smsg(): cannot set remote target\n");
-			return -1;
-		}
-	}
-
-	/* reset user AVP lists, otherwise TM would free the memory twice cousing crash */
-	backup_uri_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &def_avp_list);
-	backup_uri_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &def_avp_list);
-	backup_user_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &def_avp_list);
-	backup_user_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &def_avp_list);
-	backup_domain_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &def_avp_list);
-	backup_domain_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &def_avp_list);
-
-	set_uac_req(&uac_r,
-			&method,
-			(hdrs.len) ? &hdrs : 0,
-			(body.len) ? &body : 0,
-			UAC,
-			(onreply_idx < 0) ? 0 : TMCB_LOCAL_COMPLETED,
-			(onreply_idx < 0) ? 0 : tmcb_func,
-			(onreply_idx < 0) ? 0 : (void *)(long)onreply_idx
-		);
-
-	if (tmb.t_uac(&uac_r) < 0) {
-		LOG(L_ERR, "ERROR: smsg(): request could not be sent\n");
-		ret = -1;
-	}
-
-	/* restore AVP lists */
-	set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, backup_uri_from);
-	set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, backup_uri_to);
-	set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, backup_user_from);
-	set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, backup_user_to);
-	set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, backup_domain_from);
-	set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, backup_domain_to);
-
-	/* reset smsg_on_reply */
-	onreply_idx = -1;
-	return ret;
-}
-
-/* sents on_reply route which will be called later */
-int smsg_on_reply(struct sip_msg *_msg, char *_param1, char *_param2)
-{
-	onreply_idx = (int)(long)(_param1);
-	return 1;
-}

+ 0 - 42
modules/msg_shooter/msg_shooter.h

@@ -1,42 +0,0 @@
-/*$Id$
- *
- * Copyright (C) 2011 iptelorg GmbH
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-
-#ifndef _MSG_SHOOTER_H
-#define _MSG_SHOOTER_H
-
-#include "parser/msg_parser.h"
-
-/* get method of the request */
-int smsg_create(struct sip_msg *_msg, char *_param1, char *_param2);
-
-/* free allocated memory */
-void smsg_destroy(void);
-
-/* set From and To headers of the request */
-int smsg_from_to(struct sip_msg *_msg, char *_param1, char *_param2);
-
-/* append headers and optionally body to the request */
-int smsg_append_hdrs(struct sip_msg *_msg, char *_param1, char *_param2);
-
-/* shoots a request to a destination outside of a dialog */
-int smsg(struct sip_msg *_msg, char *_param1, char *_param2);
-
-/* sents on_reply route which will be called later */
-int smsg_on_reply(struct sip_msg *_msg, char *_param1, char *_param2);
-
-#endif /* _MSG_SHOOTER_H */

+ 0 - 124
modules/msg_shooter/msg_shooter_mod.c

@@ -1,124 +0,0 @@
-/*$Id$
- *
- * Copyright (C) 2011 iptelorg GmbH
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-
-#include "sr_module.h"
-#include "script_cb.h"
-#include "route.h"
-#include "modules/tm/tm_load.h"
-#include "msg_shooter.h"
-#include "msg_shooter_mod.h"
-
-MODULE_VERSION
-
-struct tm_binds	tmb;
-
-/* Module management function prototypes */
-static int mod_init(void);
-static int w_smsg_destroy(struct sip_msg *_msg, unsigned int flags, void *_param);
-static int fixup_smsg_on_reply(void** _param, int _param_no);
-
-/* Exported functions */
-static cmd_export_t cmds[] = {
-	{"shoot_msg",	smsg,		0, 0,
-			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
-
-	{"shoot_msg",	smsg,		1, fixup_var_str_1,
-			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
-
-	{"shoot_msg",	smsg,		2, fixup_var_str_12,
-			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
-
-	{"smsg_create",	smsg_create, 	1, fixup_str_1,
-			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
-
-	{"smsg_from_to",	smsg_from_to, 2, fixup_var_str_12,
-			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
-
-	{"smsg_append_hdrs", 	smsg_append_hdrs, 1, fixup_var_str_1,
-			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
-
-	{"smsg_append_hdrs", 	smsg_append_hdrs, 2, fixup_var_str_12,
-			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
-
-	{"smsg_on_reply", 	smsg_on_reply,	1, fixup_smsg_on_reply,
-			REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE | BRANCH_ROUTE},
-
-	{0, 0, 0, 0, 0}
-};
-
-/* Module interface */
-struct module_exports exports = {
-	"msg_shooter",
-	cmds,		/* Exported functions */
-	0,		/* RPC methods */	
-	0,		/* Exported parameters */
-	mod_init,	/* module initialization function */
-	0,		/* response function */
-	0,		/* destroy function */
-	0,		/* oncancel function */
-	0		/* child initialization function */
-};
-
-/* module initialization function */
-static int mod_init(void)
-{
-	load_tm_f	load_tm;
-
-	LOG(L_DBG, "DEBUG: mod_init(): Initializing msg_shooter module\n");
-
-	/* import the TM auto-loading function */
-	if ( !(load_tm=(load_tm_f)find_export("load_tm", NO_SCRIPT, 0))) {
-		LOG(L_ERR, "ERROR: mod_init(): can't import load_tm\n");
-		return -1;
-	}
-	/* let the auto-loading function load all TM stuff */
-	if (load_tm( &tmb )==-1) return -1;
-
-	if (register_script_cb(w_smsg_destroy,
-			REQUEST_CB | FAILURE_CB | ONREPLY_CB | BRANCH_CB | POST_SCRIPT_CB,
-			0) < 0
-	)
-		return -1;
-
-	return 0;
-}
-
-/* free allocated memory */
-static int w_smsg_destroy(struct sip_msg *_msg, unsigned int flags, void *_param)
-{
-	smsg_destroy();
-	return 1;
-}
-
-/* fixup function to convert route name to index */
-static int fixup_smsg_on_reply(void** _param, int _param_no)
-{
-	int index;
-
-	if (_param_no != 1) return 0;
-
-	index = route_lookup(&onreply_rt, (char*)(*_param));
-	if (index < 0) {
-		LOG(L_ERR, "ERROR: fixup_smsg_on_reply(): unknown on_reply route name: %s\n",
-				(char*)(*_param));
-		return -1;
-	}
-	pkg_free(*_param);
-	*_param = (void *)(long)index;
-	return 0;
-}

+ 0 - 26
modules/msg_shooter/msg_shooter_mod.h

@@ -1,26 +0,0 @@
-/*$Id$
- *
- * Copyright (C) 2011 iptelorg GmbH
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-
-#ifndef _MSG_SHOOTER_MOD_H
-#define _MSG_SHOOTER_MOD_H
-
-#include "modules/tm/tm_load.h"
-
-extern struct tm_binds	tmb;
-
-#endif /* _MSG_SHOOTER_MOD_H */

+ 0 - 54
modules/msg_shooter/smsg_routes.c

@@ -1,54 +0,0 @@
-/*$Id$
- *
- * Copyright (C) 2011 iptelorg GmbH
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include "action.h"
-#include "route.h"
-#include "modules/tm/h_table.h"
-#include "smsg_routes.h"
-
-/* run reply route functions */
-int run_reply_route(struct sip_msg *_rpl, struct cell *_t, int index)
-{
-	avp_list_t	*backup_uri_from, *backup_uri_to;
-	avp_list_t	*backup_user_from, *backup_user_to;
-	avp_list_t	*backup_domain_from, *backup_domain_to;
-	struct run_act_ctx	ra_ctx;
-
-	if (!_t || (index < 0)) return -1;
-
-	/* set the avp_list the one from transaction */
-	backup_uri_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_URI, &_t->uri_avps_from );
-	backup_uri_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_URI, &_t->uri_avps_to );
-	backup_user_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_USER, &_t->user_avps_from );
-	backup_user_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_USER, &_t->user_avps_to );
-	backup_domain_from = set_avp_list(AVP_TRACK_FROM | AVP_CLASS_DOMAIN, &_t->domain_avps_from );
-	backup_domain_to = set_avp_list(AVP_TRACK_TO | AVP_CLASS_DOMAIN, &_t->domain_avps_to );
-
-	init_run_actions_ctx(&ra_ctx);
-	if (run_actions(&ra_ctx, onreply_rt.rlist[index], _rpl)<0)
-		LOG(L_ERR, "ERROR: run_reply_route(): on_reply processing failed\n");
-
-	/* restore original avp list */
-	set_avp_list( AVP_TRACK_FROM | AVP_CLASS_URI, backup_uri_from );
-	set_avp_list( AVP_TRACK_TO | AVP_CLASS_URI, backup_uri_to );
-	set_avp_list( AVP_TRACK_FROM | AVP_CLASS_USER, backup_user_from );
-	set_avp_list( AVP_TRACK_TO | AVP_CLASS_USER, backup_user_to );
-	set_avp_list( AVP_TRACK_FROM | AVP_CLASS_DOMAIN, backup_domain_from );
-	set_avp_list( AVP_TRACK_TO | AVP_CLASS_DOMAIN, backup_domain_to );
-
-	return 0;
-}

+ 0 - 26
modules/msg_shooter/smsg_routes.h

@@ -1,26 +0,0 @@
-/*$Id$
- *
- * Copyright (C) 2011 iptelorg GmbH
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
- * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
- * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-
-#ifndef _ROUTES_H
-#define _ROUTES_H
-
-/* run reply route functions */
-int run_reply_route(struct sip_msg *res, struct cell *t, int index);
-
-
-#endif /* _ROUTES_H */

+ 6 - 0
modules/sipcapture/sipcapture.h

@@ -23,6 +23,12 @@
  *
  */
 
+#ifdef __OS_solaris
+typedef uint8_t u_int8_t;
+typedef uint16_t u_int16_t;
+#define IPPROTO_IPIP IPPROTO_ENCAP /* Solaris IPIP protocol has name ENCAP */
+#endif
+
 
 struct hep_hdr{
     u_int8_t hp_v;            /* version */

+ 1 - 1
modules_k/auth_radius/extra.c

@@ -190,7 +190,7 @@ int extra2strar( struct extra_attr *extra, struct sip_msg *rq, str *val_arr)
 	    val_arr[n].len = 0;
 	} else if (value.flags&PV_VAL_INT) {
 	    /* len = -1 denotes int type */
-	    val_arr[n].s = (char *)value.ri;
+	    val_arr[n].s = (char *)(long)value.ri;
 	    val_arr[n].len = -1;
 	} else {
 	    /* set the value into the acc buffer */

+ 3 - 3
modules_k/dialog/dialog.c

@@ -567,19 +567,19 @@ static int mod_init(void)
 	}
 
 	if (register_script_cb( profile_cleanup, POST_SCRIPT_CB|REQUEST_CB,0)<0) {
-		LM_ERR("cannot regsiter script callback");
+		LM_ERR("cannot register script callback");
 		return -1;
 	}
 	if (register_script_cb(dlg_cfg_cb,
 				PRE_SCRIPT_CB|REQUEST_CB,0)<0)
 	{
-		LM_ERR("cannot regsiter pre-script ctx callback\n");
+		LM_ERR("cannot register pre-script ctx callback\n");
 		return -1;
 	}
 	if (register_script_cb(dlg_cfg_cb,
 				POST_SCRIPT_CB|REQUEST_CB,0)<0)
 	{
-		LM_ERR("cannot regsiter post-script ctx callback\n");
+		LM_ERR("cannot register post-script ctx callback\n");
 		return -1;
 	}
 

+ 9 - 0
modules_k/dialog/doc/dialog_admin.xml

@@ -1434,6 +1434,15 @@ dlg_refer("caller", "sip:[email protected]");
 		<para>
 		This function can be used from REQUEST_ROUTE.
 		</para>
+		<para>
+		<b>IMPORTANT</b>: Users of this function should make sure that the
+		dialog created is further processed statefully. Specifically, if a
+		stateless response is sent out after dlg_manage() is called, the
+		dialog cannot be handled properly. So make sure that a transaction
+		exists or create it explicitly using the tm module.<br>This is a
+		shortcoming of the current implementation that may be resolved in a
+		future version hopefully.
+		</para>
 		<example>
 		<title><function>dlg_manage</function> usage</title>
 		<programlisting format="linespecific">

+ 20 - 9
modules_k/dispatcher/dispatch.c

@@ -252,6 +252,8 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs,
 	static char hn[256];
 	struct hostent* he;
 	struct sip_uri puri;
+	int orig_id = 0, orig_nr = 0;
+	ds_set_t *orig_ds_lists = ds_lists[list_idx];
 
 	/* check uri */
 	if(parse_uri(uri.s, uri.len, &puri)!=0 || puri.host.len>254)
@@ -283,6 +285,8 @@ int add_dest2list(int id, str uri, int flags, int priority, str *attrs,
 		ds_lists[list_idx] = sp;
 		*setn = *setn+1;
 	}
+	orig_id = sp->id;
+	orig_nr = sp->nr;
 	sp->id = id;
 	sp->nr++;
 
@@ -365,6 +369,18 @@ err:
 			shm_free(dp->uri.s);
 		shm_free(dp);
 	}
+
+	if (sp != NULL)
+	{
+		sp->id = orig_id;
+		sp->nr = orig_nr;
+		if (sp->nr == 0)
+		{
+			shm_free(sp);
+			ds_lists[list_idx] = orig_ds_lists;
+		}
+	}
+
 	return -1;
 }
 
@@ -566,9 +582,8 @@ int ds_load_list(char *lfile)
 add_destination:
 		if(add_dest2list(id, uri, flags, priority, &attrs,
 					*next_idx, &setn) != 0)
-			goto error;
-					
-		
+			LM_WARN("unable to add destination %.*s to set %d -- skipping\n",
+					uri.len, uri.s, id);
 next_line:
 		p = fgets(line, 256, f);
 	}
@@ -720,11 +735,7 @@ int ds_load_db(void)
 	nr_rows = RES_ROW_N(res);
 	rows 	= RES_ROWS(res);
 	if(nr_rows == 0)
-	{
 		LM_WARN("no dispatching data in the db -- empty destination set\n");
-		ds_dbf.free_result(ds_db_handle, res);
-		return 0;
-	}
 
 	setn = 0;
 	*next_idx = (*crt_idx + 1)%2;
@@ -752,8 +763,8 @@ int ds_load_db(void)
 		}
 		if(add_dest2list(id, uri, flags, priority, &attrs,
 					*next_idx, &setn) != 0)
-			goto err2;
-
+			LM_WARN("unable to add destination %.*s to set %d -- skipping\n",
+					uri.len, uri.s, id);
 	}
 	ds_dbf.free_result(ds_db_handle, res);
 

+ 1 - 1
modules_k/misc_radius/extra.c

@@ -190,7 +190,7 @@ int extra2strar( struct extra_attr *extra, struct sip_msg *rq, str *val_arr)
 	    val_arr[n].len = 0;
 	} else if (value.flags&PV_VAL_INT) {
 	    /* len = -1 denotes int type */
-	    val_arr[n].s = (char *)value.ri;
+	    val_arr[n].s = (char *)(long)value.ri;
 	    val_arr[n].len = -1;
 	} else {
 	    /* set the value into the acc buffer */

+ 1 - 1
modules_k/osp/osp_mod.c

@@ -182,7 +182,7 @@ static int ospInitMod(void)
     }
 
     /* Load the AUTH API */
-    bind_su = (bind_siputils_t)find_export("bind_siputils", 0, 0);
+    bind_su = (bind_siputils_t)find_export("bind_siputils", 1, 0);
     if ((bind_su == NULL) || (bind_su(&osp_siputils) != 0)) {
         LM_WARN("failed to load the SIPUTILS API. Check if you load the auth module.\n");
         LM_WARN("rpid_avp & rpid_avp_type is required for calling number translation\n");

+ 13 - 3
modules_k/presence_xml/pres_check.c

@@ -162,9 +162,19 @@ int presxml_check_activities(struct sip_msg *msg, str presentity_uri, str activi
 		{
 			if ((activitiesNode = xmlNodeGetNodeByName(person, "activities", NULL)) == NULL)
 			{
-				LM_DBG("unable to extract 'actvities' node\n");
-				retval = -2;
-				goto error;
+				LM_DBG("unable to extract 'activities' node\n");
+				if (retval <= 0)
+				{
+					retval = -2;
+				}
+			}
+			if (activitiesNode->children == NULL)
+			{
+				LM_DBG("activities node has no children\n");
+				if (retval <= 0)
+				{
+					retval = -2;
+				}
 			}
 
 			if ((activityNode = xmlNodeGetNodeByName(activitiesNode, nodeName, NULL)) != NULL)

+ 1 - 1
modules_k/siputils/siputils.c

@@ -154,7 +154,7 @@ static cmd_export_t cmds[]={
 		    fixup_free_set_uri,	ANY_ROUTE},
 	{"set_uri_host", (cmd_function)set_uri_host,             2, fixup_set_uri,
 		    fixup_free_set_uri,	ANY_ROUTE},
-	{"bind_siputils",       (cmd_function)bind_siputils,           0, 0,
+	{"bind_siputils",       (cmd_function)bind_siputils,           1, 0,
 			0, 0},
 	{"is_request",          (cmd_function)w_is_request,            0, 0,
 			0, ANY_ROUTE},

+ 24 - 7
modules_k/snmpstats/README

@@ -8,7 +8,7 @@ Edited by
 
 Jeffrey Magder
 
-   Copyright © 2006 SOMA Networks, Inc.
+   Copyright © 2006 SOMA Networks, Inc.
      __________________________________________________________________
 
    Table of Contents
@@ -40,6 +40,7 @@ Jeffrey Magder
               4.5. dlg_major_threshold (Integer)
               4.6. snmpgetPath (String)
               4.7. snmpCommunity (String)
+              4.8. export_registrar (int)
 
         5. Functions
         6. Installation and Running
@@ -64,6 +65,7 @@ Jeffrey Magder
    1.5. Setting the dlg_major_threshold parameter
    1.6. Setting the snmpgetPath parameter
    1.7. Setting the snmpCommunity parameter
+   1.8. Setting the export_registrar parameter
 
 Chapter 1. Admin Guide
 
@@ -94,6 +96,7 @@ Chapter 1. Admin Guide
         4.5. dlg_major_threshold (Integer)
         4.6. snmpgetPath (String)
         4.7. snmpCommunity (String)
+        4.8. export_registrar (int)
 
    5. Functions
    6. Installation and Running
@@ -275,6 +278,7 @@ Chapter 1. Admin Guide
    4.5. dlg_major_threshold (Integer)
    4.6. snmpgetPath (String)
    4.7. snmpCommunity (String)
+   4.8. export_registrar (int)
 
 4.1. sipEntityType (String)
 
@@ -367,7 +371,7 @@ modparam("snmpstats", "MsgQueueMajorThreshold", 5000)
    the master agent. You can use this parameter to set the path to your
    instance of NetSNMP's snmpget program.
 
-   Default value is “/usr/local/bin/�.
+   Default value is "/usr/local/bin/".
 
    Example 1.6. Setting the snmpgetPath parameter
 ...
@@ -381,13 +385,26 @@ modparam("snmpstats", "snmpgetPath",     "/my/custom/path/")
    the master agent. If you have defined a custom community string for the
    snmp daemon, you need to specify it with this parameter.
 
-   Default value is “public�.
+   Default value is "public".
 
    Example 1.7. Setting the snmpCommunity parameter
 ...
 modparam("snmpstats", "snmpCommunity", "customCommunityString")
 ...
 
+4.8. export_registrar (int)
+
+   The SNMPStats module will export registrar (usrloc) records if this
+   parameter is set to 1. This will result in more memory usage and bigger
+   exporter structure.
+
+   Default value is "0" (don't export).
+
+   Example 1.8. Setting the export_registrar parameter
+...
+modparam("snmpstats", "export_registrar", 1)
+...
+
 5. Functions
 
    Currently, there are no exported functions.
@@ -406,7 +423,7 @@ modparam("snmpstats", "snmpCommunity", "customCommunityString")
    There are several things that need to be done to get the SNMPStats
    module compiled and up and running.
 
-6.1.  Compiling the SNMPStats Module
+6.1. Compiling the SNMPStats Module
 
    In order for the SNMPStats module to compile, you will need at least
    version 5.3 of the NetSNMP source code. The source can be found at:
@@ -428,7 +445,7 @@ modparam("snmpstats", "snmpCommunity", "customCommunityString")
    recommended you install NetSNMP from source to avoid bringing in
    excessive dependencies to the SNMPStats module.
 
-6.2.  Configuring NetSNMP to allow connections from the SNMPStats module.
+6.2. Configuring NetSNMP to allow connections from the SNMPStats module.
 
    The SNMPStats module will communicate with the NetSNMP Master Agent.
    This communication happens over a protocol known as AgentX. This means
@@ -460,7 +477,7 @@ modparam("snmpstats", "snmpCommunity", "customCommunityString")
    This tells NetSNMP to act as a master agent, listening on the localhost
    UDP interface at port 705.
 
-6.3.  Configuring the SNMPStats module for communication with a Master Agent
+6.3. Configuring the SNMPStats module for communication with a Master Agent
 
    The previous section explained how to set up a NetSNMP master agent to
    accept AgentX connections. We now need to tell the SNMPStats module how
@@ -480,7 +497,7 @@ modparam("snmpstats", "snmpCommunity", "customCommunityString")
    be present on the same machine as OpenSER. localhost could be replaced
    with any other machine.
 
-6.4.  Testing for a proper Configuration
+6.4. Testing for a proper Configuration
 
    As a quick test to make sure that the SNMPStats module sub-agent can
    succesfully connect to the NetSNMP Master agent, start snmpd with the

+ 25 - 0
modules_k/snmpstats/doc/snmpstats_admin.xml

@@ -421,6 +421,31 @@ modparam("snmpstats", "snmpCommunity", "customCommunityString")
 		</example>
 	</section>
 
+	<section>
+		<title><varname>export_registrar</varname> (int)</title>
+
+		<para>
+		The SNMPStats module will export registrar (usrloc) records if
+		this parameter is set to 1. This will result in more memory usage
+		and bigger exporter structure.
+		</para>
+
+		<para>
+		<emphasis>
+			Default value is <quote>0</quote> (don't export).
+		</emphasis>
+		</para>
+
+		<example>
+		<title>Setting the <varname>export_registrar</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("snmpstats", "export_registrar", 1)
+...
+		</programlisting>
+		</example>
+	</section>
+
 	</section>
 	<section>
 	<title>Functions</title>

+ 12 - 1
modules_k/snmpstats/mibs/OPENSER-MIB

@@ -399,6 +399,16 @@ OPENSER-MIB DEFINITIONS ::= BEGIN
              -1 indicates the value is not configured, and alarms will never be 
              set, and the usage state will never be reported as 'busy'."
         ::= { openserDialogStats 6 }
+
+    openserTotalNumDialogSetups     OBJECT-TYPE
+        SYNTAX      Counter32
+        MAX-ACCESS  read-only
+        STATUS      current
+        DESCRIPTION
+            "The total number of calls (answered and failed)."
+        ::= { openserDialogStats 7 }
+
+
 --
 -- Dialog State
 --
@@ -601,7 +611,8 @@ OPENSER-MIB DEFINITIONS ::= BEGIN
             openserCurNumDialogsInSetup,
             openserTotalNumFailedDialogSetups,
             openserDialogLimitMinorThreshold,
-            openserDialogLimitMajorThreshold           
+            openserDialogLimitMajorThreshold,
+            openserTotalNumDialogSetups
         }
         STATUS  current
         DESCRIPTION

+ 28 - 0
modules_k/snmpstats/snmpObjects.c

@@ -94,6 +94,9 @@ void init_openserObjects(void)
 	static oid openserDialogLimitMajorThreshold_oid[]  = 
 		{ OPENSER_OID,3,1,3,1,3,2,6 };
 
+	static oid openserTotalNumDialogSetups_oid[] =
+		{ OPENSER_OID,3,1,3,1,3,2,7 };
+
 	static oid openserDialogUsageState_oid[]       = 
 		{ OPENSER_OID,3,1,3,1,3,3,1 };
 
@@ -217,6 +220,15 @@ void init_openserObjects(void)
 			HANDLER_CAN_RONLY)
 		);
 
+	netsnmp_register_scalar(
+		netsnmp_create_handler_registration(
+			"openserTotalNumDialogSetups",
+		handle_openserTotalNumDialogSetups,
+		openserTotalNumDialogSetups_oid,
+		OID_LENGTH(openserTotalNumDialogSetups_oid),
+		HANDLER_CAN_RONLY)
+		);
+
 	netsnmp_register_scalar(
 		netsnmp_create_handler_registration(
 			"openserDialogUsageState", 
@@ -467,6 +479,22 @@ int handle_openserTotalNumFailedDialogSetups(netsnmp_mib_handler *handler,
 	return SNMP_ERR_GENERR;
 }
 
+int handle_openserTotalNumDialogSetups(netsnmp_mib_handler *handler,
+		netsnmp_handler_registration *reginfo,
+		netsnmp_agent_request_info   *reqinfo,
+		netsnmp_request_info         *requests)
+{
+	int result = get_statistic("processed_dialogs");
+
+	if (reqinfo->mode == MODE_GET) {
+		snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER,
+			(u_char *) &result, sizeof(int));
+		return SNMP_ERR_NOERROR;
+	}
+
+	return SNMP_ERR_GENERR;
+}
+
 int handle_openserDialogLimitMinorThreshold(netsnmp_mib_handler *handler,
 		netsnmp_handler_registration *reginfo,
 		netsnmp_agent_request_info   *reqinfo,

+ 1 - 0
modules_k/snmpstats/snmpObjects.h

@@ -57,6 +57,7 @@ Netsnmp_Node_Handler handle_openserCurNumDialogsInSetup;
 Netsnmp_Node_Handler handle_openserTotalNumFailedDialogSetups;
 Netsnmp_Node_Handler handle_openserDialogLimitMinorThreshold;
 Netsnmp_Node_Handler handle_openserDialogLimitMajorThreshold;
+Netsnmp_Node_Handler handle_openserTotalNumDialogSetups;
 Netsnmp_Node_Handler handle_openserDialogUsageState;
 Netsnmp_Node_Handler handle_openserDialogLimitAlarmStatus;
 Netsnmp_Node_Handler handle_openserDialogLimitMinorAlarm;

+ 25 - 15
modules_k/snmpstats/snmpstats.c

@@ -107,6 +107,10 @@
 /* Required in every Kamailio Module. */
 MODULE_VERSION
 
+/* module parameter to register for usrloc callbacks or not,
+ * in order to export registrar records (0 - don't export, 1 - export) */
+static int snmp_export_registrar = 0;
+
 /*! This is the first function to be called by Kamailio, to initialize the module.
  * This call must always return a value as soon as possible.  If it were not to
  * return, then Kamailio would not be able to initialize any of the other
@@ -150,6 +154,10 @@ static param_export_t mod_params[] =
 			(void *)set_snmpget_path          },
 	{ "snmpCommunity",          STR_PARAM|USE_FUNC_PARAM,
 			(void *)set_snmp_community        },
+	{ "snmpCommunity",          STR_PARAM|USE_FUNC_PARAM,
+			(void *)set_snmp_community        },
+	{ "export_registrar",       INT_PARAM,
+			&snmp_export_registrar            },
 	{ 0,0,0 }
 };
 
@@ -318,24 +326,26 @@ static int mod_init(void)
 	 * the database.  That load will happen if a lookup() function is come
 	 * across in kamailio.cfg. */
 
-	if (!registerForUSRLOCCallbacks()) 
+	if (snmp_export_registrar!=0)
 	{
-		/* Originally there were descriptive error messages here to help
-		 * the operator debug problems.  Turns out this may instead
-		 * alarm them about problems they don't need to worry about.  So
-		 * the messages are commented out for now */
+		if(!registerForUSRLOCCallbacks())
+		{
+			/* Originally there were descriptive error messages here to help
+			 * the operator debug problems.  Turns out this may instead
+			 * alarm them about problems they don't need to worry about.  So
+			 * the messages are commented out for now */
 		
-		/*
-		LM_ERR("snmpstats module was unable to register callbacks" 
-						" with the usrloc module\n");
-		LM_ERR("Are you sure that the usrloc module was loaded"
-				" before the snmpstats module in ");
-		LM_ERR("kamailio.cfg?  openserSIPRegUserTable will not be "
-			   "updated.");
-		*/
-	} 
+			/*
+			LM_ERR("snmpstats module was unable to register callbacks"
+					" with the usrloc module\n");
+			LM_ERR("Are you sure that the usrloc module was loaded"
+					" before the snmpstats module in ");
+			LM_ERR("kamailio.cfg?  openserSIPRegUserTable will not be "
+				   "updated.");
+			*/
+		}
+	}
 
-	
 	/* Register the alarm checking function to run periodically */
 	register_timer(run_alarm_check, 0, ALARM_AGENT_FREQUENCY_IN_SECONDS);
 

+ 403 - 12
socket_info.c

@@ -1,3 +1,4 @@
+
 /* $Id$
  *
  * find & manage listen addresses 
@@ -713,7 +714,369 @@ error:
 	return -1;
 }
 
+#ifdef __OS_linux
+
+#include "linux/netlink.h"
+#include "linux/rtnetlink.h"
+#include "arpa/inet.h"
+
+
+#define MAX_IF_LEN 64
+struct idx
+{
+	struct idx * 	next;
+	int 		family;
+	unsigned	ifa_flags;
+	char		addr[MAX_IF_LEN];
+
+};
+
+struct idxlist{
+	struct idx* 	addresses;
+	int 		index;
+	char 		name[MAX_IF_LEN];
+	unsigned 	flags;
+};
+
+#define MAX_IFACE_NO 32
+
+static struct idxlist *ifaces = NULL;
+static int seq = 0;
+
+#define SADDR(s) ((struct sockaddr_in*)s)->sin_addr.s_addr
+
+#define NLMSG_TAIL(nmsg) \
+	((struct rtattr *) (((void *) (nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len)))
+
+int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
+	      int alen)
+{
+	int len = RTA_LENGTH(alen);
+	struct rtattr *rta;
+
+	if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
+		fprintf(stderr, "addattr_l ERROR: message exceeded bound of %d\n",maxlen);
+		return -1;
+	}
+	rta = NLMSG_TAIL(n);
+	rta->rta_type = type;
+	rta->rta_len = len;
+	memcpy(RTA_DATA(rta), data, alen);
+	n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len);
+	return 0;
+}
+
+
+
+static int nl_bound_sock(void)
+{
+	int sock;
+	struct sockaddr_nl la;
+
+	sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
+	if(sock <= 0){
+		LM_ERR("could not create NETLINK sock to get interface list");
+		goto error;
+	}
+
+	/* bind NETLINK socket to pid */
+	bzero(&la, sizeof(la));
+	la.nl_family = AF_NETLINK;
+	la.nl_pad = 0;
+	la.nl_pid = getpid();
+	la.nl_groups = 0;
+	if ( bind(sock, (struct sockaddr*) &la, sizeof(la)) < 0){
+		LM_ERR("could not bind NETLINK sock to sockaddr_nl\n");
+		goto error;
+	}
+
+	return sock;
+error:
+	if(sock > 0) close(sock);
+	return -1;
+}
+
+#define fill_nl_req(req, type, family) do {\
+	memset(&req, 0, sizeof(req));\
+	req.nlh.nlmsg_len = sizeof(req);\
+	req.nlh.nlmsg_type = type;\
+	req.nlh.nlmsg_flags = NLM_F_ROOT|NLM_F_MATCH|NLM_F_REQUEST|NLM_F_DUMP;\
+	req.nlh.nlmsg_pid = getpid();\
+	req.nlh.nlmsg_seq = seq++;\
+	req.g.rtgen_family = family;\
+	} while(0);
+
+	
+static int get_flags(int family){
+	struct {
+		struct nlmsghdr nlh;
+		struct rtgenmsg g;
+	} req;
+	int rtn = 0;
+	struct nlmsghdr*  nlp;
+	struct ifinfomsg *ifi;
+	char buf[8192];
+	char *p = buf;
+	int nll = 0;
+        int nl_sock = 0;
+
+	fill_nl_req(req, RTM_GETLINK, AF_INET);
+
+	if((nl_sock = nl_bound_sock()) < 0) return -1;
+
+	if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0)
+	{
+		LM_ERR("error sending NETLINK request\n");
+		goto error;
+	}
+
+	while(1) {
+		rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
+		nlp = (struct nlmsghdr *) p;
+		if(nlp->nlmsg_type == NLMSG_DONE){
+			LM_DBG("done\n");
+			 break;
+		}
+		if(nlp->nlmsg_type == NLMSG_ERROR){
+			 LM_DBG("Error on message to netlink");
+			 break;
+		}
+		p += rtn;
+
+		nll += rtn;
+	}
+
+	nlp = (struct nlmsghdr *) buf;
+	for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
+		ifi = NLMSG_DATA(nlp);
+
+		if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
+			goto error;
+
+		LM_ERR("Interface with index %d has flags %d\n", ifi->ifi_index, ifi->ifi_flags);
+		if(ifaces == NULL){
+			LM_ERR("get_flags must not be called on empty interface list");
+			goto error;
+		}
+		if(ifi->ifi_index >= MAX_IFACE_NO){
+			LM_ERR("invalid network interface index returned %d", ifi->ifi_index);
+			goto error;
+		}
+		ifaces[ifi->ifi_index].flags = ifi->ifi_flags;
+	}
+
+	if(nl_sock>0) close(nl_sock);
+	return 0;
+
+error:
+	if(nl_sock>0) close(nl_sock);
+	return -1;
+}
+
+static int build_iface_list(void)
+{
+	struct {
+		struct nlmsghdr nlh;
+		struct rtgenmsg g;
+	} req;
+
+	int seq = 0;
+	int rtn = 0;
+	struct nlmsghdr*  nlp;
+	struct ifaddrmsg *ifi;
+	int rtl;
+	char buf[8192];
+	char *p = buf;
+	int nll = 0;
+	struct rtattr * rtap;
+	int index, i;
+	struct idx* entry;
+	struct idx* tmp;
+        int nl_sock = 0;
+        int families[] = {AF_INET, AF_INET6};
+        char name[MAX_IF_LEN];
+	int is_link_local = 0;
+
+	if(ifaces == NULL){
+		if((ifaces = (struct idxlist*)pkg_malloc(MAX_IFACE_NO*sizeof(struct idxlist))) == NULL){
+			LM_ERR("No more pkg memory\n");
+			return -1;
+		}
+		memset(ifaces, 0, sizeof(struct idxlist)*MAX_IFACE_NO);
+	}
+
+	/* bind netlink socket */
+	if((nl_sock = nl_bound_sock()) < 0) return -1;
 
+	for (i = 0 ; i < sizeof(families)/sizeof(int); i++) {
+		fill_nl_req(req, RTM_GETADDR, families[i]);
+
+		if(send(nl_sock, (void*)&req, sizeof(req), 0) < 0){
+			LM_ERR("error sending NETLINK request\n");
+			goto error;
+		};
+
+		memset(buf, 0, sizeof(buf));
+		nll = 0;
+		p = buf;
+		while(1) {
+			rtn = recv(nl_sock, p, sizeof(buf) - nll, 0);
+			LM_DBG("received %d byles \n", rtn);
+			nlp = (struct nlmsghdr *) p;
+			if(nlp->nlmsg_type == NLMSG_DONE){
+				LM_DBG("done receiving netlink info \n");
+				 break;
+			}
+			if(nlp->nlmsg_type == NLMSG_ERROR){
+				 LM_ERR("Error on message to netlink");
+				 break;
+			}
+			p += rtn;
+
+			nll += rtn;
+		}
+
+		nlp = (struct nlmsghdr *) buf;
+		for(;NLMSG_OK(nlp, nll);nlp=NLMSG_NEXT(nlp, nll)){
+			ifi = NLMSG_DATA(nlp);
+
+			if (nlp->nlmsg_len < NLMSG_LENGTH(sizeof(ifi)))
+				continue;
+			// init all the strings
+			// inner loop: loop thru all the attributes of
+			// one route entry
+			rtap = (struct rtattr *) IFA_RTA(ifi);
+
+			rtl = IFA_PAYLOAD(nlp);
+
+			index = ifi->ifa_index;
+			if(index >= MAX_IFACE_NO){
+				LM_ERR("Invalid interface index returned: %d\n", index);
+				goto error;
+			}
+
+			entry = (struct idx*)pkg_malloc(sizeof(struct idx));
+			if(entry == 0)
+			{
+				LM_ERR("could not allocate memory\n");
+				goto error;
+			}
+
+			entry->next = 0;
+			entry->family = families[i];
+			entry->ifa_flags = ifi->ifa_flags;
+                        is_link_local = 0;
+
+			for(;RTA_OK(rtap, rtl);rtap=RTA_NEXT(rtap,rtl)){
+				switch(rtap->rta_type){
+					case IFA_ADDRESS:
+						if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
+							LM_DBG("Link Local Address, ignoring ...\n");
+							is_link_local = 1;
+							break;
+						}
+						inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
+						LM_DBG("iface <IFA_ADDRESS> addr is  %s\n", entry->addr);
+						break;
+					case IFA_LOCAL:
+						if((*(int*)RTA_DATA(rtap))== htons(0xfe80)){
+							LM_DBG("Link Local Address, ignoring ...\n");
+							is_link_local = 1;
+						}
+						inet_ntop(families[i], RTA_DATA(rtap), entry->addr, MAX_IF_LEN);
+						LM_DBG("iface <IFA_LOCAL> addr is %s\n", entry->addr);
+						break;
+					case IFA_LABEL:
+						LM_DBG("iface name is %s\n", (char*)RTA_DATA(rtap));
+						strncpy(name, (char*)RTA_DATA(rtap), MAX_IF_LEN);
+						break;
+					case IFA_BROADCAST:
+					case IFA_ANYCAST:
+					case IFA_UNSPEC:
+					case IFA_CACHEINFO:
+					default:
+						break;
+				}
+			}
+			if(is_link_local) continue;    /* link local addresses are not bindable */
+
+			if(strlen(ifaces[index].name)==0)
+				strncpy(ifaces[index].name, name, MAX_IF_LEN);
+
+			ifaces[index].index = index;
+
+			if(ifaces[index].addresses == 0 )
+				ifaces[index].addresses = entry;
+			else {
+				for(tmp = ifaces[index].addresses; tmp->next ; tmp = tmp->next)/*empty*/;
+				tmp->next = entry;
+			}
+		}
+	}
+	if(nl_sock>0) close(nl_sock);
+	/* the socket should be closed so we can bind again */
+	for(i = 0; i < sizeof(families)/sizeof(int); i++){
+		/* get device flags */
+		get_flags(families[i]); /* AF_INET or AF_INET6 */
+	}
+
+	return 0;
+error:
+	if(nl_sock>0) close(nl_sock);
+	return -1;
+
+}
+/* add all family type addresses of interface if_to the socket_info array
+ * if if_name==0, adds all addresses on all interfaces
+ * uses RTNETLINK sockets to get addresses on the present interface on LINUX
+ * return: -1 on error, 0 on success
+ */
+int add_interfaces_via_netlink(char* if_name, int family, unsigned short port,
+					unsigned short proto,
+					struct addr_info** ai_l)
+{
+	int i;
+	struct idx* tmp;
+	enum si_flags flags;
+
+	if(ifaces == NULL && (build_iface_list()!=0)){
+		LM_ERR("Could not get network interface list\n");
+		return -1;
+	}
+
+	flags=SI_NONE;
+	for(i=0; i< MAX_IFACE_NO; ++i){
+		if(ifaces[i].addresses == NULL) continue; /* not present/configured */
+		if ((if_name==0)||
+			(strncmp(if_name, ifaces[i].name, strlen(ifaces[i].name))==0)){
+
+			/* check if iface is up */
+			//if(! (ifaces[i].flags & IFF_UP) ) continue;
+
+			for(tmp = ifaces[i].addresses; tmp; tmp = tmp->next){
+				LM_DBG("\t in add_iface_via_netlink Name %s Adress %s\n", ifaces[i].name, tmp->addr);
+		                /* match family */
+                                if (family == tmp->family){
+					/* check if loopback */
+					if (ifaces[i].flags & IFF_LOOPBACK){
+						LM_DBG("INTERFACE %s is loopback", ifaces[i].name);
+						flags|=SI_IS_LO;
+					}
+					/* save the info */
+					if (new_addr_info2list(tmp->addr, flags, ai_l)!=0){
+						LOG(L_ERR, "ERROR: add_interfaces: "
+							"new_addr_info2list failed\n");
+						goto error;
+			    		}
+				}
+			}
+		}
+	}
+	return 0;
+error:
+	return -1;
+}
+#endif /* __OS_linux */
 
 /* add all family type addresses of interface if_name to the socket_info array
  * if if_name==0, adds all addresses on all interfaces
@@ -736,7 +1099,7 @@ int add_interfaces(char* if_name, int family, unsigned short port,
 	struct ip_addr addr;
 	int ret;
 	enum si_flags flags;
-	
+
 #ifdef HAVE_SOCKADDR_SA_LEN
 	#ifndef MAX
 		#define MAX(a,b) ( ((a)>(b))?(a):(b))
@@ -1345,25 +1708,46 @@ int fix_all_socket_lists()
 			&& (sctp_listen==0)
 #endif
 		){
-		/* get all listening ipv4 interfaces */
-		if ((add_interfaces(0, AF_INET, 0,  PROTO_UDP, &ai_lst)==0) &&
-			(addr_info_to_si_lst(ai_lst, 0, PROTO_UDP, 0, &udp_listen)==0)){
+		/* get all listening ipv4/ipv6 interfaces */
+		if ( ( (add_interfaces(0, AF_INET, 0,  PROTO_UDP, &ai_lst)==0)
+#ifdef USE_IPV6
+#ifdef __OS_linux
+		&&  (!auto_bind_ipv6 || add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_UDP, &ai_lst) == 0)
+#else
+		&& ( !auto_bind_ipv6 || add_interfaces(0, AF_INET6, 0,  PROTO_UDP, &ai_lst) !=0 ) /* add_interface does not work for IPv6 on Linux */
+#endif /* __OS_linux */
+#endif /* USE_IPV6 */
+			 ) && (addr_info_to_si_lst(ai_lst, 0, PROTO_UDP, 0, &udp_listen)==0)){
 			free_addr_info_lst(&ai_lst);
 			ai_lst=0;
 			/* if ok, try to add the others too */
 #ifdef USE_TCP
 			if (!tcp_disable){
-				if ((add_interfaces(0, AF_INET, 0,  PROTO_TCP, &ai_lst)!=0) ||
-					(addr_info_to_si_lst(ai_lst, 0, PROTO_TCP, 0,
+				if ( ((add_interfaces(0, AF_INET, 0,  PROTO_TCP, &ai_lst)!=0)
+#ifdef USE_IPV6
+#ifdef __OS_linux
+    				|| (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TCP, &ai_lst) != 0)
+#else
+				|| (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_TCP, &ai_lst) !=0 )
+#endif /* __OS_linux */
+#endif /* USE_IPV6 */
+				) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TCP, 0,
 										 				&tcp_listen)!=0))
 					goto error;
 				free_addr_info_lst(&ai_lst);
 				ai_lst=0;
 #ifdef USE_TLS
 				if (!tls_disable){
-					if ((add_interfaces(0, AF_INET, 0, PROTO_TLS,
-										&ai_lst)!=0) ||
-						(addr_info_to_si_lst(ai_lst, 0, PROTO_TLS, 0,
+					if (((add_interfaces(0, AF_INET, 0, PROTO_TLS,
+										&ai_lst)!=0)
+#ifdef USE_IPV6
+#ifdef __OS_linux
+    				|| (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_TLS, &ai_lst) != 0)
+#else
+				|| (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_TLS, &ai_lst)!=0)
+#endif /* __OS_linux */
+#endif /* USE_IPV6 */
+					) || (addr_info_to_si_lst(ai_lst, 0, PROTO_TLS, 0,
 										 				&tls_listen)!=0))
 						goto error;
 				}
@@ -1374,9 +1758,16 @@ int fix_all_socket_lists()
 #endif
 #ifdef USE_SCTP
 			if (!sctp_disable){
-				if ((add_interfaces(0, AF_INET, 0,  PROTO_SCTP, &ai_lst)!=0)||
-					(addr_info_to_si_lst(ai_lst, 0, PROTO_SCTP, 0,
-										 				&sctp_listen)!=0))
+				if (((add_interfaces(0, AF_INET, 0,  PROTO_SCTP, &ai_lst)!=0)
+#ifdef USE_IPV6
+#ifdef __OS_linux
+    				|| (auto_bind_ipv6 && add_interfaces_via_netlink(0, AF_INET6, 0, PROTO_SCTP, &ai_lst) != 0)
+#else
+				|| (auto_bind_ipv6 && add_interfaces(0, AF_INET6, 0,  PROTO_SCTP, &ai_lst) != 0)
+#endif /* __OS_linux */
+#endif /* USE_IPV6 */
+					) || (addr_info_to_si_lst(ai_lst, 0, PROTO_SCTP, 0,
+							 				&sctp_listen)!=0))
 					goto error;
 				free_addr_info_lst(&ai_lst);
 				ai_lst=0;