瀏覽代碼

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_MEM		dns_cache_mem
 DNS_CACHE_GC_INT	dns_cache_gc_interval
 DNS_CACHE_GC_INT	dns_cache_gc_interval
 DNS_CACHE_DEL_NONEXP	dns_cache_del_nonexp|dns_cache_delete_nonexpired
 DNS_CACHE_DEL_NONEXP	dns_cache_del_nonexp|dns_cache_delete_nonexpired
+/* ipv6 auto bind */
+AUTO_BIND_IPV6		auto_bind_ipv6
 /* blacklist */
 /* blacklist */
 DST_BLST_INIT	dst_blacklist_init
 DST_BLST_INIT	dst_blacklist_init
 USE_DST_BLST		use_dst_blacklist
 USE_DST_BLST		use_dst_blacklist
@@ -751,6 +753,8 @@ IMPORTFILE      "import_file"
 								return DNS_CACHE_GC_INT; }
 								return DNS_CACHE_GC_INT; }
 <INITIAL>{DNS_CACHE_DEL_NONEXP}	{ count(); yylval.strval=yytext;
 <INITIAL>{DNS_CACHE_DEL_NONEXP}	{ count(); yylval.strval=yytext;
 								return DNS_CACHE_DEL_NONEXP; }
 								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;
 <INITIAL>{DST_BLST_INIT}	{ count(); yylval.strval=yytext;
 								return DST_BLST_INIT; }
 								return DST_BLST_INIT; }
 <INITIAL>{USE_DST_BLST}	{ count(); yylval.strval=yytext;
 <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");\
 		if (rt!=ONSEND_ROUTE) yyerror( s " allowed only in onsend_routes");\
 	}while(0)
 	}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
 #ifdef USE_DNS_CACHE
 	#define IF_DNS_CACHE(x) x
 	#define IF_DNS_CACHE(x) x
@@ -419,6 +424,10 @@ extern char *finame;
 %token DNS_CACHE_MEM
 %token DNS_CACHE_MEM
 %token DNS_CACHE_GC_INT
 %token DNS_CACHE_GC_INT
 %token DNS_CACHE_DEL_NONEXP
 %token DNS_CACHE_DEL_NONEXP
+
+/* ipv6 auto bind */
+%token AUTO_BIND_IPV6
+
 /*blacklist*/
 /*blacklist*/
 %token DST_BLST_INIT
 %token DST_BLST_INIT
 %token USE_DST_BLST
 %token USE_DST_BLST
@@ -877,6 +886,8 @@ assign_stm:
 	| DNS_CACHE_GC_INT error { yyerror("boolean value expected"); }
 	| 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 EQUAL NUMBER   { IF_DNS_CACHE(default_core_cfg.dns_cache_del_nonexp=$3); }
 	| DNS_CACHE_DEL_NONEXP error { yyerror("boolean value expected"); }
 	| 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 EQUAL NUMBER   { IF_DST_BLACKLIST(dst_blacklist_init=$3); }
 	| DST_BLST_INIT error { yyerror("boolean value expected"); }
 	| DST_BLST_INIT error { yyerror("boolean value expected"); }
 	| USE_DST_BLST EQUAL NUMBER {
 	| USE_DST_BLST EQUAL NUMBER {

+ 11 - 5
etc/kamailio.cfg

@@ -87,11 +87,13 @@
 #!ifdef ACCDB_COMMENT
 #!ifdef ACCDB_COMMENT
   ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
   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_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_ouser VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE acc ADD COLUMN dst_user 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 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_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_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_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_user VARCHAR(64) NOT NULL DEFAULT '';
   ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) 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 ########
 ####### 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"
 mpath="modules_k:modules"
 #!else
 #!else
 mpath="/usr/local/lib/kamailio/modules_k/:/usr/local/lib/kamailio/modules/"
 mpath="/usr/local/lib/kamailio/modules_k/:/usr/local/lib/kamailio/modules/"
@@ -222,6 +224,7 @@ loadmodule "siputils.so"
 loadmodule "xlog.so"
 loadmodule "xlog.so"
 loadmodule "sanity.so"
 loadmodule "sanity.so"
 loadmodule "ctl.so"
 loadmodule "ctl.so"
+loadmodule "cfg_rpc.so"
 loadmodule "mi_rpc.so"
 loadmodule "mi_rpc.so"
 loadmodule "acc.so"
 loadmodule "acc.so"
 
 
@@ -318,7 +321,8 @@ modparam("acc", "detect_direction", 0)
 modparam("acc", "log_flag", FLT_ACC)
 modparam("acc", "log_flag", FLT_ACC)
 modparam("acc", "log_missed_flag", FLT_ACCMISSED)
 modparam("acc", "log_missed_flag", FLT_ACCMISSED)
 modparam("acc", "log_extra", 
 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)
 modparam("acc", "failed_transaction_flag", FLT_ACCFAILED)
 /* enhanced DB accounting */
 /* enhanced DB accounting */
 #!ifdef WITH_ACCDB
 #!ifdef WITH_ACCDB
@@ -326,7 +330,8 @@ modparam("acc", "db_flag", FLT_ACC)
 modparam("acc", "db_missed_flag", FLT_ACCMISSED)
 modparam("acc", "db_missed_flag", FLT_ACCMISSED)
 modparam("acc", "db_url", DBURL)
 modparam("acc", "db_url", DBURL)
 modparam("acc", "db_extra",
 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
 #!endif
 
 
 
 
@@ -438,7 +443,8 @@ modparam("debugger", "cfgtrace", 1)
 
 
 # Main SIP request routing logic
 # Main SIP request routing logic
 # - processing of any incoming SIP request starts with this route
 # - processing of any incoming SIP request starts with this route
-route {
+# - note: this is the same as route { ... }
+request_route {
 
 
 	# per request initial checks
 	# per request initial checks
 	route(REQINIT);
 	route(REQINIT);

+ 4 - 0
globals.h

@@ -137,6 +137,10 @@ extern int stun_allow_stun;
 extern int stun_allow_fp;
 extern int stun_allow_fp;
 #endif
 #endif
 
 
+#ifdef USE_IPV6
+extern int auto_bind_ipv6;
+#endif
+
 extern int tos;
 extern int tos;
 extern int pmtu_discovery;
 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 tos = IPTOS_LOWDELAY;
 int pmtu_discovery = 0;
 int pmtu_discovery = 0;
 
 
+#ifdef USE_IPV6
+int auto_bind_ipv6 = 0;
+#endif
+
 #if 0
 #if 0
 char* names[MAX_LISTEN];              /* our names */
 char* names[MAX_LISTEN];              /* our names */
 int names_len[MAX_LISTEN];            /* lengths of the 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));
 	memset(&val, 0, sizeof(pv_value_t));
 	if(pv_get_spec_value(env_L->msg, &pvs, &val) != 0)
 	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)
 	if(val.flags&PV_VAL_NULL)
 	{
 	{

+ 182 - 70
modules/cfg_rpc/README

@@ -4,80 +4,192 @@ Miklos Tirpak
 
 
    <[email protected]>
    <[email protected]>
 
 
-   Copyright © 2007 iptelorg GmbH
+   Copyright © 2007 iptelorg GmbH
      __________________________________________________________________
      __________________________________________________________________
 
 
    1.1. Overview
    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
 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
    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[] = {
 static rpc_export_t rpc_calls[] = {
 	{"cfg.set",		rpc_set,		rpc_set_now_doc,	0},
 	{"cfg.set",		rpc_set,		rpc_set_now_doc,	0},
 	{"cfg.set_now_int",	rpc_set_now_int,	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.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.del",		rpc_del,		rpc_del_now_doc,	0},
 	{"cfg.set_delayed",	rpc_set_delayed,	rpc_set_delayed_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},
 	{"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">
     <section id="cfg_rpc.overview">
 	<title>Overview</title>
 	<title>Overview</title>
 	<para>
 	<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
 	    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>
 	</para>
     </section>
     </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"/>
     <xi:include href="rpc.xml"/>
 
 
 </section>
 </section>

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

@@ -7,28 +7,85 @@
     <title>RPC Interface</title>
     <title>RPC Interface</title>
 
 
     <para>
     <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>
 	    <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.
 		a configuration variable and commit the change immediately.
 		The function accepts three parameters: group name, variable
 		The function accepts three parameters: group name, variable
 		name, integer value. The group name can optionally contain the
 		name, integer value. The group name can optionally contain the
 		group instance id, for example foo[5].
 		group instance id, for example foo[5].
 	    </para>
 	    </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.
 		a configuration variable and commit the change immediately.
 		The function accepts three parameters: group name, variable
 		The function accepts three parameters: group name, variable
 		name, string value. The group name can optionally contain the
 		name, string value. The group name can optionally contain the
 		group instance id, for example foo[5].
 		group instance id, for example foo[5].
 	    </para>
 	    </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>
 	    <para>
 		<emphasis>cfg.set</emphasis> - Set the value of
 		<emphasis>cfg.set</emphasis> - Set the value of
 		a configuration variable and commit the change immediately.
 		a configuration variable and commit the change immediately.
@@ -38,8 +95,9 @@
 		name, int/string value. The group name can optionally contain the
 		name, int/string value. The group name can optionally contain the
 		group instance id, for example foo[5].
 		group instance id, for example foo[5].
 	    </para>
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.del">
+    <title>cfg.del</title>
 	    <para>
 	    <para>
 		<emphasis>cfg.del</emphasis> - Delete the value of
 		<emphasis>cfg.del</emphasis> - Delete the value of
 		a configuration variable from a group instance and commit the change immediately.
 		a configuration variable from a group instance and commit the change immediately.
@@ -49,8 +107,9 @@
 		name. The group name must contain the
 		name. The group name must contain the
 		group instance id, for example foo[5].
 		group instance id, for example foo[5].
 	    </para>
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.set_delayed_int">
+    <title>cfg.set_delayed_int</title>
 	    <para>
 	    <para>
 		<emphasis>cfg.set_delayed_int</emphasis> - Prepare the change of
 		<emphasis>cfg.set_delayed_int</emphasis> - Prepare the change of
 		a configuration variable, but does not commit the new value yet.
 		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
 		name, integer value. The group name can optionally contain the
 		group instance id, for example foo[5].
 		group instance id, for example foo[5].
 	    </para>
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.set_delayed_string">
+    <title>cfg.set_delayed_string</title>
 	    <para>
 	    <para>
 		<emphasis>cfg.set_delayed_string</emphasis> - Prepare the change of
 		<emphasis>cfg.set_delayed_string</emphasis> - Prepare the change of
 		a configuration variable, but does not commit the new value yet.
 		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
 		name, string value. The group name can optionally contain the
 		group instance id, for example foo[5].
 		group instance id, for example foo[5].
 	    </para>
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.set_delayed">
+    <title>cfg.set_delayed</title>
 	    <para>
 	    <para>
 		<emphasis>cfg.set_delayed</emphasis> - Prepare the change of
 		<emphasis>cfg.set_delayed</emphasis> - Prepare the change of
 		a configuration variable, but does not commit the new value yet.
 		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
 		name, int/string value. The group name can optionally contain the
 		group instance id, for example foo[5].
 		group instance id, for example foo[5].
 	    </para>
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.del_delayed">
+    <title>cfg.del_delayed</title>
 	    <para>
 	    <para>
 		<emphasis>cfg.del_delayed</emphasis> - Prepare the deletion of the value of
 		<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.
 		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
 		name. The group name must contain the
 		group instance id, for example foo[5].
 		group instance id, for example foo[5].
 	    </para>
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.commit">
+    <title>cfg.commit</title>
 	    <para>
 	    <para>
 		<emphasis>cfg.commit</emphasis> - Commit the previously
 		<emphasis>cfg.commit</emphasis> - Commit the previously
 		prepared configuration changes. The function does not have
 		prepared configuration changes. The function does not have
 		any parameters.
 		any parameters.
 	    </para>
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.rollback">
+    <title>cfg.rollback</title>
 	    <para>
 	    <para>
 		<emphasis>cfg.rollback</emphasis> - Drop the prepared
 		<emphasis>cfg.rollback</emphasis> - Drop the prepared
 		configuration changes. The function does not have any
 		configuration changes. The function does not have any
 		parameters.
 		parameters.
 	    </para>
 	    </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>
 	    <para>
 		<emphasis>cfg.help</emphasis> - Print the description of
 		<emphasis>cfg.help</emphasis> - Print the description of
 		a configuration variable. The function accepts two parameters:
 		a configuration variable. The function accepts two parameters:
 		group name, variable name.
 		group name, variable name.
 	    </para>
 	    </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>
 	    <para>
 		<emphasis>cfg.diff</emphasis> - List the pending
 		<emphasis>cfg.diff</emphasis> - List the pending
 		configuration changes that have not been committed yet.
 		configuration changes that have not been committed yet.
 		The function does not have any parameters.
 		The function does not have any parameters.
 	    </para>
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.add_group_inst">
+    <title>cfg.add_group_inst</title>
 	    <para>
 	    <para>
 		<emphasis>cfg.add_group_inst</emphasis> - Add a new instance
 		<emphasis>cfg.add_group_inst</emphasis> - Add a new instance
 		to an existing configuration group. The function accepts one parameter:
 		to an existing configuration group. The function accepts one parameter:
 		group name[instance id], for example foo[5].
 		group name[instance id], for example foo[5].
 	    </para>
 	    </para>
-	</listitem>
-	<listitem>
+	</section>
+	<section id="cfg_rpc.rpc.del_group_inst">
+    <title>cfg.del_group_inst</title>
 	    <para>
 	    <para>
 		<emphasis>cfg.del_group_inst</emphasis> - Delete an instance
 		<emphasis>cfg.del_group_inst</emphasis> - Delete an instance
 		of an existing configuration group. The function accepts one parameter:
 		of an existing configuration group. The function accepts one parameter:
 		group name[instance id], for example foo[5].
 		group name[instance id], for example foo[5].
 	    </para>
 	    </para>
-	</listitem>
-    </itemizedlist>
+	</section>
 </section>
 </section>

+ 1 - 1
modules/ctl/ctl_defaults.h

@@ -4,7 +4,7 @@
 #ifndef __ctl_defaults_h
 #ifndef __ctl_defaults_h
 #define __ctl_defaults_h
 #define __ctl_defaults_h
 /*listen by default on: */
 /*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 */
 /* port used by default for tcp/udp if no port is explicitely specified */
 #define DEFAULT_CTL_PORT 2049
 #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{
 struct hep_hdr{
     u_int8_t hp_v;            /* version */
     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;
 	    val_arr[n].len = 0;
 	} else if (value.flags&PV_VAL_INT) {
 	} else if (value.flags&PV_VAL_INT) {
 	    /* len = -1 denotes int type */
 	    /* 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;
 	    val_arr[n].len = -1;
 	} else {
 	} else {
 	    /* set the value into the acc buffer */
 	    /* 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) {
 	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;
 		return -1;
 	}
 	}
 	if (register_script_cb(dlg_cfg_cb,
 	if (register_script_cb(dlg_cfg_cb,
 				PRE_SCRIPT_CB|REQUEST_CB,0)<0)
 				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;
 		return -1;
 	}
 	}
 	if (register_script_cb(dlg_cfg_cb,
 	if (register_script_cb(dlg_cfg_cb,
 				POST_SCRIPT_CB|REQUEST_CB,0)<0)
 				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;
 		return -1;
 	}
 	}
 
 

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

@@ -1434,6 +1434,15 @@ dlg_refer("caller", "sip:[email protected]");
 		<para>
 		<para>
 		This function can be used from REQUEST_ROUTE.
 		This function can be used from REQUEST_ROUTE.
 		</para>
 		</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>
 		<example>
 		<title><function>dlg_manage</function> usage</title>
 		<title><function>dlg_manage</function> usage</title>
 		<programlisting format="linespecific">
 		<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];
 	static char hn[256];
 	struct hostent* he;
 	struct hostent* he;
 	struct sip_uri puri;
 	struct sip_uri puri;
+	int orig_id = 0, orig_nr = 0;
+	ds_set_t *orig_ds_lists = ds_lists[list_idx];
 
 
 	/* check uri */
 	/* check uri */
 	if(parse_uri(uri.s, uri.len, &puri)!=0 || puri.host.len>254)
 	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;
 		ds_lists[list_idx] = sp;
 		*setn = *setn+1;
 		*setn = *setn+1;
 	}
 	}
+	orig_id = sp->id;
+	orig_nr = sp->nr;
 	sp->id = id;
 	sp->id = id;
 	sp->nr++;
 	sp->nr++;
 
 
@@ -365,6 +369,18 @@ err:
 			shm_free(dp->uri.s);
 			shm_free(dp->uri.s);
 		shm_free(dp);
 		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;
 	return -1;
 }
 }
 
 
@@ -566,9 +582,8 @@ int ds_load_list(char *lfile)
 add_destination:
 add_destination:
 		if(add_dest2list(id, uri, flags, priority, &attrs,
 		if(add_dest2list(id, uri, flags, priority, &attrs,
 					*next_idx, &setn) != 0)
 					*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:
 next_line:
 		p = fgets(line, 256, f);
 		p = fgets(line, 256, f);
 	}
 	}
@@ -720,11 +735,7 @@ int ds_load_db(void)
 	nr_rows = RES_ROW_N(res);
 	nr_rows = RES_ROW_N(res);
 	rows 	= RES_ROWS(res);
 	rows 	= RES_ROWS(res);
 	if(nr_rows == 0)
 	if(nr_rows == 0)
-	{
 		LM_WARN("no dispatching data in the db -- empty destination set\n");
 		LM_WARN("no dispatching data in the db -- empty destination set\n");
-		ds_dbf.free_result(ds_db_handle, res);
-		return 0;
-	}
 
 
 	setn = 0;
 	setn = 0;
 	*next_idx = (*crt_idx + 1)%2;
 	*next_idx = (*crt_idx + 1)%2;
@@ -752,8 +763,8 @@ int ds_load_db(void)
 		}
 		}
 		if(add_dest2list(id, uri, flags, priority, &attrs,
 		if(add_dest2list(id, uri, flags, priority, &attrs,
 					*next_idx, &setn) != 0)
 					*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);
 	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;
 	    val_arr[n].len = 0;
 	} else if (value.flags&PV_VAL_INT) {
 	} else if (value.flags&PV_VAL_INT) {
 	    /* len = -1 denotes int type */
 	    /* 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;
 	    val_arr[n].len = -1;
 	} else {
 	} else {
 	    /* set the value into the acc buffer */
 	    /* 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 */
     /* 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)) {
     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("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");
         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)
 			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)
 			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},
 		    fixup_free_set_uri,	ANY_ROUTE},
 	{"set_uri_host", (cmd_function)set_uri_host,             2, fixup_set_uri,
 	{"set_uri_host", (cmd_function)set_uri_host,             2, fixup_set_uri,
 		    fixup_free_set_uri,	ANY_ROUTE},
 		    fixup_free_set_uri,	ANY_ROUTE},
-	{"bind_siputils",       (cmd_function)bind_siputils,           0, 0,
+	{"bind_siputils",       (cmd_function)bind_siputils,           1, 0,
 			0, 0},
 			0, 0},
 	{"is_request",          (cmd_function)w_is_request,            0, 0,
 	{"is_request",          (cmd_function)w_is_request,            0, 0,
 			0, ANY_ROUTE},
 			0, ANY_ROUTE},

+ 24 - 7
modules_k/snmpstats/README

@@ -8,7 +8,7 @@ Edited by
 
 
 Jeffrey Magder
 Jeffrey Magder
 
 
-   Copyright © 2006 SOMA Networks, Inc.
+   Copyright © 2006 SOMA Networks, Inc.
      __________________________________________________________________
      __________________________________________________________________
 
 
    Table of Contents
    Table of Contents
@@ -40,6 +40,7 @@ Jeffrey Magder
               4.5. dlg_major_threshold (Integer)
               4.5. dlg_major_threshold (Integer)
               4.6. snmpgetPath (String)
               4.6. snmpgetPath (String)
               4.7. snmpCommunity (String)
               4.7. snmpCommunity (String)
+              4.8. export_registrar (int)
 
 
         5. Functions
         5. Functions
         6. Installation and Running
         6. Installation and Running
@@ -64,6 +65,7 @@ Jeffrey Magder
    1.5. Setting the dlg_major_threshold parameter
    1.5. Setting the dlg_major_threshold parameter
    1.6. Setting the snmpgetPath parameter
    1.6. Setting the snmpgetPath parameter
    1.7. Setting the snmpCommunity parameter
    1.7. Setting the snmpCommunity parameter
+   1.8. Setting the export_registrar parameter
 
 
 Chapter 1. Admin Guide
 Chapter 1. Admin Guide
 
 
@@ -94,6 +96,7 @@ Chapter 1. Admin Guide
         4.5. dlg_major_threshold (Integer)
         4.5. dlg_major_threshold (Integer)
         4.6. snmpgetPath (String)
         4.6. snmpgetPath (String)
         4.7. snmpCommunity (String)
         4.7. snmpCommunity (String)
+        4.8. export_registrar (int)
 
 
    5. Functions
    5. Functions
    6. Installation and Running
    6. Installation and Running
@@ -275,6 +278,7 @@ Chapter 1. Admin Guide
    4.5. dlg_major_threshold (Integer)
    4.5. dlg_major_threshold (Integer)
    4.6. snmpgetPath (String)
    4.6. snmpgetPath (String)
    4.7. snmpCommunity (String)
    4.7. snmpCommunity (String)
+   4.8. export_registrar (int)
 
 
 4.1. sipEntityType (String)
 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
    the master agent. You can use this parameter to set the path to your
    instance of NetSNMP's snmpget program.
    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
    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
    the master agent. If you have defined a custom community string for the
    snmp daemon, you need to specify it with this parameter.
    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
    Example 1.7. Setting the snmpCommunity parameter
 ...
 ...
 modparam("snmpstats", "snmpCommunity", "customCommunityString")
 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
 5. Functions
 
 
    Currently, there are no exported 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
    There are several things that need to be done to get the SNMPStats
    module compiled and up and running.
    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
    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:
    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
    recommended you install NetSNMP from source to avoid bringing in
    excessive dependencies to the SNMPStats module.
    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.
    The SNMPStats module will communicate with the NetSNMP Master Agent.
    This communication happens over a protocol known as AgentX. This means
    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
    This tells NetSNMP to act as a master agent, listening on the localhost
    UDP interface at port 705.
    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
    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
    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
    be present on the same machine as OpenSER. localhost could be replaced
    with any other machine.
    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
    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
    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>
 		</example>
 	</section>
 	</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>
 	<section>
 	<section>
 	<title>Functions</title>
 	<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 
              -1 indicates the value is not configured, and alarms will never be 
              set, and the usage state will never be reported as 'busy'."
              set, and the usage state will never be reported as 'busy'."
         ::= { openserDialogStats 6 }
         ::= { 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
 -- Dialog State
 --
 --
@@ -601,7 +611,8 @@ OPENSER-MIB DEFINITIONS ::= BEGIN
             openserCurNumDialogsInSetup,
             openserCurNumDialogsInSetup,
             openserTotalNumFailedDialogSetups,
             openserTotalNumFailedDialogSetups,
             openserDialogLimitMinorThreshold,
             openserDialogLimitMinorThreshold,
-            openserDialogLimitMajorThreshold           
+            openserDialogLimitMajorThreshold,
+            openserTotalNumDialogSetups
         }
         }
         STATUS  current
         STATUS  current
         DESCRIPTION
         DESCRIPTION

+ 28 - 0
modules_k/snmpstats/snmpObjects.c

@@ -94,6 +94,9 @@ void init_openserObjects(void)
 	static oid openserDialogLimitMajorThreshold_oid[]  = 
 	static oid openserDialogLimitMajorThreshold_oid[]  = 
 		{ OPENSER_OID,3,1,3,1,3,2,6 };
 		{ 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[]       = 
 	static oid openserDialogUsageState_oid[]       = 
 		{ OPENSER_OID,3,1,3,1,3,3,1 };
 		{ OPENSER_OID,3,1,3,1,3,3,1 };
 
 
@@ -217,6 +220,15 @@ void init_openserObjects(void)
 			HANDLER_CAN_RONLY)
 			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_register_scalar(
 		netsnmp_create_handler_registration(
 		netsnmp_create_handler_registration(
 			"openserDialogUsageState", 
 			"openserDialogUsageState", 
@@ -467,6 +479,22 @@ int handle_openserTotalNumFailedDialogSetups(netsnmp_mib_handler *handler,
 	return SNMP_ERR_GENERR;
 	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,
 int handle_openserDialogLimitMinorThreshold(netsnmp_mib_handler *handler,
 		netsnmp_handler_registration *reginfo,
 		netsnmp_handler_registration *reginfo,
 		netsnmp_agent_request_info   *reqinfo,
 		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_openserTotalNumFailedDialogSetups;
 Netsnmp_Node_Handler handle_openserDialogLimitMinorThreshold;
 Netsnmp_Node_Handler handle_openserDialogLimitMinorThreshold;
 Netsnmp_Node_Handler handle_openserDialogLimitMajorThreshold;
 Netsnmp_Node_Handler handle_openserDialogLimitMajorThreshold;
+Netsnmp_Node_Handler handle_openserTotalNumDialogSetups;
 Netsnmp_Node_Handler handle_openserDialogUsageState;
 Netsnmp_Node_Handler handle_openserDialogUsageState;
 Netsnmp_Node_Handler handle_openserDialogLimitAlarmStatus;
 Netsnmp_Node_Handler handle_openserDialogLimitAlarmStatus;
 Netsnmp_Node_Handler handle_openserDialogLimitMinorAlarm;
 Netsnmp_Node_Handler handle_openserDialogLimitMinorAlarm;

+ 25 - 15
modules_k/snmpstats/snmpstats.c

@@ -107,6 +107,10 @@
 /* Required in every Kamailio Module. */
 /* Required in every Kamailio Module. */
 MODULE_VERSION
 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 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
  * 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
  * 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          },
 			(void *)set_snmpget_path          },
 	{ "snmpCommunity",          STR_PARAM|USE_FUNC_PARAM,
 	{ "snmpCommunity",          STR_PARAM|USE_FUNC_PARAM,
 			(void *)set_snmp_community        },
 			(void *)set_snmp_community        },
+	{ "snmpCommunity",          STR_PARAM|USE_FUNC_PARAM,
+			(void *)set_snmp_community        },
+	{ "export_registrar",       INT_PARAM,
+			&snmp_export_registrar            },
 	{ 0,0,0 }
 	{ 0,0,0 }
 };
 };
 
 
@@ -318,24 +326,26 @@ static int mod_init(void)
 	 * the database.  That load will happen if a lookup() function is come
 	 * the database.  That load will happen if a lookup() function is come
 	 * across in kamailio.cfg. */
 	 * 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 the alarm checking function to run periodically */
 	register_timer(run_alarm_check, 0, ALARM_AGENT_FREQUENCY_IN_SECONDS);
 	register_timer(run_alarm_check, 0, ALARM_AGENT_FREQUENCY_IN_SECONDS);
 
 

+ 403 - 12
socket_info.c

@@ -1,3 +1,4 @@
+
 /* $Id$
 /* $Id$
  *
  *
  * find & manage listen addresses 
  * find & manage listen addresses 
@@ -713,7 +714,369 @@ error:
 	return -1;
 	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
 /* add all family type addresses of interface if_name to the socket_info array
  * if if_name==0, adds all addresses on all interfaces
  * 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;
 	struct ip_addr addr;
 	int ret;
 	int ret;
 	enum si_flags flags;
 	enum si_flags flags;
-	
+
 #ifdef HAVE_SOCKADDR_SA_LEN
 #ifdef HAVE_SOCKADDR_SA_LEN
 	#ifndef MAX
 	#ifndef MAX
 		#define MAX(a,b) ( ((a)>(b))?(a):(b))
 		#define MAX(a,b) ( ((a)>(b))?(a):(b))
@@ -1345,25 +1708,46 @@ int fix_all_socket_lists()
 			&& (sctp_listen==0)
 			&& (sctp_listen==0)
 #endif
 #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);
 			free_addr_info_lst(&ai_lst);
 			ai_lst=0;
 			ai_lst=0;
 			/* if ok, try to add the others too */
 			/* if ok, try to add the others too */
 #ifdef USE_TCP
 #ifdef USE_TCP
 			if (!tcp_disable){
 			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))
 										 				&tcp_listen)!=0))
 					goto error;
 					goto error;
 				free_addr_info_lst(&ai_lst);
 				free_addr_info_lst(&ai_lst);
 				ai_lst=0;
 				ai_lst=0;
 #ifdef USE_TLS
 #ifdef USE_TLS
 				if (!tls_disable){
 				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))
 										 				&tls_listen)!=0))
 						goto error;
 						goto error;
 				}
 				}
@@ -1374,9 +1758,16 @@ int fix_all_socket_lists()
 #endif
 #endif
 #ifdef USE_SCTP
 #ifdef USE_SCTP
 			if (!sctp_disable){
 			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;
 					goto error;
 				free_addr_info_lst(&ai_lst);
 				free_addr_info_lst(&ai_lst);
 				ai_lst=0;
 				ai_lst=0;