瀏覽代碼

Merge remote branch 'origin/tmp/k3.0_sr_backports' into sr_3.0

* origin/tmp/k3.0_sr_backports: (86 commits)
  usrloc(k): rpc version for ul.dump
  core: init the len of sock_str attribute
  ctl: added parameters to control buffer size
  htable(k): rpc commad to dump htable
  pv(k): fixed $shv engine
  sanity: print From hdr in warning message
  nathelper(k): print bad contact uri
  core: more verbose when error parsing hdr
  kamailio.cfg: updated cfg with sample PSTN gw routing
  nathelper(k): fix for swap scenario
  presence(k): aliased MLA to SLA
  core: event parsing enahced for dialog;ma
  tm: documented t_relay_to() function
  tm: added t_relay_to(proxy, flags)
  tm: documented t_replicate() functions
  tm: t_replicate() can take avps & select as params
  tm: added t_replicate(uri)
  db_oracle: use PARAM_TYPE_MASK when checking param type
  snmpstats: fix param type checking
  core: define module_loaded to use find_module_by_name
  ...
Andrei Pelinescu-Onciul 15 年之前
父節點
當前提交
0e1baf00ab
共有 100 個文件被更改,包括 3068 次插入1216 次删除
  1. 1 0
      .gitignore
  2. 69 2
      Makefile
  3. 13 3
      Makefile.defs
  4. 154 3
      cfg.lex
  5. 302 228
      etc/kamailio.cfg
  6. 8 1
      lib/srdb1/schema/dialog.xml
  7. 80 0
      lib/srdb1/schema/dr_gateways.xml
  8. 64 0
      lib/srdb1/schema/dr_groups.xml
  9. 47 0
      lib/srdb1/schema/dr_gw_lists.xml
  10. 86 0
      lib/srdb1/schema/dr_rules.xml
  11. 16 0
      lib/srdb1/schema/kamailio-drouting.xml
  12. 25 3
      modules/ctl/README
  13. 4 3
      modules/ctl/binrpc_run.c
  14. 12 1
      modules/ctl/ctl.c
  15. 36 0
      modules/ctl/doc/params.xml
  16. 10 0
      modules/db_berkeley/Makefile
  17. 8 0
      modules/db_mysql/Makefile
  18. 10 0
      modules/db_postgres/Makefile
  19. 119 43
      modules/tm/README
  20. 156 3
      modules/tm/doc/functions.xml
  21. 76 15
      modules/tm/t_funcs.c
  22. 2 2
      modules/tm/t_hooks.c
  23. 35 11
      modules/tm/t_reply.c
  24. 1 1
      modules/tm/t_reply.h
  25. 25 1
      modules/tm/timer.c
  26. 217 1
      modules/tm/tm.c
  27. 62 30
      modules/topoh/README
  28. 40 0
      modules/topoh/doc/topoh_admin.xml
  29. 132 4
      modules/topoh/th_msg.c
  30. 2 0
      modules/topoh/th_msg.h
  31. 7 1
      modules/topoh/topoh_mod.c
  32. 10 0
      modules_k/db_oracle/Makefile
  33. 1 1
      modules_k/db_oracle/asynch.c
  34. 10 0
      modules_k/db_text/Makefile
  35. 15 0
      modules_k/dialog/dialog.c
  36. 16 7
      modules_k/dialog/dlg_db_handler.c
  37. 3 2
      modules_k/dialog/dlg_db_handler.h
  38. 9 1
      modules_k/dialog/dlg_handlers.c
  39. 13 3
      modules_k/dialog/dlg_hash.c
  40. 3 1
      modules_k/dialog/dlg_hash.h
  41. 10 0
      modules_k/dialog/dlg_profile.c
  42. 4 0
      modules_k/dialog/dlg_profile.h
  43. 4 3
      modules_k/dialog/dlg_transfer.c
  44. 68 92
      modules_k/drouting/README
  45. 4 4
      modules_k/drouting/doc/drouting_admin.xml
  46. 21 9
      modules_k/drouting/dr_load.c
  47. 101 0
      modules_k/htable/htable.c
  48. 3 0
      modules_k/nat_traversal/Makefile
  49. 1 0
      modules_k/nat_traversal/nat_traversal.c
  50. 4 2
      modules_k/nathelper/nathelper.c
  51. 2 1
      modules_k/nathelper/nhelpr_funcs.c
  52. 4 2
      modules_k/perl/Makefile
  53. 11 8
      modules_k/presence/subscribe.c
  54. 2 1
      modules_k/presence/utils_func.h
  55. 7 4
      modules_k/presence_xml/README
  56. 19 5
      modules_k/presence_xml/doc/presence_xml_admin.xml
  57. 13 3
      modules_k/pua_dialoginfo/dialog_publish.c
  58. 51 14
      modules_k/pua_dialoginfo/pua_dialoginfo.c
  59. 4 1
      modules_k/pua_dialoginfo/pua_dialoginfo.h
  60. 2 5
      modules_k/pv/pv.c
  61. 82 0
      modules_k/pv/pv_branch.c
  62. 4 0
      modules_k/pv/pv_branch.h
  63. 1 1
      modules_k/pv/pv_core.c
  64. 42 159
      modules_k/pv/pv_shv.c
  65. 0 1
      modules_k/pv/pv_shv.h
  66. 1 1
      modules_k/snmpstats/snmpObjects.c
  67. 1 1
      modules_k/snmpstats/utilities.c
  68. 3 3
      modules_k/uac/auth.c
  69. 1 0
      modules_k/uac/uac_send.c
  70. 8 0
      modules_k/usrloc/ul_mod.c
  71. 293 0
      modules_k/usrloc/ul_rpc.c
  72. 28 0
      modules_k/usrloc/ul_rpc.h
  73. 1 1
      modules_s/sanity/sanity.c
  74. 2 1
      parser/msg_parser.c
  75. 9 0
      parser/parse_param.c
  76. 3 1
      parser/parse_param.h
  77. 7 0
      pkg/kamailio/debian-lenny/changelog
  78. 0 3
      pkg/kamailio/debian-lenny/patches/00list
  79. 0 27
      pkg/kamailio/debian-lenny/patches/10_no_lib64_on_64_bits.dpatch
  80. 0 24
      pkg/kamailio/debian-lenny/patches/11_always_smp.dpatch
  81. 55 16
      pkg/kamailio/debian-lenny/rules
  82. 14 0
      pkg/kamailio/debian/changelog
  83. 32 49
      pkg/kamailio/debian/control
  84. 0 3
      pkg/kamailio/debian/patches/00list
  85. 0 27
      pkg/kamailio/debian/patches/10_no_lib64_on_64_bits.dpatch
  86. 0 24
      pkg/kamailio/debian/patches/11_always_smp.dpatch
  87. 156 311
      pkg/kamailio/debian/rules
  88. 1 0
      socket_info.c
  89. 5 1
      sr_module.c
  90. 4 14
      sr_module.h
  91. 11 3
      utils/kamctl/Makefile
  92. 2 2
      utils/kamctl/db_berkeley/kamailio/dialog
  93. 12 4
      utils/kamctl/db_berkeley/kamailio/version
  94. 1 1
      utils/kamctl/dbtext/kamailio/dialog
  95. 7 3
      utils/kamctl/dbtext/kamailio/version
  96. 2 5
      utils/kamctl/kamctl
  97. 3 2
      utils/kamctl/mysql/dialog-create.sql
  98. 39 0
      utils/kamctl/mysql/drouting-create.sql
  99. 2 1
      utils/kamctl/mysql/lcr-create.sql
  100. 2 2
      utils/kamctl/mysql/permissions-create.sql

+ 1 - 0
.gitignore

@@ -11,6 +11,7 @@ modules.lst
 *.d
 # ignore binary files and objects
 ser
+kamailio
 *.so
 *.so.*
 *.o

+ 69 - 2
Makefile

@@ -194,6 +194,71 @@ module_group_stable=cpl-c dbtext jabber osp sms pdb
 # not have dependencies
 module_group_experimental=tls oracle iptrtpproxy
 
+# Kamailio specific groups
+# Standard modules in K Debian distro
+module_group_kstandard=acc alias_db auth auth_db benchmark call_control \
+				cfgutils db_text dialog dispatcher diversion domain drouting \
+				exec group htable imc kex maxfwd mi_datagram mi_fifo msilo \
+				nat_traversal nathelper path pdt permissions pike pv qos \
+				ratelimit regex registrar rr rtimer siptrace siputils sl sms \
+				speeddial sqlops sst statistics textops tmx uac uac_redirect \
+				uri_db userblacklist usrloc xlog \
+				avpops cfg_db cfg_rpc ctl db_flatstore dialplan enum \
+				iptrtpproxy lcr mediaproxy mi_rpc pdb sanity tm topoh
+
+# K mysql module
+module_group_kmysql=db_mysql
+
+# K postgress module
+module_group_kpostgres=db_postgres
+
+# K cpl module
+module_group_kcpl=cpl-c
+
+# K radius modules
+module_group_kradius=auth_radius misc_radius peering
+
+# K unixodbc module
+module_group_kunixodbc=db_unixodbc
+
+# K xmlrpc modules
+module_group_kxmlrpc=xmlrpc mi_xmlrpc
+
+# K perl module
+module_group_kperl=perl perlvdb
+
+# K snmpstats module
+module_group_ksnmpstats=snmpstats
+
+# K xmpp module
+module_group_kxmpp=xmpp
+
+# K carrierroute module
+module_group_kcarrierroute=carrierroute
+
+# K berkeley module
+module_group_kberkeley=db_berkeley
+
+# K ldap modules
+module_group_kldap=ldap h350
+
+# K utils module
+module_group_kutils=utils
+
+# K purple module
+module_group_kpurple=purple
+
+# K memcached module
+module_group_kmemcached=memcached
+
+# K tls module
+module_group_ktls=tls
+
+# K presence modules
+module_group_kpresence=presence presence_dialoginfo presence_mwi presence_xml \
+						pua pua_bla pua_dialoginfo pua_mi pua_usrloc pua_xmpp \
+						rls xcap_client
+
 # if not set on the cmd. line, env or in the modules.lst (cfg_group_include)
 # exclude the below modules.
 ifneq ($(group_include)$(cfg_group_include),)
@@ -947,7 +1012,8 @@ install-sr-man: $(man_prefix)/$(man_dir)/man8 $(man_prefix)/$(man_dir)/man5
 			$(foreach m,$(modules_dirs),\
 				-e "s#/usr/lib/$(CFG_NAME)/$(m)\([^_]\)#$($(m)_target)\1#g") \
 			-e "s#/usr/share/doc/$(CFG_NAME)/#$(doc_target)#g" \
-			< $(CFG_NAME).8 >  \
+			-e "s#$(SRC_NAME)#$(MAIN_NAME)#g" \
+			< $(SRC_NAME).8 >  \
 							$(man_prefix)/$(man_dir)/man8/$(MAIN_NAME).8
 		@chmod 644  $(man_prefix)/$(man_dir)/man8/$(MAIN_NAME).8
 		@sed -e "s#/etc/$(CFG_NAME)/$(CFG_NAME)\.cfg#$(cfg_target)$(MAIN_NAME).cfg#g" \
@@ -955,7 +1021,8 @@ install-sr-man: $(man_prefix)/$(man_dir)/man8 $(man_prefix)/$(man_dir)/man5
 			$(foreach m,$(modules_dirs),\
 				-e "s#/usr/lib/$(CFG_NAME)/$(m)\([^_]\)#$($(m)_target)\1#g") \
 			-e "s#/usr/share/doc/$(CFG_NAME)/#$(doc_target)#g" \
-			< $(CFG_NAME).cfg.5 >  \
+			-e "s#$(SRC_NAME)#$(MAIN_NAME)#g" \
+			< $(SRC_NAME).cfg.5 >  \
 			$(man_prefix)/$(man_dir)/man5/$(MAIN_NAME).cfg.5
 		@chmod 644  $(man_prefix)/$(man_dir)/man5/$(MAIN_NAME).cfg.5
 

+ 13 - 3
Makefile.defs

@@ -134,6 +134,8 @@ endif
 CFG_NAME=sip-router
 #config name/name-prefix for distributed scripts
 SCR_NAME=sip-router
+#name in source tree
+SRC_NAME=sip-router
 
 # what to install
 INSTALL_FLAVOUR=$(FLAVOUR)
@@ -210,30 +212,36 @@ lib_dir = lib/$(MAIN_NAME)/
 ifeq ($(OS), linux)
 	doc_dir = share/doc/$(MAIN_NAME)/
 	man_dir = share/man/
+	data_dir = share/$(MAIN_NAME)/
 	LOCALBASE ?= /usr/local
 else
 ifeq ($(OS), freebsd)
 	doc_dir = share/doc/$(MAIN_NAME)/
 	man_dir = man/
+	data_dir = share/$(MAIN_NAME)/
 	LOCALBASE ?= /usr/local
 else
 ifeq ($(OS), openbsd)
 	doc_dir = share/doc/$(MAIN_NAME)/
 	man_dir = man/
+	data_dir = share/$(MAIN_NAME)/
 	LOCALBASE ?= /usr/local
 else
 ifeq ($(OS), netbsd)
 	doc_dir = share/doc/$(MAIN_NAME)/
 	man_dir = man/
+	data_dir = share/$(MAIN_NAME)/
 	LOCALBASE ?= /usr/pkg
 else
 ifeq ($(OS), darwin)
 	doc_dir = share/doc/$(MAIN_NAME)/
 	man_dir = man/
+	data_dir = share/$(MAIN_NAME)/
 	LOCALBASE ?= /usr/local
 else
 	doc_dir = doc/$(MAIN_NAME)/
 	man_dir = man/
+	data_dir = $(MAIN_NAME)/
 	LOCALBASE ?= /usr/local
 endif
 endif
@@ -265,6 +273,7 @@ doc_prefix = $(basedir)$(prefix)
 man_prefix = $(basedir)$(prefix)
 ut_prefix = $(basedir)$(prefix)
 share_prefix = $(basedir)$(prefix)
+data_prefix = $(basedir)$(prefix)
 
 
 # target dirs for various stuff
@@ -273,6 +282,7 @@ bin_target = $(prefix)/$(bin_dir)
 #modules_target = $(prefix)/$(modules_dir)
 lib_target = $(prefix)/$(lib_dir)
 doc_target = $(prefix)/$(doc_dir)
+data_target = $(prefix)/$(data_dir)
 
 
 
@@ -1919,7 +1929,7 @@ export exported_vars
 #  cannot be overwritten from environment or command line, unless make cfg
 #  is run)
 saved_fixed_vars:=	MAIN_NAME  CFG_NAME SCR_NAME FLAVOUR INSTALL_FLAVOUR \
-		RELEASE OS ARCH \
+		SRC_NAME RELEASE OS ARCH \
 		C_DEFS DEFS_RM PROFILE CC LD MKDEP MKTAGS LDFLAGS C_INCLUDES \
 		MOD_LDFLAGS LIB_LDFLAGS UTILS_LDFLAGS LIB_SONAME LD_RPATH \
 		LIB_SUFFIX LIB_PREFIX \
@@ -1939,8 +1949,8 @@ saved_chg_vars:=\
 		PREFIX prefix\
 		cfg_prefix cfg_dir bin_prefix bin_dir modules_prefix modules_dir \
 		doc_prefix doc_dir man_prefix man_dir ut_prefix ut_dir \
-		share_prefix share_dir lib_prefix lib_dir \
-		cfg_target lib_target
+		share_prefix share_dir lib_prefix lib_dir data_prefix data_dir \
+		cfg_target lib_target data_target
 
 
 #export relevant variables to the sub-makes

+ 154 - 3
cfg.lex

@@ -107,6 +107,12 @@
 	#define PVAR_P_S                7  /* pvar: $(...)  or $foo(...)*/
 	#define PVARID_S                8  /* $foo.bar...*/
 	#define STR_BETWEEN_S		9
+	#define LINECOMMENT_S            10
+	#define DEFINE_S                11
+	#define DEFINE_EOL_S            12
+	#define IFDEF_S                    13
+	#define IFDEF_EOL_S                14
+	#define IFDEF_SKIP_S            15
 
 	#define STR_BUF_ALLOC_UNIT	128
 	struct str_buf{
@@ -154,11 +160,19 @@
 		struct sr_yy_fname *next;
 	} *sr_yy_fname_list = 0;
 
+	static int  pp_define(int len, const char * text);
+	static int  pp_ifdef_type(int pos);
+	static void pp_ifdef_var(int len, const char * text);
+	static void pp_ifdef();
+	static void pp_else();
+	static void pp_endif();
+
 %}
 
 /* start conditions */
 %x STRING1 STRING2 STR_BETWEEN COMMENT COMMENT_LN ATTR SELECT AVP_PVAR PVAR_P 
 %x PVARID INCLF
+%x LINECOMMENT DEFINE_ID DEFINE_EOL IFDEF_ID IFDEF_EOL IFDEF_SKIP
 
 /* config script types : #!SER  or #!KAMAILIO or #!MAX_COMPAT */
 SER_CFG			SER
@@ -477,8 +491,9 @@ TLSv1			"tlsv1"|"TLSv1"|"TLSV1"
 
 LETTER		[a-zA-Z]
 DIGIT		[0-9]
-ALPHANUM	{LETTER}|{DIGIT}|[_]
-ID			{LETTER}{ALPHANUM}*
+LETTER_     {LETTER}|[_]
+ALPHANUM    {LETTER_}|{DIGIT}
+ID          {LETTER_}{ALPHANUM}*
 NUM_ID		{ALPHANUM}+
 HEX			[0-9a-fA-F]
 HEXNUMBER	0x{HEX}+
@@ -509,6 +524,12 @@ COM_LINE	#
 COM_START	"/\*"
 COM_END		"\*/"
 
+DEFINE       define
+IFDEF        ifdef
+IFNDEF       ifndef
+ENDIF        endif
+/* else is already defined */
+
 EAT_ABLE	[\ \t\b\r]
 
 %%
@@ -1133,7 +1154,38 @@ EAT_ABLE	[\ \t\b\r]
 											sr_cfg_compat=SR_COMPAT_KAMAILIO;}
 <INITIAL>{COM_LINE}!{MAXCOMPAT_CFG}{CR}	{ count(); 
 												sr_cfg_compat=SR_COMPAT_MAX;}
-<INITIAL>{COM_LINE}.*{CR}	{ count(); }
+
+<INITIAL>{COM_LINE}!{DEFINE}{EAT_ABLE}+        { count();
+										state = DEFINE_S; BEGIN(DEFINE_ID); }
+<DEFINE_ID>{ID}                                { count();
+								if (pp_define(yyleng, yytext)) return 1;
+								state = DEFINE_EOL_S; BEGIN(DEFINE_EOL); }
+<DEFINE_EOL>{EAT_ABLE}*{CR}                    { count();
+									state = INITIAL; BEGIN(INITIAL); }
+
+<INITIAL,IFDEF_SKIP>{COM_LINE}!{IFDEF}{EAT_ABLE}+    { count();
+								if (pp_ifdef_type(1)) return 1;
+								state = IFDEF_S; BEGIN(IFDEF_ID); }
+<INITIAL,IFDEF_SKIP>{COM_LINE}!{IFNDEF}{EAT_ABLE}+    { count();
+								if (pp_ifdef_type(0)) return 1;
+								state = IFDEF_S; BEGIN(IFDEF_ID); }
+<IFDEF_ID>{ID}                { count();
+                                pp_ifdef_var(yyleng, yytext);
+                                state = IFDEF_EOL_S; BEGIN(IFDEF_EOL); }
+<IFDEF_EOL>{EAT_ABLE}*{CR}    { count(); pp_ifdef(); }
+
+<INITIAL,IFDEF_SKIP>{COM_LINE}!{ELSE}{EAT_ABLE}*{CR}    { count(); pp_else(); }
+
+<INITIAL,IFDEF_SKIP>{COM_LINE}!{ENDIF}{EAT_ABLE}*{CR}    { count();
+															pp_endif(); }
+
+ /* we're in an ifdef that evaluated to false -- throw it away */
+<IFDEF_SKIP>.|{CR}    { count(); }
+
+ /* this is split so the shebangs match more, giving them priority */
+<INITIAL>{COM_LINE}        { count(); state = LINECOMMENT_S;
+								BEGIN(LINECOMMENT); }
+<LINECOMMENT>.*{CR}        { count(); state = INITIAL_S; BEGIN(INITIAL); }
 
 <INITIAL>{ID}			{ count(); addstr(&s_buf, yytext, yyleng);
 									yylval.strval=s_buf.s;
@@ -1484,3 +1536,102 @@ static int sr_pop_yy_state()
 	return 0;
 }
 
+/* define/ifdef support */
+
+#define MAX_DEFINES    1024
+static str pp_defines[MAX_DEFINES];
+static int pp_num_defines = 0;
+
+/* pp_ifdef_stack[i] is 1 if the ifdef test at depth i is either
+ * ifdef(defined), ifndef(undefined), or the opposite of these
+ * two, but in an else branch
+ */
+#define MAX_IFDEFS    128
+static int pp_ifdef_stack[MAX_IFDEFS];
+static int pp_sptr = 0; /* stack pointer */
+
+static int pp_lookup(int len, const char * text)
+{
+	str var = {(char *)text, len};
+	int i;
+
+	for (i=0; i<pp_num_defines; i++)
+		if (STR_EQ(pp_defines[i], var))
+			return i;
+
+	return -1;
+}
+
+static int pp_define(int len, const char * text)
+{
+	if (pp_num_defines == MAX_DEFINES) {
+		LOG(L_CRIT, "ERROR: too many defines -- adjust MAX_DEFINES\n");
+		return -1;
+	}
+
+	if (pp_lookup(len, text) >= 0) {
+		LOG(L_CRIT, "ERROR: already defined: %.*s\n", len, text);
+		return -1;
+	}
+
+	pp_defines[pp_num_defines].len = len;
+	pp_defines[pp_num_defines].s = (char*)pkg_malloc(len+1);
+	memcpy(pp_defines[pp_num_defines].s, text, len);
+	pp_num_defines++;
+
+	return 0;
+}
+
+static int pp_ifdef_type(int type)
+{
+	if (pp_sptr == MAX_IFDEFS) {
+		LOG(L_CRIT, "ERROR: too many nested ifdefs -- adjust MAX_IFDEFS\n");
+		return -1;
+	}
+
+	pp_ifdef_stack[pp_sptr] = type;
+	return 0;
+}
+
+/* this sets the result of the if[n]def expr:
+ * ifdef  defined   -> 1
+ * ifdef  undefined -> 0
+ * ifndef defined   -> 0
+ * ifndef undefined -> 1
+ */
+static void pp_ifdef_var(int len, const char * text)
+{
+	pp_ifdef_stack[pp_sptr] ^= (pp_lookup(len, text) < 0);
+}
+
+static void pp_update_state()
+{
+	int i;
+
+	for (i=0; i<pp_sptr; i++)
+		if (! pp_ifdef_stack[i]) {
+			state = IFDEF_SKIP_S; BEGIN(IFDEF_SKIP);
+			return;
+		}
+
+	state = INITIAL; BEGIN(INITIAL);
+}
+
+static void pp_ifdef()
+{
+	pp_sptr++;
+	pp_update_state();
+}
+
+static void pp_else()
+{
+	pp_ifdef_stack[pp_sptr-1] ^= 1;
+	pp_update_state();
+}
+
+static void pp_endif()
+{
+	pp_sptr--;
+	pp_update_state();
+}
+

+ 302 - 228
etc/kamailio.cfg

@@ -1,117 +1,132 @@
+#!KAMAILIO
 #
 # $Id$
 #
-# Kamailio (OpenSER) SIP Server - basic configuration script
+# Kamailio (OpenSER) SIP Server v3.0 - basic configuration script
 #     - web: http://www.kamailio.org
-#     - svn: http://openser.svn.sourceforge.net/viewvc/openser/
+#     - git: http://sip-router.org
 #
 # Direct your questions about this file to: <[email protected]>
 #
 # Refer to the Core CookBook at http://www.kamailio.org/dokuwiki/doku.php
 # for an explanation of possible statements, functions and parameters.
 #
-# There are comments showing how to enable different features in th econfig
-# file. Such commented code starts with #X# where X is a letter to identify
-# a feature. Delete entire #X# if you want to enable that feature. Next are
-# sed commands that help you enable such features.
+# Several features can be enabled using '#!define WITH_FEATURE' directives:
 #
-# *** To enamble mysql execute:
-#     sed -i 's/#m#//g' kamailio.cfg
+# *** To run in debug mode: 
+#     - define WITH_DEBUG
 #
-# *** To enamble authentication execute:
+# *** To enable mysql: 
+#     - define WITH_MYSQL
+#
+# *** To enable authentication execute:
 #     - enable mysql
-#     sed -i 's/#a#//g' kamailio.cfg
+#     - define WITH_AUTH
 #     - add users using 'kamctl'
 #
-# *** To enamble persistent user location execute:
+# *** To enable persistent user location execute:
 #     - enable mysql
-#     sed -i 's/#u#//g' kamailio.cfg
+#     - define WITH_USRLOCDB
 #
-# *** To enamble presence server execute:
+# *** To enable presence server execute:
 #     - enable mysql
-#     sed -i 's/#p#//g' kamailio.cfg
+#     - define WITH_PRESENCE
 #
-# *** To enamble nat traversal execute:
-#     sed -i 's/#n#//g' kamailio.cfg
+# *** To enable nat traversal execute:
+#     - define WITH_NAT
 #     - install RTPProxy: http://www.rtpproxy.org
 #     - start RTPProxy:
 #        rtpproxy -l _your_public_ip_ -s udp:localhost:7722
 #
+# *** To enable PSTN gateway routing execute:
+#     - define WITH_PSTN
+#     - set the value of pstn.gw_ip
+#     - check route[PSTN] for regexp routing condition
+#
 # *** To enhance accounting execute:
 #     - enable mysql
-#     sed -i 's/#c#//g' kamailio.cfg
+#     - define WITH_ACCDB
 #     - add following columns to database
-# 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 dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
-# ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
-# ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
-# ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
-# ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
-# ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
-# ALTER TABLE missed_call ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
-# ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
-#
+#!ifdef ACCDB_COMMENT
+  ALTER TABLE acc ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
+  ALTER TABLE acc ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
+  ALTER TABLE acc ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
+  ALTER TABLE acc ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
+  ALTER TABLE acc ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
+  ALTER TABLE missed_calls ADD COLUMN src_user VARCHAR(64) NOT NULL DEFAULT '';
+  ALTER TABLE missed_calls ADD COLUMN src_domain VARCHAR(128) NOT NULL DEFAULT '';
+  ALTER TABLE missed_calls ADD COLUMN dst_ouser VARCHAR(64) NOT NULL DEFAULT '';
+  ALTER TABLE missed_call ADD COLUMN dst_user VARCHAR(64) NOT NULL DEFAULT '';
+  ALTER TABLE missed_calls ADD COLUMN dst_domain VARCHAR(128) NOT NULL DEFAULT '';
+#!endif
 
 
 ####### Global Parameters #########
 
-debug=3
+#!ifdef WITH_DEBUG
+debug=4
+log_stderror=yes
+#!else
+debug=2
 log_stderror=no
+#!endif
+
+memdbg=5
+memlog=5
+
 log_facility=LOG_LOCAL0
 
 fork=yes
 children=4
 
-/* uncomment the following lines to enable debugging */
-#debug=6
-#fork=no
-#log_stderror=yes
-
 /* uncomment the next line to disable TCP (default on) */
 #disable_tcp=yes
 
-/* uncomment the next line to enable the auto temporary blacklisting of 
-   not available destinations (default disabled) */
-#disable_dns_blacklist=no
-
-/* uncomment the next line to enable IPv6 lookup after IPv4 dns 
-   lookup failures (default disabled) */
-#dns_try_ipv6=yes
-
 /* uncomment the next line to disable the auto discovery of local aliases
    based on revers DNS on IPs (default on) */
 #auto_aliases=no
 
-/* uncomment the following lines to enable TLS support  (default off) */
-#disable_tls = no
-#listen = tls:your_IP:5061
-#tls_verify_server = 1
-#tls_verify_client = 1
-#tls_require_client_certificate = 0
-#tls_method = TLSv1
-#tls_certificate = "/usr/local/etc/kamailio/tls/user/user-cert.pem"
-#tls_private_key = "/usr/local/etc/kamailio/tls/user/user-privkey.pem"
-#tls_ca_list     = "/usr/local/etc/kamailio/tls/user/user-calist.pem"
-
-
 port=5060
 
 /* uncomment and configure the following line if you want Kamailio to 
    bind on a specific interface/port/proto (default bind on all available) */
-#listen=udp:192.168.1.2:5060
+#listen=udp:10.0.0.10:5060
+
+
+####### Custom Parameters #########
+
+# These parameters can be modified runtime via RPC interface
+# - see the documentation of 'cfg_rpc' module.
+#
+# Format: group.id = value 'desc' description
+# Access: $sel(cfg_get.group.id) or @cfg_get.group.id
+#
+
+#!ifdef WITH_PSTN
+# PSTN GW Routing
+#
+# - pstn.gw_ip: valid IP or hostname as string value, example:
+# pstn.gw_ip = "10.0.0.101" desc "My PSTN GW Address"
+#
+# - by default is empty to avoid misrouting
+pstn.gw_ip = "" desc "PSTN GW Address"
+#!endif
 
 
 ####### Modules Section ########
 
 #set module path
-mpath="/usr/local/lib/kamailio/modules/"
+mpath="/usr/local/lib/kamailio/modules_k/:/usr/local/lib/kamailio/modules/"
 
 /* uncomment next line for MySQL DB support */
-#m#loadmodule "db_mysql.so"
+#!ifdef WITH_MYSQL
+loadmodule "db_mysql.so"
+#!endif
 loadmodule "mi_fifo.so"
-loadmodule "sl.so"
+loadmodule "kex.so"
 loadmodule "tm.so"
+loadmodule "tmx.so"
+loadmodule "sl.so"
 loadmodule "rr.so"
 loadmodule "pv.so"
 loadmodule "maxfwd.so"
@@ -121,11 +136,14 @@ loadmodule "textops.so"
 loadmodule "uri_db.so"
 loadmodule "siputils.so"
 loadmodule "xlog.so"
+loadmodule "sanity.so"
+loadmodule "ctl.so"
+loadmodule "mi_rpc.so"
 loadmodule "acc.so"
-/* uncomment next lines for MySQL based authentication support 
-   NOTE: a DB (like db_mysql) module must be also loaded */
-#a#loadmodule "auth.so"
-#a#loadmodule "auth_db.so"
+#!ifdef WITH_AUTH
+loadmodule "auth.so"
+loadmodule "auth_db.so"
+#!endif
 /* uncomment next line for aliases support
    NOTE: a DB (like db_mysql) module must be also loaded */
 #loadmodule "alias_db.so"
@@ -134,12 +152,14 @@ loadmodule "acc.so"
    NOTE: be sure and enable multi-domain support in all used modules
          (see "multi-module params" section ) */
 #loadmodule "domain.so"
-/* uncomment the next two lines for presence server support
-   NOTE: a DB (like db_mysql) module must be also loaded */
-#p#loadmodule "presence.so"
-#p#loadmodule "presence_xml.so"
+#!ifdef WITH_PRESENCE
+loadmodule "presence.so"
+loadmodule "presence_xml.so"
+#!endif
 
-#n#loadmodule "nathelper.so"
+#!ifdef WITH_NAT
+loadmodule "nathelper.so"
+#!endif
 
 # ----------------- setting module-specific parameters ---------------
 
@@ -185,31 +205,33 @@ modparam("acc", "log_flag", 1)
 modparam("acc", "log_missed_flag", 2)
 modparam("acc", "log_extra", 
 	"src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
-/* uncomment the following lines to enable DB accounting also */
-#c#modparam("acc", "db_flag", 1)
-#c#modparam("acc", "db_missed_flag", 2)
-#c#modparam("acc", "db_url",
-#c#	"mysql://openser:openserrw@localhost/openser")
-#c#modparam("acc", "db_extra",
-#c#	"src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
-
+/* enhanced DB accounting */
+#!ifdef WITH_ACCDB
+modparam("acc", "db_flag", 1)
+modparam("acc", "db_missed_flag", 2)
+modparam("acc", "db_url",
+	"mysql://openser:openserrw@localhost/openser")
+modparam("acc", "db_extra",
+	"src_user=$fU;src_domain=$fd;dst_ouser=$tU;dst_user=$rU;dst_domain=$rd")
+#!endif
 
 # ----- usrloc params -----
-/* uncomment the following lines if you want to enable DB persistency
-   for location entries */
-#u#modparam("usrloc", "db_mode",   2)
-#u#modparam("usrloc", "db_url",
-#u#	"mysql://openser:openserrw@localhost/openser")
+/* enable DB persistency for location entries */
+#!ifdef WITH_USRLOCDB
+modparam("usrloc", "db_mode",   2)
+modparam("usrloc", "db_url",
+	"mysql://openser:openserrw@localhost/openser")
+#!endif
 
 # ----- auth_db params -----
-/* uncomment the following lines if you want to enable the DB based
-   authentication */
-#a#modparam("auth_db", "calculate_ha1", yes)
-#a#modparam("auth_db", "password_column", "password")
-#a#modparam("auth_db", "db_url",
-#a#	"mysql://openser:openserrw@localhost/openser")
-#a#modparam("auth_db", "load_credentials", "")
-
+/* enable the DB based authentication */
+#!ifdef WITH_AUTH
+modparam("auth_db", "calculate_ha1", yes)
+modparam("auth_db", "password_column", "password")
+modparam("auth_db", "db_url",
+	"mysql://openser:openserrw@localhost/openser")
+modparam("auth_db", "load_credentials", "")
+#!endif
 
 # ----- alias_db params -----
 /* uncomment the following lines if you want to enable the DB based
@@ -233,20 +255,24 @@ modparam("acc", "log_extra",
 
 
 # ----- presence params -----
-/* uncomment the following lines if you want to enable presence */
-#p#modparam("presence|presence_xml", "db_url",
-#p#	"mysql://openser:openserrw@localhost/openser")
-#p#modparam("presence_xml", "force_active", 1)
-#p#modparam("presence", "server_address", "sip:192.168.1.2:5060")
-
-# -- nathelper
-#n#modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1:7722")
-#n#modparam("nathelper", "natping_interval", 30)
-#n#modparam("nathelper", "ping_nated_only", 1)
-#n#modparam("nathelper", "sipping_bflag", 7)
-#n#modparam("nathelper", "sipping_from", "sip:[email protected]")
-#n#modparam("registrar|nathelper", "received_avp", "$avp(i:80)")
-#n#modparam("usrloc", "nat_bflag", 6)
+/* enable presence server support */
+#!ifdef WITH_PRESENCE
+modparam("presence|presence_xml", "db_url",
+	"mysql://openser:openserrw@localhost/openser")
+modparam("presence_xml", "force_active", 1)
+modparam("presence", "server_address", "sip:10.0.0.10:5060")
+#!endif
+
+# ----- nathelper -----
+#!ifdef WITH_NAT
+modparam("nathelper", "rtpproxy_sock", "udp:127.0.0.1:7722")
+modparam("nathelper", "natping_interval", 30)
+modparam("nathelper", "ping_nated_only", 1)
+modparam("nathelper", "sipping_bflag", 7)
+modparam("nathelper", "sipping_from", "sip:[email protected]")
+modparam("registrar|nathelper", "received_avp", "$avp(i:80)")
+modparam("usrloc", "nat_bflag", 6)
+#!endif
 
 ####### Routing Logic ########
 
@@ -260,8 +286,14 @@ route{
 		exit;
 	}
 
+	if(!sanity_check("1511", "7"))
+	{
+		xlog("Malformed SIP message from $si:$sp\n");
+		exit;
+	}
+
 	# NAT detection
-	route(4);
+	route(NAT);
 
 	if (has_totag()) {
 		# sequential request withing a dialog should
@@ -271,11 +303,11 @@ route{
 				setflag(1); # do accounting ...
 				setflag(3); # ... even if the transaction fails
 			}
-			route(1);
+			route(RELAY);
 		} else {
 			if (is_method("SUBSCRIBE") && uri == myself) {
 				# in-dialog subscribe requests
-				route(2);
+				route(PRESENCE);
 				exit;
 			}
 			if ( is_method("ACK") ) {
@@ -306,9 +338,11 @@ route{
 	t_check_trans();
 
 	# authentication
-	route(3);
+	route(AUTH);
 
 	# record routing for dialog forming requests (in case they are routed)
+	# - remove preloaded route headers
+	remove_hf("Route");
 	if (is_method("INVITE|SUBSCRIBE"))
 		record_route();
 
@@ -321,41 +355,41 @@ route{
 	##if (!is_uri_host_local())
 	{
 		append_hf("P-hint: outbound\r\n"); 
-		# if you have some interdomain connections via TLS
-		##if($rd=="tls_domain1.net") {
-		##	t_relay("tls:domain1.net");
-		##	exit;
-		##} else if($rd=="tls_domain2.net") {
-		##	t_relay("tls:domain2.net");
-		##	exit;
-		##}
-		route(1);
+		route(RELAY);
 	}
 
 	# requests for my domain
 
 	if( is_method("PUBLISH|SUBSCRIBE"))
-		route(2);
+		route(PRESENCE);
 
 	if (is_method("REGISTER"))
 	{
+		if(isflagset(5))
+		{
+			setbflag("6");
+			# uncomment next line to do SIP NAT pinging 
+			## setbflag("7");
+		}
 		if (!save("location"))
 			sl_reply_error();
 
 		exit;
 	}
 
-	if ($rU==NULL) {
+	if ($rU==$null) {
 		# request with no Username in RURI
 		sl_send_reply("484","Address Incomplete");
 		exit;
 	}
 
+	route(PSTN);
+
 	# apply DB based aliases (uncomment to enable)
 	##alias_db_lookup("dbaliases");
 
 	if (!lookup("location")) {
-		switch ($retcode) {
+		switch ($rc) {
 			case -1:
 			case -3:
 				t_newtran();
@@ -370,23 +404,25 @@ route{
 	# when routing via usrloc, log the missed calls also
 	setflag(2);
 
-	route(1);
+	route(RELAY);
 }
 
 
-route[1] {
-#n#	if (check_route_param("nat=yes")) {
-#n#		setbflag(6);
-#n#	}
-#n#	if (isflagset(5) || isbflagset(6)) {
-#n#		route(5);
-#n#	}
+route[RELAY] {
+#!ifdef WITH_NAT
+	if (check_route_param("nat=yes")) {
+		setbflag("6");
+	}
+	if (isflagset(5) || isbflagset("6")) {
+		route(RTPPROXY);
+	}
+#!endif
 
 	/* example how to enable some additional event routes */
 	if (is_method("INVITE")) {
-		#t_on_branch("1");
-		t_on_reply("1");
-		t_on_failure("1");
+		#t_on_branch("BRANCH_ONE");
+		t_on_reply("REPLY_ONE");
+		t_on_failure("FAIL_ONE");
 	}
 
 	if (!t_relay()) {
@@ -396,31 +432,32 @@ route[1] {
 }
 
 
-# Presence route
-/* uncomment the whole following route for enabling presence server */
-route[2]
+# Presence server route
+route[PRESENCE]
 {
-#p#	if (!t_newtran())
-#p#	{
-#p#		sl_reply_error();
-#p#		exit;
-#p#	};
-#p#
-#p#	if(is_method("PUBLISH"))
-#p#	{
-#p#		handle_publish();
-#p#		t_release();
-#p#	}
-#p#	else
-#p#	if( is_method("SUBSCRIBE"))
-#p#	{
-#p#		handle_subscribe();
-#p#		t_release();
-#p#	}
-#p#	exit;
+#!ifdef WITH_PRESENCE
+	if (!t_newtran())
+	{
+		sl_reply_error();
+		exit;
+	};
+
+	if(is_method("PUBLISH"))
+	{
+		handle_publish();
+		t_release();
+	}
+	else
+	if( is_method("SUBSCRIBE"))
+	{
+		handle_subscribe();
+		t_release();
+	}
+	exit;
+#!endif
 	
 	# if presence enabled, this part will not be executed
-	if (is_method("PUBLISH") || $rU==null)
+	if (is_method("PUBLISH") || $rU==$null)
 	{
 		sl_send_reply("404", "Not here");
 		exit;
@@ -429,101 +466,138 @@ route[2]
 }
 
 # Authentication route
-/* uncomment the whole following route for enabling authentication */
-route[3] {
-#a#	if (is_method("REGISTER"))
-#a#	{
-#a#		# authenticate the REGISTER requests (uncomment to enable auth)
-#a#		if (!www_authorize("", "subscriber"))
-#a#		{
-#a#			www_challenge("", "0");
-#a#			exit;
-#a#		}
-#a#
-#a#		if ($au!=$tU) 
-#a#		{
-#a#			sl_send_reply("403","Forbidden auth ID");
-#a#			exit;
-#a#		}
-#a#	} else {
-#a#		# authenticate if from local subscriber (uncomment to enable auth)
-#a#		if (from_uri==myself)
-#a#		{
-#a#			if (!proxy_authorize("", "subscriber")) {
-#a#				proxy_challenge("", "0");
-#a#				exit;
-#a#			}
-#a#			if (is_method("PUBLISH"))
-#a#			{
-#a#				if ($au!=$tU) {
-#a#					sl_send_reply("403","Forbidden auth ID");
-#a#					exit;
-#a#				}
-#a#			} else {
-#a#				if ($au!=$fU) {
-#a#					sl_send_reply("403","Forbidden auth ID");
-#a#					exit;
-#a#				}
-#a#			}
-#a#
-#a#			consume_credentials();
-#a#			# caller authenticated
-#a#		}
-#a#	}
+route[AUTH] {
+#!ifdef WITH_AUTH
+	if (is_method("REGISTER"))
+	{
+		# authenticate the REGISTER requests (uncomment to enable auth)
+		if (!www_authorize("", "subscriber"))
+		{
+			www_challenge("", "0");
+			exit;
+		}
+
+		if ($au!=$tU)
+		{
+			sl_send_reply("403","Forbidden auth ID");
+			exit;
+		}
+	} else {
+		# authenticate if from local subscriber (uncomment to enable auth)
+		if (from_uri==myself)
+		{
+			if (!proxy_authorize("", "subscriber")) {
+				proxy_challenge("", "0");
+				exit;
+			}
+			if (is_method("PUBLISH"))
+			{
+				if ($au!=$tU) {
+					sl_send_reply("403","Forbidden auth ID");
+					exit;
+				}
+			} else {
+				if ($au!=$fU) {
+					sl_send_reply("403","Forbidden auth ID");
+					exit;
+				}
+			}
+
+			consume_credentials();
+			# caller authenticated
+		}
+	}
+#!endif
 	return;
 }
 
 # Caller NAT detection route
-/* uncomment the whole following route for enabling Caller NAT Detection */
-route[4]{
-#n#	force_rport();
-#n#	if (nat_uac_test("19")) {
-#n#		if (method=="REGISTER") {
-#n#			fix_nated_register();
-#n#		} else {
-#n#			fix_nated_contact();
-#n#		}
-#n#		setflag(5);
-#n#	}
+route[NAT]{
+#!ifdef WITH_NAT
+	force_rport();
+	if (nat_uac_test("19")) {
+		if (method=="REGISTER") {
+			fix_nated_register();
+		} else {
+			fix_nated_contact();
+		}
+		setflag(5);
+	}
+#!endif
 	return;
 }
 
 # RTPProxy control
-/* uncomment the whole following route for enabling RTPProxy Control */
-route[5] {
-#n#	if (is_method("BYE")) {
-#n#		unforce_rtp_proxy();
-#n#	} else if (is_method("INVITE")){
-#n#		force_rtp_proxy();
-#n#	}
-#n#	if (!has_totag()) add_rr_param(";nat=yes");
+route[RTPPROXY] {
+#!ifdef WITH_NAT
+	if (is_method("BYE")) {
+		unforce_rtp_proxy();
+	} else if (is_method("INVITE")){
+		force_rtp_proxy();
+	}
+	if (!has_totag()) add_rr_param(";nat=yes");
+#!endif
 	return;
 }
 
-branch_route[1] {
-	xdbg("new branch at $ru\n");
-}
+# PSTN GW routing
+route[PSTN] {
+#!ifdef WITH_PSTN
+	# check if PSTN GW IP is defined
+	if (strempty($sel(cfg_get.pstn.gw_ip))) {
+		xlog("SCRIPT: PSTN rotuing enabled but pstn.gw_ip not defined\n");
+		return;
+	}
 
+	# route to PSTN dialed numbers starting with '+' or '00'
+	#     (international format)
+	# - update the condition to match your dialing rules for PSTN routing
+	if(!($rU=~"^(\+|00)[1-9][0-9]{3,20}$"))
+		return;
 
-onreply_route[1] {
-	xdbg("incoming reply\n");
+	# only local users allowed to call
+	if(from_uri!=myself) {
+		sl_send_reply("403", "Not Allowed");
+		exit;
+	}
+
+	$ru = "sip:" + $rU + "@" + $sel(cfg_get.pstn.gw_ip);
+
+	route(RELAY);
+	exit;
+#!endif
 
-#n#	if ((isflagset(5) || isbflagset(6)) && status=~"(183)|(2[0-9][0-9])") {
-#n#		force_rtp_proxy();
-#n#	}
-#n#	if (isbflagset(6)) {
-#n#		fix_nated_contact();
-#n#	}
+	return;
+}
+
+# Sample branch router
+branch_route[BRANCH_ONE] {
+	xdbg("new branch at $ru\n");
 }
 
+# Sample onreply route
+onreply_route[REPLY_ONE] {
+	xdbg("incoming reply\n");
+#!ifdef WITH_NAT
+	if ((isflagset(5) || isbflagset("6")) && status=~"(183)|(2[0-9][0-9])") {
+		force_rtp_proxy();
+	}
+	if (isbflagset("6")) {
+		fix_nated_contact();
+	}
+#!endif
+}
 
-failure_route[1] {
-#n#	if (is_method("INVITE")
-#n#			&& (isbflagset(6) || isflagset(5))) {
-#n#		unforce_rtp_proxy();
-#n#	}
+# Sample failure route
+failure_route[FAIL_ONE] {
+#!ifdef WITH_NAT
+	if (is_method("INVITE")
+			&& (isbflagset("6") || isflagset(5))) {
+		unforce_rtp_proxy();
+	}
+#!endif
 
-	if (t_was_cancelled()) {
+	if (t_is_canceled()) {
 		exit;
 	}
 

+ 8 - 1
lib/srdb1/schema/dialog.xml

@@ -9,7 +9,7 @@
 
 <table id="dialog" xmlns:db="http://docbook.org/ns/docbook">
 	<name>dialog</name>
-	<version>3</version>
+	<version>4</version>
 	<type db="mysql">&MYSQL_TABLE_TYPE;</type>
 	<description>
 		<db:para>Persistent dialog information for the dialog module. More 
@@ -185,6 +185,13 @@
 		</description>
 	</column>
 
+	<column>
+		<name>req_uri</name>
+		<type>string</type>
+		<size>&uri_len;</size>
+		<description>The URI of initial request in dialog</description>
+	</column>
+
 	<index>
 		<name>hash_idx</name>
 		<colref linkend="hash_entry"/>

+ 80 - 0
lib/srdb1/schema/dr_gateways.xml

@@ -0,0 +1,80 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE table PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN" 
+  "http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
+
+<!ENTITY % entities SYSTEM "entities.xml">
+%entities;
+
+]>
+
+<table id="dr_gateways" xmlns:db="http://docbook.org/ns/docbook">
+	<name>dr_gateways</name>
+	<version>3</version>
+	<type db="mysql">&MYSQL_TABLE_TYPE;</type>
+	<description>
+		<db:para>This table is used by the douting module - keeps the
+			gateways data.
+		</db:para>
+	</description>
+
+	<column id="gwid">
+		<name>gwid</name>
+		<type>unsigned int</type>
+		<size>&table_id_len;</size>
+		<autoincrement/>
+		<primary/>
+		<type db="dbtext">int,auto</type>
+		<description>Unique ID per gateway
+		</description>
+	</column>
+
+	<column id="type">
+		<name>type</name>
+		<type>unsigned int</type>
+		<size>11</size>
+		<default>0</default>
+		<description>Type of gateway</description>
+	</column>
+
+	<column id="address">
+		<name>address</name>
+		<type>string</type>
+		<size>128</size>
+		<description>Address of gateway (hostname or ip and port)</description>
+	</column>
+
+	<column id="strip">
+		<name>strip</name>
+		<type>unsigned int</type>
+		<size>11</size>
+		<default>0</default>
+		<description>Number of digits to strip from dialed number</description>
+	</column>
+
+	<column id="pri_prefix">
+		<name>pri_prefix</name>
+		<type>string</type>
+		<size>64</size>
+		<null/>
+		<default><null/></default>
+		<description>What to prefix to dialed number</description>
+	</column>
+
+	<column id="attrs">
+		<name>attrs</name>
+		<type>string</type>
+		<size>255</size>
+		<null/>
+		<default><null/></default>
+		<description>Generic string to be returned in cfg script</description>
+	</column>
+
+	<column id="description">
+		<name>description</name>
+		<type>string</type>
+		<size>128</size>
+		<default></default>
+		<description>Short description of gateway</description>
+	</column>
+</table>
+

+ 64 - 0
lib/srdb1/schema/dr_groups.xml

@@ -0,0 +1,64 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE table PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN" 
+  "http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
+
+<!ENTITY % entities SYSTEM "entities.xml">
+%entities;
+
+]>
+
+<table id="dr_groups" xmlns:db="http://docbook.org/ns/docbook">
+	<name>dr_groups</name>
+	<version>2</version>
+	<type db="mysql">&MYSQL_TABLE_TYPE;</type>
+	<description>
+		<db:para>This table is used by the drouting module to store
+		information about the routing groups (users mapped over groups).
+		More information can be found at: &KAMAILIO_MOD_DOC;drouting.html.
+		</db:para>
+	</description>
+
+	<column id="gwid">
+		<name>id</name>
+		<type>unsigned int</type>
+		<size>&table_id_len;</size>
+		<autoincrement/>
+		<primary/>
+		<type db="dbtext">int,auto</type>
+		<description>Unique ID</description>
+	</column>
+
+	<column id="username">
+		<name>username</name>
+		<type>string</type>
+		<size>64</size>
+		<description>Username part of user</description>
+	</column>
+
+	<column id="domain">
+		<name>domain</name>
+		<type>string</type>
+		<size>128</size>
+		<default></default>
+		<description>Domain part of user</description>
+	</column>
+
+	<column id="groupid">
+		<name>groupid</name>
+		<type>unsigned int</type>
+		<size>11</size>
+		<default>0</default>
+		<description>The ID of the routing group the user belongs to.
+		</description>
+	</column>
+
+
+	<column id="description">
+		<name>description</name>
+		<type>string</type>
+		<size>128</size>
+		<default></default>
+		<description>Text description of the group/user</description>
+	</column>
+
+</table>

+ 47 - 0
lib/srdb1/schema/dr_gw_lists.xml

@@ -0,0 +1,47 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE table PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN" 
+  "http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
+
+<!ENTITY % entities SYSTEM "entities.xml">
+%entities;
+
+]>
+
+<table id="dr_gw_lists" xmlns:db="http://docbook.org/ns/docbook">
+	<name>dr_gw_lists</name>
+	<version>1</version>
+	<type db="mysql">&MYSQL_TABLE_TYPE;</type>
+	<description>
+		<db:para>This table is used by the drouting module to define
+		lists of gateways to be used in rule definitions.
+		More information can be found at: &KAMAILIO_MOD_DOC;drouting.html.
+		</db:para>
+	</description>
+
+	<column id="id">
+		<name>id</name>
+		<type>unsigned int</type>
+		<size>&table_id_len;</size>
+		<autoincrement/>
+		<primary/>
+		<type db="dbtext">int,auto</type>
+		<description>Unique ID</description>
+	</column>
+
+	<column id="gwlist">
+		<name>gwlist</name>
+		<type>string</type>
+		<size>255</size>
+		<description>List of GW ids.
+		</description>
+	</column>
+
+	<column id="description">
+		<name>description</name>
+		<type>string</type>
+		<size>128</size>
+		<default></default>
+		<description>Text description of the GW list</description>
+	</column>
+
+</table>

+ 86 - 0
lib/srdb1/schema/dr_rules.xml

@@ -0,0 +1,86 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE table PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN" 
+  "http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
+
+<!ENTITY % entities SYSTEM "entities.xml">
+%entities;
+
+]>
+
+<table id="dr_rules" xmlns:db="http://docbook.org/ns/docbook">
+	<name>dr_rules</name>
+	<version>3</version>
+	<type db="mysql">&MYSQL_TABLE_TYPE;</type>
+	<description>
+		<db:para>This table is used by the drouting module - keeps the
+			routing rules data.
+		</db:para>
+	</description>
+
+	<column id="ruleid">
+		<name>ruleid</name>
+		<type>unsigned int</type>
+		<size>&table_id_len;</size>
+		<autoincrement/>
+		<primary/>
+		<type db="dbtext">int,auto</type>
+		<description>Rule unique ID
+		</description>
+	</column>
+
+	<column id="groupid">
+		<name>groupid</name>
+		<type>string</type>
+		<size>255</size>
+		<description>list of routing group IDs
+		</description>
+	</column>
+
+	<column id="prefix">
+		<name>prefix</name>
+		<type>string</type>
+		<size>64</size>
+		<description>Destination prefix for this rule</description>
+	</column>
+
+	<column id="timerec">
+		<name>timerec</name>
+		<type>string</type>
+		<size>255</size>
+		<description>Time recurrence for this rule.</description>
+	</column>
+
+	<column id="priority">
+		<name>priority</name>
+		<type>int</type>
+		<size>11</size>
+		<default>0</default>
+		<description>Priority of the rule.</description>
+	</column>
+
+	<column id="routeid">
+		<name>routeid</name>
+		<type>string</type>
+		<size>64</size>
+		<description>Name of route block (from cfg script) to be
+			executed when matching this rule.</description>
+	</column>
+
+	<column id="gwlist">
+		<name>gwlist</name>
+		<type>string</type>
+		<size>255</size>
+		<description>The list of destinations (gws) to be used when
+		matching this rule.</description>
+	</column>
+
+	<column id="description">
+		<name>description</name>
+		<type>string</type>
+		<size>128</size>
+		<default></default>
+		<description>Short description of the rule</description>
+	</column>
+
+</table>
+

+ 16 - 0
lib/srdb1/schema/kamailio-drouting.xml

@@ -0,0 +1,16 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE database PUBLIC "-//kamailio.org//DTD DBSchema V1.1//EN"
+  "http://kamailio.org/pub/kamailio/dbschema/dtd/1.1/dbschema.dtd" [
+
+<!ENTITY % entities SYSTEM "entities.xml">
+%entities;
+
+]>
+
+<database xmlns:xi="http://www.w3.org/2001/XInclude">
+    <name>DRouting</name>
+    <xi:include href="dr_gateways.xml"/>
+    <xi:include href="dr_rules.xml"/>
+    <xi:include href="dr_gw_lists.xml"/>
+    <xi:include href="dr_groups.xml"/>
+</database>

+ 25 - 3
modules/ctl/README

@@ -19,6 +19,8 @@ Andrei Pelinescu-Onciul
         1.3.4. group (integer or string)
         1.3.5. fifo (integer)
         1.3.6. autoconversion (integer)
+        1.3.7. binrpc_max_body_size (integer)
+        1.3.8. binrpc_struct_max_body_size (integer)
 
    1.4. RPC Functions
 
@@ -180,6 +182,26 @@ modparam("ctl", "fifo", "tcp:*:2050")              # fifo over tcp
    Example 7. Set the autoconversion parameter
 modparam("ctl", "autoconversion", 1)
 
+1.3.7. binrpc_max_body_size (integer)
+
+   Set the size of binrpc buffer for RPC reply. Value represents
+   kilobytes.
+
+   Default: 4 (meaning 4KB);
+
+   Example 8. Set the binrpc_max_body_size parameter
+modparam("ctl", "binrpc_max_body_size", 10)
+
+1.3.8. binrpc_struct_max_body_size (integer)
+
+   Set the size of binrpc structure buffer for RPC reply. Value represents
+   kilobytes.
+
+   Default: 1 (meaning 1KB);
+
+   Example 9. Set the binrpc_struct_max_body_size parameter
+modparam("ctl", "binrpc_struct_max_body_size", 3)
+
 1.4. RPC Functions
 
    Revision History
@@ -189,7 +211,7 @@ modparam("ctl", "autoconversion", 1)
 
    List all the sockets on which the ctl module listens.
 
-   Example 8. print usage
+   Example 10. print usage
  $ sercmd -f"[%v] %v:%v %v\n" ctl.listen
 [binrpc] unix_stream:/tmp/ser_ctl
 
@@ -199,7 +221,7 @@ modparam("ctl", "autoconversion", 1)
 
    Returns the number of open binrpc connections (to the ctl module).
 
-   Example 9. ctl.connections usage
+   Example 11. ctl.connections usage
  $ sercmd ctl.connections
 1
 
@@ -207,7 +229,7 @@ modparam("ctl", "autoconversion", 1)
 
    List open binrpc connections (to the ctl module).
 
-   Example 10. ctl.who usage
+   Example 12. ctl.who usage
  $ sercmd -f"[%v] %v: %v %v -> %v %v\n" ctl.who
 [binrpc] unix_stream: <anonymous unix socket>  -> /tmp/ser_ctl
 

+ 4 - 3
modules/ctl/binrpc_run.c

@@ -46,9 +46,10 @@
    rpc->scan (default: not set) */
 int autoconvert=0;
 
-
-#define BINRPC_MAX_BODY	4096  /* maximum body for send */
-#define STRUCT_MAX_BODY	1024
+int binrpc_max_body_size = 4; /* multiplied by 1024 in mod init */
+int  binrpc_struct_max_body_size = 1; /* multiplied by 1024 in mod init */
+#define BINRPC_MAX_BODY	binrpc_max_body_size  /* maximum body for send */
+#define STRUCT_MAX_BODY	binrpc_struct_max_body_size
 #define MAX_MSG_CHUNKS	96
 
 #define BINRPC_GC_IBSIZE 4 /* initial gc block size (pointers no.) */

+ 12 - 1
modules/ctl/ctl.c

@@ -70,6 +70,8 @@ static int usock_gid=-1;
 /* if set try to automatically convert values to the requested type in
    rpc->scan (default: not set) */
 extern int autoconvert; 
+extern int binrpc_max_body_size;
+extern int binrpc_struct_max_body_size;
 
 static int add_binrpc_socket(modparam_t type, void * val);
 #ifdef USE_FIFO
@@ -104,6 +106,8 @@ static param_export_t params[]={
 	{"user",		PARAM_STRING|PARAM_USE_FUNC,	fix_user				 },
 	{"group",		PARAM_STRING|PARAM_USE_FUNC,	fix_group				 },
 	{"autoconversion",	PARAM_INT,					&autoconvert			 },
+	{"binrpc_max_body_size",        PARAM_INT, &binrpc_max_body_size         },
+	{"binrpc_struct_max_body_size", PARAM_INT, &binrpc_struct_max_body_size  },
 	{0,0,0} 
 }; /* no params */
 
@@ -224,7 +228,14 @@ error:
 static int mod_init(void)
 {
 	struct id_list* l;
-	
+
+	if(binrpc_max_body_size<=0)
+		binrpc_max_body_size = 4;
+	if(binrpc_struct_max_body_size<=0)
+		binrpc_struct_max_body_size = 1;
+	binrpc_max_body_size *= 1024;
+	binrpc_struct_max_body_size *= 1024;
+
 	if (listen_lst==0) {
 		add_binrpc_socket(PARAM_STRING, DEFAULT_CTL_SOCKET);
 	}

+ 36 - 0
modules/ctl/doc/params.xml

@@ -192,4 +192,40 @@ modparam("ctl", "autoconversion", 1)
 	</example>
 	</section>
 
+	<section id="binrpc_max_body_size">
+	<title><varname>binrpc_max_body_size</varname> (integer)</title>
+	<para>
+		Set the size of binrpc buffer for RPC reply. Value represents
+		kilobytes.
+	</para>
+	<para>
+		Default: 4 (meaning 4KB);
+	</para>
+	<example>
+		<title>Set the <varname>binrpc_max_body_size</varname> parameter
+		</title>
+		<programlisting>
+modparam("ctl", "binrpc_max_body_size", 10)
+		</programlisting>
+	</example>
+	</section>
+
+	<section id="binrpc_struct_max_body_size">
+	<title><varname>binrpc_struct_max_body_size</varname> (integer)</title>
+	<para>
+		Set the size of binrpc structure buffer for RPC reply. Value represents
+		kilobytes.
+	</para>
+	<para>
+		Default: 1 (meaning 1KB);
+	</para>
+	<example>
+		<title>Set the <varname>binrpc_struct_max_body_size</varname> parameter
+		</title>
+		<programlisting>
+modparam("ctl", "binrpc_struct_max_body_size", 3)
+		</programlisting>
+	</example>
+	</section>
+
 </section>

+ 10 - 0
modules/db_berkeley/Makefile

@@ -20,3 +20,13 @@ SERLIBPATH=../../lib
 SER_LIBS=$(SERLIBPATH)/srdb2/srdb2 $(SERLIBPATH)/srdb1/srdb1 $(SERLIBPATH)/kmi/kmi
 
 include ../../Makefile.modules
+
+ifeq ($(INSTALL_FLAVOUR),kamailio)
+# extra install for kamailio
+
+install-berkeley-scripts: $(bin_prefix)/$(bin_dir)
+		BERKELEYDBON=yes make -C ../../utils/kamctl/ install-modules
+
+install-scripts: install-berkeley-scripts
+
+endif # INSTALL_FLAVOUR

+ 8 - 0
modules/db_mysql/Makefile

@@ -42,4 +42,12 @@ install-mysql-script: $(bin_prefix)/$(bin_dir)
 
 install-scripts: install-mysql-script
 
+else ifeq ($(INSTALL_FLAVOUR),kamailio)
+# extra install for kamailio
+
+install-mysql-scripts: $(bin_prefix)/$(bin_dir)
+		MYSQLON=yes make -C ../../utils/kamctl/ install-modules
+
+install-scripts: install-mysql-scripts
+
 endif # INSTALL_FLAVOUR

+ 10 - 0
modules/db_postgres/Makefile

@@ -35,3 +35,13 @@ SERLIBPATH=../../lib
 SER_LIBS=$(SERLIBPATH)/srdb2/srdb2 $(SERLIBPATH)/srdb1/srdb1
 
 include ../../Makefile.modules
+
+ifeq ($(INSTALL_FLAVOUR),kamailio)
+# extra install for kamailio
+
+install-pgsql-scripts: $(bin_prefix)/$(bin_dir)
+		PGSQLON=yes make -C ../../utils/kamctl/ install-modules
+
+install-scripts: install-pgsql-scripts
+
+endif # INSTALL_FLAVOUR

+ 119 - 43
modules/tm/README

@@ -96,13 +96,15 @@ Juha Heinanen
         1.5.26. t_is_expired()
         1.5.27. t_relay_cancel()
         1.5.28. t_lookup_cancel(), t_lookup_cancel(1)
-        1.5.29. t_drop_replies()
+        1.5.29. t_drop_replies([mode])
         1.5.30. t_save_lumps()
         1.5.31. t_load_contacts()
         1.5.32. t_next_contacts()
         1.5.33. t_check_trans()
         1.5.34. t_set_disable_6xx(0|1)
         1.5.35. t_set_disable_failover(0|1)
+        1.5.36. t_replicate(params)
+        1.5.37. t_relay_to(proxy, flags)
 
    1.6. TM Module API
 
@@ -1134,7 +1136,7 @@ modparam("tm", "local_ack_mode", 1)
    Revision History
    Revision $Revision$ $Date$
 
-1.5.1.  t_relay_to_udp(ip, port), t_relay_to_udp(), t_relay_to_tcp(ip, port)
+1.5.1. t_relay_to_udp(ip, port), t_relay_to_udp(), t_relay_to_tcp(ip, port)
 t_relay_to_tcp() t_relay_to_tls(ip, port) t_relay_to_tls()
 t_relay_to_sctp(ip, port) t_relay_to_sctp()
 
@@ -1162,7 +1164,7 @@ else
         t_relay_to_tcp(); # relay to msg. uri, but over tcp
 ...
 
-1.5.2.  t_relay() t_relay(host, port)
+1.5.2. t_relay() t_relay(host, port)
 
    Relay a message statefully either to the destination indicated in the
    current URI (if called without any parameters) or to the specified host
@@ -1190,7 +1192,7 @@ if (!t_relay())
 };
 ...
 
-1.5.3.  t_on_failure(failure_route)
+1.5.3. t_on_failure(failure_route)
 
    Sets failure routing block, to which control is passed after a
    transaction completed with a negative result but before sending a final
@@ -1227,7 +1229,7 @@ failure_route[1] {
    See test/onr.cfg for a more complex example of combination of serial
    with parallel forking.
 
-1.5.4.  t_on_reply(onreply_route)
+1.5.4. t_on_reply(onreply_route)
 
    Sets the reply routing block, to which control is passed when a reply
    for the current transaction is received. Note that the set of commands
@@ -1257,7 +1259,7 @@ es');
         }
 }
 
-1.5.5.  t_on_branch(branch_route)
+1.5.5. t_on_branch(branch_route)
 
    Sets the branch routing block, to which control is passed after forking
    (when a new branch is created). For now branch routes are intended only
@@ -1281,7 +1283,7 @@ branch_route[1] {
         }
 }
 
-1.5.6.  append_branch()
+1.5.6. append_branch()
 
    Similarly to t_fork_to, it extends destination set by a new entry. The
    difference is that current URI is taken as new entry.
@@ -1295,7 +1297,7 @@ t_fork();
 t_relay();
 ...
 
-1.5.7.  t_newtran()
+1.5.7. t_newtran()
 
    Creates a new transaction, returns a negative value on error. This is
    the only way a script can add a new transaction in an atomic way.
@@ -1311,7 +1313,7 @@ if (t_newtran()) {
 
    See test/uas.cfg for more examples.
 
-1.5.8.  t_reply(code, reason_phrase)
+1.5.8. t_reply(code, reason_phrase)
 
    Sends a stateful reply after a transaction has been established. See
    t_newtran for usage.
@@ -1325,7 +1327,7 @@ if (t_newtran()) {
 t_reply("404", "Not found");
 ...
 
-1.5.9.  t_lookup_request()
+1.5.9. t_lookup_request()
 
    Checks if a transaction exists. Returns a positive value if so,
    negative otherwise. Most likely you will not want to use it, as a
@@ -1340,7 +1342,7 @@ if (t_lookup_request()) {
 };
 ...
 
-1.5.10.  t_retransmit_reply()
+1.5.10. t_retransmit_reply()
 
    Retransmits a reply sent previously by UAS transaction.
 
@@ -1349,7 +1351,7 @@ if (t_lookup_request()) {
 t_retransmit_reply();
 ...
 
-1.5.11.  t_release()
+1.5.11. t_release()
 
    Remove transaction from memory (it will be first put on a wait timer to
    absorb delayed messages).
@@ -1359,7 +1361,7 @@ t_retransmit_reply();
 t_release();
 ...
 
-1.5.12.  t_forward_nonack() t_forward_nonack(ip, port)
+1.5.12. t_forward_nonack() t_forward_nonack(ip, port)
 t_forward_nonack_udp(ip, port) t_forward_nonack_tcp(ip, port)
 t_forward_nonack_tls(ip, port) t_forward_nonack_sctp(ip, port)
 
@@ -1374,7 +1376,7 @@ t_forward_nonack_tls(ip, port) t_forward_nonack_sctp(ip, port)
 t_forward_nonack("1.2.3.4", "5060");
 ...
 
-1.5.13.  t_set_fr(fr_inv_timeout [, fr_timeout])
+1.5.13. t_set_fr(fr_inv_timeout [, fr_timeout])
 
    Sets the fr_inv_timeout and optionally fr_timeout for the current
    transaction or for transactions created during the same script
@@ -1408,7 +1410,7 @@ branch_route[1] {
         }
 }
 
-1.5.14.  t_reset_fr()
+1.5.14. t_reset_fr()
 
    Resets the fr_inv_timer and fr_timer for the current transaction to the
    default values (set using the tm module parameters fr_inv_timer and
@@ -1427,7 +1429,7 @@ route {
 ...
 }
 
-1.5.15.  t_set_max_lifetime(inv_lifetime, noninv_lifetime)
+1.5.15. t_set_max_lifetime(inv_lifetime, noninv_lifetime)
 
    Sets the maximum lifetime for the current INVITE or non-INVITE
    transaction, or for transactions created during the same script
@@ -1456,7 +1458,7 @@ route {
                                           # INVITE and to 15s if not
 }
 
-1.5.16.  t_reset_max_lifetime()
+1.5.16. t_reset_max_lifetime()
 
    Resets the the maximum lifetime for the current INVITE or non-INVITE
    transaction to the default value (set using the tm module parameter
@@ -1475,7 +1477,7 @@ route {
 ...
 }
 
-1.5.17.  t_set_retr(retr_t1_interval, retr_t2_interval)
+1.5.17. t_set_retr(retr_t1_interval, retr_t2_interval)
 
    Sets the retr_t1_interval and retr_t2_interval for the current
    transaction or for transactions created during the same script
@@ -1521,7 +1523,7 @@ branch_route[1] {
         }
 }
 
-1.5.18.  t_reset_retr()
+1.5.18. t_reset_retr()
 
    Resets the retr_timer1 and retr_timer2 for the current transaction to
    the default values (set using the tm module parameters retr_timer1 and
@@ -1540,7 +1542,7 @@ route {
 ...
 }
 
-1.5.19.  t_set_auto_inv_100(0|1)
+1.5.19. t_set_auto_inv_100(0|1)
 
    Switch automatically sending 100 replies to INVITEs on/off on a per
    transaction basis. It overrides the auto_inv_100 value for the current
@@ -1557,7 +1559,7 @@ route {
 ...
 }
 
-1.5.20.  t_branch_timeout()
+1.5.20. t_branch_timeout()
 
    Returns true if the failure route is executed for a branch that did
    timeout. It can be used only from the failure_route.
@@ -1571,7 +1573,7 @@ failure_route[0]{
         }
 }
 
-1.5.21.  t_branch_replied()
+1.5.21. t_branch_replied()
 
    Returns true if the failure route is executed for a branch that did
    receive at least one reply in the past (the "current" reply is not
@@ -1589,7 +1591,7 @@ failure_route[0]{
         }
 }
 
-1.5.22.  t_any_timeout()
+1.5.22. t_any_timeout()
 
    Returns true if at least one of the current transactions branches did
    timeout.
@@ -1605,7 +1607,7 @@ failure_route[0]{
         }
 }
 
-1.5.23.  t_any_replied()
+1.5.23. t_any_replied()
 
    Returns true if at least one of the current transactions branches did
    receive some reply in the past. If called from a failure or onreply
@@ -1620,7 +1622,7 @@ onreply_route[0]{
         }
 }
 
-1.5.24.  t_grep_status("code")
+1.5.24. t_grep_status("code")
 
    Returns true if "code" is the final reply received (or locally
    generated) in at least one of the current transactions branches.
@@ -1634,7 +1636,7 @@ onreply_route[0]{
         }
 }
 
-1.5.25.  t_is_canceled()
+1.5.25. t_is_canceled()
 
    Returns true if the current transaction was canceled.
 
@@ -1647,7 +1649,7 @@ failure_route[0]{
         }
 }
 
-1.5.26.  t_is_expired()
+1.5.26. t_is_expired()
 
    Returns true if the current transaction has already been expired, i.e.
    the max_inv_lifetime/max_noninv_lifetime interval has already elapsed.
@@ -1661,7 +1663,7 @@ failure_route[0]{
         }
 }
 
-1.5.27.  t_relay_cancel()
+1.5.27. t_relay_cancel()
 
    Forwards the CANCEL if the corresponding INVITE transaction exists. The
    function is supposed to be used at the very beginning of the script,
@@ -1686,7 +1688,7 @@ if (method == CANCEL) {
         # do the same as for INVITEs
 }
 
-1.5.28.  t_lookup_cancel(), t_lookup_cancel(1)
+1.5.28. t_lookup_cancel(), t_lookup_cancel(1)
 
    Returns true if the corresponding INVITE transaction exists for a
    CANCEL request. The function can be called at the beginning of the
@@ -1718,12 +1720,17 @@ if (method == CANCEL) {
         # do the same as for INVITEs
 }
 
-1.5.29.  t_drop_replies()
+1.5.29. t_drop_replies([mode])
 
    Drops all the previously received replies in failure_route block to
-   make sure that none of them is picked up again. Works only if a new
-   branch is added to the transaction, or it is explicitly replied in the
-   script!
+   make sure that none of them is picked up again.
+
+   The parameter 'mode' controls which replies are dropped: 'a' or missing
+   - all replies are dropped; 'l' - replies received for last set of
+   branches are dropped; 'n' - no reply is dropped.
+
+   Dropping replies works only if a new branch is added to the
+   transaction, or it is explicitly replied in the script!
 
    Example 66. t_drop_replies() usage
 ...
@@ -1741,7 +1748,7 @@ failure_route[0]{
         }
 }
 
-1.5.30.  t_save_lumps()
+1.5.30. t_save_lumps()
 
    Forces the modifications of the processed SIP message to be saved in
    shared memory before t_relay() is called. The new branches which are
@@ -1781,7 +1788,7 @@ failure_route[1] {
         t_relay();
 }
 
-1.5.31.  t_load_contacts()
+1.5.31. t_load_contacts()
 
    This is the first of the two functions that can be used to implement
    serial/parallel forking based on the q value of individual branches in
@@ -1834,7 +1841,7 @@ if (!t_load_contacts()) {
 };
 ...
 
-1.5.32.  t_next_contacts()
+1.5.32. t_next_contacts()
 
    The function t_next_contacts is the second of the two functions that
    can be used to implement serial/parallel forking based on the q value
@@ -1897,7 +1904,7 @@ if (!t_next_contacts()) {
 };
 ...
 
-1.5.33.  t_check_trans()
+1.5.33. t_check_trans()
 
    t_check_trans() can be used to quickly check if a message belongs or is
    related to a transaction. It behaves differently for different types of
@@ -1947,7 +1954,7 @@ if ( method == "CANCEL" && !t_check_trans())
         sl_reply("403", "cancel out of the blue forbidden");
 # note: in this example t_check_trans() can be replaced by t_lookup_cancel()
 
-1.5.34.  t_set_disable_6xx(0|1)
+1.5.34. t_set_disable_6xx(0|1)
 
    Turn off/on 6xx replies special rfc conformant handling on a per
    transaction basis. If turned off (t_set_disable_6xx("1")) 6XXs will be
@@ -1966,7 +1973,7 @@ route {
 ...
 }
 
-1.5.35.  t_set_disable_failover(0|1)
+1.5.35. t_set_disable_failover(0|1)
 
    Turn off/on dns failover on a per transaction basis.
 
@@ -1981,6 +1988,75 @@ route {
 ...
 }
 
+1.5.36. t_replicate(params)
+
+   Replicate the SIP request to a specific address.
+
+   There are several function prototypes:
+     * t_replicate(uri),
+     * t_replicate(host, port),
+     * t_replicat_udp(host, port)
+     * t_replicate_tcp(host, port)
+     * t_replicate_tls(host, port)
+     * t_replicate_sctp(host, port)
+     * t_replicate_to(proto, hostport)
+
+   Meaning of the parameters is as follows:
+     * uri - SIP URI where the message should be sent. It can be given via
+       a script variable.
+     * host - host address where the message should be sent.
+     * port - port number.
+     * proto - transport protocol to be used.
+     * hostport - address in "host:port" format. It can be given via an
+       AVP.
+
+   Example 73. t_replicate usage
+...
+# sent to 1.2.3.4:5060 over tcp
+t_replicate("sip:1.2.3.4:5060;transport=tcp");
+
+# sent to 1.2.3.4:5061 over tls
+$var(h) = "1.2.3.4:5061";
+t_replicate("sip:$var(h);transport=tls");
+
+# sent to 1.2.3.4:5060 over udp
+t_replicate_to_udp("1.2.3.4", "5060");
+...
+
+1.5.37. t_relay_to(proxy, flags)
+
+   Forward the SIP request to a specific address, controlling internal
+   behavior via flags.
+
+   There are several function prototypes:
+     * t_relay_to(),
+     * t_relay_to(proxy),
+     * t_relay_to(flags)
+     * t_relay_to(proxy, flags)
+
+   Meaning of the parameters is as follows:
+     * proxy - address where the request should be sent. Format is:
+       "proto:host:port" - any of proto or port can be ommitted, along
+       with the semicolon after or before.
+     * flags - bitmask integer value to control the internal behavior.
+       Bits can be:
+          + 0x01 - do not generate 100 reply.
+          + 0x02 - do not generate reply on internal error (NOTE: has no
+            effect anymore).
+          + 0x04 - disable dns failover.
+
+   Example 74. t_replicate usage
+...
+# sent to 1.2.3.4:5060 over tcp
+t_relay_to("tcp:1.2.3.4:5060");
+
+# sent to 1.2.3.4 over tls
+t_relay_to("tls:1.2.3.4");
+
+# sent to dst URI or R-URI without a 100 reply
+t_relay_to("0x01");
+...
+
 1.6. TM Module API
 
    Revision History
@@ -2051,7 +2127,7 @@ end of body
 
 1.6.2. Functions
 
-1.6.2.1.  register_tmcb(cb_type, cb_func)
+1.6.2.1. register_tmcb(cb_type, cb_func)
 
    For programmatic use only--register a function to be called back on an
    event. See t_hooks.h for more details.
@@ -2060,7 +2136,7 @@ end of body
      * cb_type - Callback type.
      * cb_func - Callback function.
 
-1.6.2.2.  load_tm(*import_structure)
+1.6.2.2. load_tm(*import_structure)
 
    For programmatic use only--import exported TM functions. See the acc
    module for an example of use.
@@ -2068,7 +2144,7 @@ end of body
    Meaning of the parameters is as follows:
      * import_structure - Pointer to the import structure.
 
-1.6.2.3.  int t_suspend(struct sip_msg *msg, unsigned int *hash_index,
+1.6.2.3. int t_suspend(struct sip_msg *msg, unsigned int *hash_index,
 unsigned int *label)
 
    For programmatic use only. This function together with t_continue() can
@@ -2106,7 +2182,7 @@ unsigned int *label)
    t_suspend() should return 0 to make sure that the script processing
    does not continue.
 
-1.6.2.4.  int t_continue(unsigned int hash_index, unsigned int label, struct
+1.6.2.4. int t_continue(unsigned int hash_index, unsigned int label, struct
 action *route)
 
    For programmatic use only. This function is the pair of t_suspend(),

+ 156 - 3
modules/tm/doc/functions.xml

@@ -946,13 +946,20 @@ if (method == CANCEL) {
 
     <section id="t_drop_replies">
 	<title>
-	    <function>t_drop_replies()</function>
+	    <function>t_drop_replies([mode])</function>
 	</title>
 	<para>
 		Drops all the previously received replies in failure_route
 		block to make sure that none of them is picked up again.
-		Works only if a new branch is added to the transaction,
-		or it is explicitly replied in the script!
+	</para>
+	<para>
+		The parameter 'mode' controls which replies are dropped: 'a'
+		or missing - all replies are dropped; 'l' - replies received for
+		last set of branches are dropped; 'n' - no reply is dropped.
+	</para>
+	<para>
+		Dropping replies works only if a new branch is added to the
+		transaction, or it is explicitly replied in the script!
 	</para>
 	<example>
 	    <title><function>t_drop_replies()</function> usage</title>
@@ -1315,4 +1322,150 @@ route {
 	</example>
 	</section>
 
+	<section id="t_replicate">
+	<title>
+	    <function>t_replicate(params)</function>
+	</title>
+	<para>
+		Replicate the SIP request to a specific address.
+	</para>
+	<para>
+		There are several function prototypes:
+		<itemizedlist>
+		<listitem>
+	    <function>t_replicate(uri)</function>,
+		</listitem>
+		<listitem>
+	    <function>t_replicate(host, port)</function>,
+		</listitem>
+		<listitem>
+	    <function>t_replicat_udp(host, port)</function>
+		</listitem>
+		<listitem>
+	    <function>t_replicate_tcp(host, port)</function>
+		</listitem>
+		<listitem>
+	    <function>t_replicate_tls(host, port)</function>
+		</listitem>
+		<listitem>
+	    <function>t_replicate_sctp(host, port)</function>
+		</listitem>
+		<listitem>
+	    <function>t_replicate_to(proto, hostport)</function>
+		</listitem>
+		</itemizedlist>
+	</para>
+	<para>Meaning of the parameters is as follows:</para>
+	<itemizedlist>
+	    <listitem>
+		<para><emphasis>uri</emphasis> - SIP URI where the message should be sent.
+		It can be given via a script variable.
+		</para>
+	    </listitem>
+	    <listitem>
+		<para><emphasis>host</emphasis> - host address where the message should be sent.
+		</para>
+	    </listitem>
+	    <listitem>
+		<para><emphasis>port</emphasis> - port number.
+		</para>
+	    </listitem>
+	    <listitem>
+		<para><emphasis>proto</emphasis> - transport protocol to be used.
+		</para>
+	    </listitem>
+	    <listitem>
+		<para><emphasis>hostport</emphasis> - address in "host:port" format. It can be
+		given via an AVP.
+		</para>
+	    </listitem>
+	</itemizedlist>
+	<example>
+	    <title><function>t_replicate</function> usage</title>
+	    <programlisting>
+...
+# sent to 1.2.3.4:5060 over tcp
+t_replicate("sip:1.2.3.4:5060;transport=tcp");
+
+# sent to 1.2.3.4:5061 over tls
+$var(h) = "1.2.3.4:5061";
+t_replicate("sip:$var(h);transport=tls");
+
+# sent to 1.2.3.4:5060 over udp
+t_replicate_to_udp("1.2.3.4", "5060");
+...
+	    </programlisting>
+	</example>
+    </section>
+	<section id="t_relay_to">
+	<title>
+	    <function>t_relay_to(proxy, flags)</function>
+	</title>
+	<para>
+		Forward the SIP request to a specific address, controlling internal
+		behavior via flags.
+	</para>
+	<para>
+		There are several function prototypes:
+		<itemizedlist>
+		<listitem>
+	    <function>t_relay_to()</function>,
+		</listitem>
+		<listitem>
+	    <function>t_relay_to(proxy)</function>,
+		</listitem>
+		<listitem>
+	    <function>t_relay_to(flags)</function>
+		</listitem>
+		<listitem>
+	    <function>t_relay_to(proxy, flags)</function>
+		</listitem>
+		</itemizedlist>
+	</para>
+	<para>Meaning of the parameters is as follows:</para>
+	<itemizedlist>
+	    <listitem>
+		<para><emphasis>proxy</emphasis> - address where the request should
+		be sent. Format is: "proto:host:port" - any of proto or port can be
+		ommitted, along with the semicolon after or before.
+		</para>
+	    </listitem>
+	    <listitem>
+		<para><emphasis>flags</emphasis> - bitmask integer value to control
+		the internal behavior. Bits can be:
+		</para>
+		<itemizedlist>
+	    <listitem>
+		<para><emphasis>0x01</emphasis> - do not generate 100 reply.
+		</para>
+	    </listitem>
+	    <listitem>
+		<para><emphasis>0x02</emphasis> - do not generate reply on internal
+		error (NOTE: has no effect anymore).
+		</para>
+	    </listitem>
+	    <listitem>
+		<para><emphasis>0x04</emphasis> - disable dns failover.
+		</para>
+	    </listitem>
+		</itemizedlist>
+	    </listitem>
+	</itemizedlist>
+	<example>
+	    <title><function>t_replicate</function> usage</title>
+	    <programlisting>
+...
+# sent to 1.2.3.4:5060 over tcp
+t_relay_to("tcp:1.2.3.4:5060");
+
+# sent to 1.2.3.4 over tls
+t_relay_to("tls:1.2.3.4");
+
+# sent to dst URI or R-URI without a 100 reply
+t_relay_to("0x01");
+...
+	    </programlisting>
+	</example>
+    </section>
+
 </section>

+ 76 - 15
modules/tm/t_funcs.c

@@ -63,6 +63,8 @@
 #include "../../hash_func.h"
 #include "../../dset.h"
 #include "../../mem/mem.h"
+#include "../../sr_compat.h"
+#include "../../pvar.h"
 #include "defs.h"
 #include "t_funcs.h"
 #include "t_fwd.h"
@@ -399,36 +401,88 @@ done:
 int init_avp_params(char *fr_timer_param, char *fr_inv_timer_param,
 					char* contacts_avp_param)
 {
+	pv_spec_t avp_spec;
+
 	if (fr_timer_param && *fr_timer_param) {
 		fr_timer_str.s = fr_timer_param;
 		fr_timer_str.len = strlen(fr_timer_str.s);
-		if (parse_avp_spec( &fr_timer_str, &fr_timer_avp_type,
-		&fr_timer_avp, &fr_timer_index)<0) {
-			LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid fr_timer "
-				"AVP specs \"%s\"\n", fr_timer_param);
-			return -1;
+
+		if(sr_cfg_compat==SR_COMPAT_KAMAILIO) {
+			if (pv_parse_spec(&fr_timer_str, &avp_spec)==0
+			        || avp_spec.type!=PVT_AVP) {
+			        LM_ERR("malformed or non AVP %s AVP definition\n",
+							fr_timer_param);
+				return -1;
+			}
+
+			if(pv_get_avp_name(0, &avp_spec.pvp, &fr_timer_avp, 
+						(unsigned short*)&fr_timer_avp_type)!=0)
+			{
+				LM_ERR("[%s]- invalid AVP definition\n", fr_timer_param);
+				return -1;
+			}
+		} else {
+			if (parse_avp_spec( &fr_timer_str, &fr_timer_avp_type,
+			&fr_timer_avp, &fr_timer_index)<0) {
+				LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid fr_timer "
+					"AVP specs \"%s\"\n", fr_timer_param);
+				return -1;
+			}
 		}
 	}
 
 	if (fr_inv_timer_param && *fr_inv_timer_param) {
 		fr_inv_timer_str.s = fr_inv_timer_param;
 		fr_inv_timer_str.len = strlen(fr_inv_timer_str.s);
-		if (parse_avp_spec( &fr_inv_timer_str, &fr_inv_timer_avp_type, 
-		&fr_inv_timer_avp, &fr_inv_timer_index)<0) {
-			LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid fr_inv_timer "
-				"AVP specs \"%s\"\n", fr_inv_timer_param);
-			return -1;
+
+		if(sr_cfg_compat==SR_COMPAT_KAMAILIO) {
+			if (pv_parse_spec(&fr_inv_timer_str, &avp_spec)==0
+					|| avp_spec.type!=PVT_AVP) {
+				LM_ERR("malformed or non AVP %s AVP definition\n",
+					fr_inv_timer_param);
+				return -1;
+			}
+
+			if(pv_get_avp_name(0, &avp_spec.pvp, &fr_inv_timer_avp,
+						(unsigned short*)&fr_inv_timer_avp_type)!=0)
+			{
+				LM_ERR("[%s]- invalid AVP definition\n", fr_inv_timer_param);
+				return -1;
+			}
+		} else {
+			if (parse_avp_spec( &fr_inv_timer_str, &fr_inv_timer_avp_type, 
+			&fr_inv_timer_avp, &fr_inv_timer_index)<0) {
+				LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid fr_inv_timer "
+					"AVP specs \"%s\"\n", fr_inv_timer_param);
+				return -1;
+			}
 		}
 	}
 
 	if (contacts_avp_param && *contacts_avp_param) {
 		contacts_avp_str.s = contacts_avp_param;
 		contacts_avp_str.len = strlen(contacts_avp_str.s);
-		if (parse_avp_spec( &contacts_avp_str, &contacts_avp_type,
-							&contacts_avp, &contacts_avp_index)<0) {
-			LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid contact_avp_params "
-				"AVP specs \"%s\"\n", contacts_avp_param);
-			return -1;
+
+		if(sr_cfg_compat==SR_COMPAT_KAMAILIO) {
+			if ((pv_parse_spec(&contacts_avp_str, &avp_spec) == 0) 
+					|| (avp_spec.type != PVT_AVP)) {
+				LM_ERR("malformed or non AVP definition <%s>\n",
+					contacts_avp_param);
+				return -1;
+			}
+
+			if(pv_get_avp_name(0, &(avp_spec.pvp), &contacts_avp,
+						(unsigned short*)&contacts_avp_type) != 0) {
+				LM_ERR("invalid AVP definition <%s>\n", contacts_avp_param);
+				return -1;
+			}
+		} else {
+			if (parse_avp_spec( &contacts_avp_str, &contacts_avp_type,
+								&contacts_avp, &contacts_avp_index)<0) {
+				LOG(L_CRIT,"ERROR:tm:init_avp_params: invalid contact_avp_params "
+					"AVP specs \"%s\"\n", contacts_avp_param);
+				return -1;
+			}
 		}
 	}
 
@@ -464,6 +518,13 @@ static inline int avp2timer(unsigned int* timer, int type, int_str name)
 		*timer = val_istr.n;
 	}
 
+	if(sr_cfg_compat==SR_COMPAT_KAMAILIO) {
+		if(*timer>0 && *timer<=120) {
+			LM_WARN("too small given timer value: %ums (using T*1000)\n",
+					*timer);
+			*timer *= 1000;
+		}
+	}
 	return *timer==0; /* 1 if 0 (use default), 0 if !=0 (use *timer) */
 }
 

+ 2 - 2
modules/tm/t_hooks.c

@@ -184,14 +184,14 @@ int register_tmcb( struct sip_msg* p_msg, struct cell *t, int types,
 		return E_BUG;
 	}
 
-	if (types&TMCB_REQUEST_IN) {
+	if ((types!=TMCB_MAX) && (types&TMCB_REQUEST_IN)) {
 		if (types!=TMCB_REQUEST_IN) {
 			LOG(L_CRIT, "BUG:tm:register_tmcb: callback type TMCB_REQUEST_IN "
 				"can't be register along with types\n");
 			return E_BUG;
 		}
 		cb_list = req_in_tmcb_hl;
-	}else if (types & TMCB_LOCAL_REQUEST_IN) {
+	}else if ((types!=TMCB_MAX) && (types & TMCB_LOCAL_REQUEST_IN)) {
 		if (types!=TMCB_LOCAL_REQUEST_IN) {
 			LOG(L_CRIT, "BUG:tm:register_tmcb: callback type"
 					" TMCB_LOCAL_REQUEST_IN can't be register along with"

+ 35 - 11
modules/tm/t_reply.c

@@ -137,6 +137,7 @@
 #include "t_lookup.h"
 #include "t_fwd.h"
 #include "../../fix_lumps.h"
+#include "../../sr_compat.h"
 #include "t_stats.h"
 #include "uac.h"
 
@@ -608,7 +609,7 @@ static int _reply_light( struct cell *trans, char* buf, unsigned int len,
 			}
 #endif /* TMCB_ONSEND */
 		}
-		DBG("DEBUG: reply sent out. buf=%p: %.9s..., shmem=%p: %.9s\n",
+		DBG("DEBUG: reply sent out. buf=%p: %.20s..., shmem=%p: %.20s\n",
 			buf, buf, rb->buffer, rb->buffer );
 	}
 	if (code>=200) {
@@ -1028,6 +1029,7 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
 	int inv_through;
 	int extra_flags;
 	int i;
+	int replies_dropped;
 
 	/* note: this code never lets replies to CANCEL go through;
 	   we generate always a local 200 for CANCEL; 200s are
@@ -1114,7 +1116,11 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
 		Trans->flags&=~T_6xx; /* clear the 6xx flag , we want to 
 								 allow new branches from the failure route */
 
-		drop_replies = 0;
+		if(sr_cfg_compat==SR_COMPAT_KAMAILIO)
+			drop_replies = 3;
+		else
+			drop_replies = 0;
+		replies_dropped = 0;
 		/* run ON_FAILURE handlers ( route and callbacks) */
 		if (unlikely(has_tran_tmcbs( Trans, TMCB_ON_FAILURE_RO|TMCB_ON_FAILURE)
 						|| Trans->on_negative )) {
@@ -1125,9 +1131,19 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
 						 	FL_REPLIED:0);
 			run_failure_handlers( Trans, Trans->uac[picked_branch].reply,
 									picked_code, extra_flags);
-			if (unlikely(drop_replies)) {
+			if (unlikely((drop_replies==3 && branch_cnt<Trans->nr_of_outgoings) ||
+						         (drop_replies!=0 && drop_replies!=3))
+					) {
 				/* drop all the replies that we have already saved */
-				for (i=0; i<branch_cnt; i++) {
+				i = 0;
+				if(drop_replies==2)
+				{
+					for(i=branch_cnt-1; i>=0; i--)
+						if(Trans->uac[i].flags&TM_UAC_FLAG_FB)
+							break;
+					if(i<0) i=0;
+				}
+				for (; i<branch_cnt; i++) {
 					if (Trans->uac[i].reply &&
 					(Trans->uac[i].reply != FAKED_REPLY) &&
 					(Trans->uac[i].reply->msg_flags & FL_SHM_CLONE))
@@ -1139,6 +1155,7 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
 				/* make sure that the selected reply is not relayed even if
 				there is not any new branch added -- should not happen */
 				picked_branch = -1;
+				replies_dropped = 1;
 			}
 		}
 
@@ -1167,7 +1184,7 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
 		if (branch_cnt<Trans->nr_of_outgoings){
 			/* the new branches might be already "finished" => we
 			 * must use t_pick_branch again */
-			new_branch=t_pick_branch((drop_replies==0)?
+			new_branch=t_pick_branch((replies_dropped==0)?
 							branch :
 							-1, /* make sure we do not pick
 								the current branch */
@@ -1176,7 +1193,7 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
 						&picked_code);
 
 			if (new_branch<0){
-				if (likely(drop_replies==0)) {
+				if (likely(replies_dropped==0)) {
 					if (new_branch==-2) { /* branches open yet */
 						*should_store=1;
 						*should_relay=-1;
@@ -1202,7 +1219,7 @@ static enum rps t_should_relay_response( struct cell *Trans , int new_code,
 				/* found a new_branch */
 				picked_branch=new_branch;
 			}
-		} else if (unlikely(drop_replies)) {
+		} else if (unlikely(replies_dropped)) {
 			/* Either the script writer did not add new branches
 			after calling t_drop_replies(), or tm was unable
 			to add the new branches to the transaction. */
@@ -1852,6 +1869,7 @@ int reply_received( struct sip_msg  *p_msg )
 #ifdef TMCB_ONSEND
 	struct tmcb_params onsend_params;
 #endif
+	struct run_act_ctx ctx;
 
 	/* make sure we know the associated transaction ... */
 	if (t_check( p_msg  , &branch )==-1)
@@ -1994,8 +2012,14 @@ int reply_received( struct sip_msg  *p_msg )
 		/* lock onreply_route, for safe avp usage */
 		LOCK_REPLIES( t );
 		replies_locked=1;
-		if (run_top_route(onreply_rt.rlist[t->on_reply], p_msg, 0)<0)
-			LOG(L_ERR, "ERROR: on_reply processing failed\n");
+		run_top_route(onreply_rt.rlist[t->on_reply], p_msg, &ctx);
+		if ((ctx.run_flags&DROP_R_F)  && (msg_status<200)) {
+			if (unlikely(replies_locked)) {
+				replies_locked = 0;
+				UNLOCK_REPLIES( t );
+			}
+			goto done;
+		}
 		/* transfer current message context back to t */
 		if (t->uas.request) t->uas.request->flags=p_msg->flags;
 		getbflagsval(0, &uac->branch_flags);
@@ -2230,14 +2254,14 @@ error:
 /* drops all the replies to make sure
  * that none of them is picked up again
  */
-void t_drop_replies(void)
+void t_drop_replies(int v)
 {
 	/* It is too risky to free the replies that are in shm mem
 	at the middle of failure_route block, because other functions might
 	need them as well. And it can also happen that the current reply is not yet
 	in shm mem, we are just going to clone it. So better to set a flag
 	and check it after failure_route has ended. (Miklos) */
-	drop_replies = 1;
+	drop_replies = v;
 }
 
 #if 0

+ 1 - 1
modules/tm/t_reply.h

@@ -153,7 +153,7 @@ int t_pick_branch_blind(struct cell *t, int *res_code);
 /* drops all the replies to make sure
  * that none of them is picked up again
  */
-void t_drop_replies(void);
+void t_drop_replies(int v);
 
 extern const char* rpc_reply_doc[2];
 void rpc_reply(rpc_t* rpc, void* c);

+ 25 - 1
modules/tm/timer.c

@@ -131,7 +131,8 @@
 #include "../../parser/parser_f.h"
 #include "../../ut.h"
 #include "../../timer_ticks.h"
-#include "../../compiler_opt.h"
+#include "../../compiler_opt.h" 
+#include "../../sr_compat.h" 
 #include "t_funcs.h"
 #include "t_reply.h"
 #include "t_cancel.h"
@@ -173,6 +174,29 @@ struct msgid_var user_noninv_max_lifetime;
 /* fix timer values to ticks */
 int tm_init_timers()
 {
+	if(sr_cfg_compat==SR_COMPAT_KAMAILIO) {
+		if(default_tm_cfg.fr_timeout<=120) {
+			LM_WARN("too small given fr_timer value: %ums (using T*1000)\n",
+					default_tm_cfg.fr_timeout);
+			default_tm_cfg.fr_timeout *= 1000;
+		}
+		if(default_tm_cfg.fr_inv_timeout<=120) {
+			LM_WARN("too small given fr_inv_timer value: %ums (using T*1000)\n",
+					default_tm_cfg.fr_inv_timeout);
+			default_tm_cfg.fr_inv_timeout *= 1000;
+		}
+		if(default_tm_cfg.wait_timeout<=120) {
+			LM_WARN("too small given wait_timer value: %ums (using T*1000)\n",
+					default_tm_cfg.wait_timeout);
+			default_tm_cfg.wait_timeout *= 1000;
+		}
+		if(default_tm_cfg.delete_timeout<=120) {
+			LM_WARN("too small given delete_timer value: %ums (using T*1000)\n",
+					default_tm_cfg.delete_timeout);
+			default_tm_cfg.delete_timeout *= 1000;
+		}
+	}
+
 	default_tm_cfg.fr_timeout=MS_TO_TICKS(default_tm_cfg.fr_timeout); 
 	default_tm_cfg.fr_inv_timeout=MS_TO_TICKS(default_tm_cfg.fr_inv_timeout);
 	default_tm_cfg.wait_timeout=MS_TO_TICKS(default_tm_cfg.wait_timeout);

+ 217 - 1
modules/tm/tm.c

@@ -114,6 +114,7 @@
 #include "../../cfg/cfg.h"
 #include "../../globals.h"
 #include "../../timer_ticks.h"
+#include "../../mod_fix.h"
 
 #include "config.h"
 #include "sip_msg.h"
@@ -145,6 +146,7 @@ static int fixup_on_reply(void** param, int param_no);
 static int fixup_on_branch(void** param, int param_no);
 static int fixup_t_reply(void** param, int param_no);
 static int fixup_on_sl_reply(modparam_t type, void* val);
+static int fixup_t_relay_to(void** param, int param_no);
 
 /* init functions */
 static int mod_init(void);
@@ -180,6 +182,10 @@ inline static int w_t_relay_to_sctp( struct sip_msg  *p_msg , char *proxy,
 inline static int w_t_relay_to_sctp_uri( struct sip_msg*, char*, char*);
 #endif
 inline static int w_t_relay_to_avp(struct sip_msg* msg, char* str,char*);
+inline static int w_t_relay_to(struct sip_msg* msg, char* str,char*);
+inline static int w_t_replicate_uri( struct sip_msg  *p_msg ,
+				char *uri,       /* sip uri as string or variable */
+				char *_foo       /* nothing expected */ );
 inline static int w_t_replicate( struct sip_msg  *p_msg ,
 				char *proxy, /* struct proxy_l *proxy expected */
 				char *_foo       /* nothing expected */ );
@@ -289,6 +295,8 @@ static cmd_export_t cmds[]={
 	{T_RELAY_TO_SCTP,       w_t_relay_to_sctp_uri,    0, 0,
 			REQUEST_ROUTE|FAILURE_ROUTE},
 #endif
+	{"t_replicate",        w_t_replicate_uri,       1, fixup_var_str_1,
+			REQUEST_ROUTE},
 	{"t_replicate",        w_t_replicate,           2, fixup_hostport2proxy,
 			REQUEST_ROUTE},
 	{"t_replicate_udp",    w_t_replicate_udp,       2, fixup_hostport2proxy,
@@ -313,6 +321,12 @@ static cmd_export_t cmds[]={
 			REQUEST_ROUTE | FAILURE_ROUTE },
 	{"t_relay_to_avp", w_t_relay_to_avp,  		2, fixup_proto_hostport2proxy,
 			REQUEST_ROUTE},
+	{"t_relay_to",			w_t_relay_to,           0, 0,
+			REQUEST_ROUTE | FAILURE_ROUTE },
+	{"t_relay_to",			w_t_relay_to,           1, fixup_t_relay_to,
+			REQUEST_ROUTE | FAILURE_ROUTE },
+	{"t_relay_to",			w_t_relay_to,           2, fixup_t_relay_to,
+			REQUEST_ROUTE | FAILURE_ROUTE },
 	{T_FORWARD_NONACK,     w_t_forward_nonack,      2, fixup_hostport2proxy,
 			REQUEST_ROUTE},
 	{T_FORWARD_NONACK_URI, w_t_forward_nonack_uri,  0, 0,
@@ -381,6 +395,8 @@ static cmd_export_t cmds[]={
 			REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
 	{"t_drop_replies",    w_t_drop_replies,         0, 0,
 			FAILURE_ROUTE},
+	{"t_drop_replies",    w_t_drop_replies,         1, 0,
+			FAILURE_ROUTE},
 	{"t_save_lumps",      w_t_save_lumps,           0, 0,
 			REQUEST_ROUTE},
 	{"t_check_trans",	t_check_trans,				0, 0,
@@ -1363,6 +1379,39 @@ inline static int w_t_relay_to_avp( struct sip_msg  *p_msg ,
 	return r;
 }
 
+inline static int w_t_replicate_uri(struct sip_msg  *msg ,
+				char *uri,       /* sip uri as string or variable */
+				char *_foo       /* nothing expected */ )
+{
+	struct proxy_l *proxy;
+	struct sip_uri turi;
+	str suri;
+	int r = -1;
+
+	memset(&turi, 0, sizeof(struct sip_uri));
+	if(fixup_get_svalue(msg, (gparam_p)uri, &suri)!=0)
+	{
+		LM_ERR("invalid replicate uri parameter");
+		return -1;
+	}
+	if(parse_uri(suri.s, suri.len, &turi)!=0)
+	{
+		LM_ERR("bad replicate SIP address!\n");
+		return -1;
+	}
+
+	proxy=mk_proxy(&turi.host, turi.port_no, turi.proto);
+	if (proxy==0) {
+		LM_ERR("cannot create proxy from URI <%.*s>\n",
+			suri.len, suri.s );
+		return -1;
+	}
+
+	r = t_replicate(msg, proxy, proxy->proto);
+	free_proxy(proxy);
+	return r;
+
+}
 
 inline static int w_t_replicate( struct sip_msg  *p_msg ,
 	char *proxy, /* struct proxy_l *proxy expected */
@@ -1726,7 +1775,14 @@ int t_grep_status(struct sip_msg* msg, char* status, char* bar)
  * that none of them is picked up again */
 static int w_t_drop_replies(struct sip_msg* msg, char* foo, char* bar)
 {
-	t_drop_replies();
+	if(foo==NULL)
+		t_drop_replies(1);
+	else if(*foo=='n')
+		t_drop_replies(0);
+	else if(*foo=='l')
+		t_drop_replies(2);
+	else
+		t_drop_replies(1);
 	return 1;
 }
 
@@ -1832,3 +1888,163 @@ static int t_check_trans(struct sip_msg* msg, char* foo, char* bar)
 	}
 	return -1;
 }
+
+static int hexatoi(str *s, unsigned int* result)
+{
+	int i, xv, fact;
+
+	/* more than 32bit hexa? */
+	if (s->len>8)
+		return -1;
+
+	*result = 0;
+	fact = 1;
+
+	for(i=s->len-1; i>=0 ;i--)
+	{
+		xv = hex2int(s->s[i]);
+		if(xv<0)
+			return -1;
+
+		*result += (xv * fact);
+		fact *= 16;
+	}
+	return 0;
+}
+
+static int fixup_t_relay_to(void** param, int param_no)
+{
+
+	int port;
+	int proto;
+	unsigned int flags;
+	struct proxy_l *proxy;
+	action_u_t *a;
+	str s;
+	str host;
+
+	s.s = (char*)*param;
+	s.len = strlen(s.s);
+	LM_DBG("fixing (%s, %d)\n", s.s, param_no);
+	if (param_no==1){
+		a = fixup_get_param(param, param_no, 2);
+		if(a==NULL)
+		{
+			LM_CRIT("server error for parameter <%s>\n",s.s);
+			return E_UNSPEC;
+		}
+		if(a->u.string!=NULL) {
+			/* second parameter set, first should be proxy addr */
+			if (parse_phostport(s.s, &host.s, &host.len, &port, &proto)!=0){
+				LM_CRIT("invalid proxy addr parameter <%s>\n",s.s);
+				return E_UNSPEC;
+			}
+
+			proxy = mk_proxy(&host, port, proto);
+			if (proxy==0) {
+				LM_ERR("failed to build proxy structure for <%.*s>\n", host.len, host.s );
+				return E_UNSPEC;
+			}
+			*(param)=proxy;
+			return 0;
+		} else {
+			/* no second parameter, then is proxy addr or flags */
+			flags = 0;
+			if (s.len>2 && s.s[0]=='0' && s.s[1]=='x') {
+				s.s += 2;
+				s.len -= 2;
+				if(hexatoi(&s, &flags)<0)
+				{
+					LM_CRIT("invalid hexa flags <%s>\n", s.s);
+					return E_UNSPEC;
+				}
+				a->u.data = (void*)(unsigned long int)flags;
+				*(param)= 0;
+				return 0;
+			} else {
+				if(str2int(&s, &flags)==0)
+				{
+					a->u.data = (void*)(unsigned long int)flags;
+					*(param)= 0;
+					return 0;
+				} else {
+					/* try proxy */
+					if (parse_phostport(s.s, &host.s, &host.len, &port, &proto)!=0){
+						LM_CRIT("invalid proxy addr parameter <%s>\n",s.s);
+						return E_UNSPEC;
+					}
+
+					proxy = mk_proxy(&host, port, proto);
+					if (proxy==0) {
+						LM_ERR("failed to build proxy structure for <%.*s>\n", host.len, host.s );
+						return E_UNSPEC;
+					}
+					*(param)=proxy;
+					return 0;
+				}
+			}
+		}
+	} else if (param_no==2) {
+		/* flags */
+		flags = 0;
+		if (s.len>2 && s.s[0]=='0' && s.s[1]=='x') {
+			s.s += 2;
+			s.len -= 2;
+			if(hexatoi(&s, &flags)<0)
+			{
+				LM_CRIT("invalid hexa flags <%s>\n", s.s);
+				return E_UNSPEC;
+			}
+			*(param) = (void*)(unsigned long int)flags;
+			return 0;
+		} else {
+			if(str2int(&s, &flags)==0)
+			{
+				*(param) = (void*)(unsigned long int)flags;
+				return 0;
+			} else {
+				LM_CRIT("invalid flags <%s>\n", s.s);
+				return E_UNSPEC;
+			}
+		}
+	} else {
+		LM_ERR("invalid parameter number %d\n", param_no);
+		return E_BUG;
+	}
+}
+
+
+inline static int w_t_relay_to(struct sip_msg *msg, char *proxy, char *flags)
+{
+	unsigned int fl;
+	struct proxy_l *px;
+	fparam_t param;
+
+	fl = (unsigned int)(long)(void*)flags;
+	px = (struct proxy_l*)proxy;
+
+	if(flags!=0)
+	{
+		memset(&param, 0, sizeof(fparam_t));
+		param.type = FPARAM_INT;
+		/* no auto 100 trying */
+		if(fl&1) {
+			param.v.i = 0;
+			t_set_auto_inv_100(msg, (char*)(&param), 0);
+		}
+		/* no auto negative reply - not implemented */
+		/*
+		if(fl&2) {
+			param.v.i = 1;
+			t_set_disable_internal_reply(msg, (char*)param, 0);
+		}
+		*/
+		/* no dns failover */
+		if(fl&4) {
+			param.v.i = 1;
+			t_set_disable_failover(msg, (char*)(&param), 0);
+		}
+	}
+	return _w_t_relay_to(msg, px, PROTO_NONE);
+}
+

+ 62 - 30
modules/topoh/README

@@ -26,11 +26,13 @@ Daniel-Constantin Mierla
         3. Exported Parameters
 
               3.1. mask_key (str)
-              3.2. mask_callid (integer)
-              3.3. uparam_name (str)
-              3.4. uparam_prefix (str)
-              3.5. vparam_name (str)
-              3.6. vparam_prefix (str)
+              3.2. mask_ip (str)
+              3.3. mask_callid (integer)
+              3.4. uparam_name (str)
+              3.5. uparam_prefix (str)
+              3.6. vparam_name (str)
+              3.7. vparam_prefix (str)
+              3.8. callid_prefix (str)
 
         4. Exported Functions
 
@@ -39,11 +41,13 @@ Daniel-Constantin Mierla
    List of Examples
 
    1.1. Set mask_key parameter
-   1.2. Set mask_callid parameter
-   1.3. Set uparam_name parameter
-   1.4. Set uparam_prefix parameter
-   1.5. Set vparam_name parameter
-   1.6. Set vparam_prefix parameter
+   1.2. Set mask_ip parameter
+   1.3. Set mask_callid parameter
+   1.4. Set uparam_name parameter
+   1.5. Set uparam_prefix parameter
+   1.6. Set vparam_name parameter
+   1.7. Set vparam_prefix parameter
+   1.8. Set callid_prefix parameter
 
 Chapter 1. Admin Guide
 
@@ -58,11 +62,13 @@ Chapter 1. Admin Guide
    3. Exported Parameters
 
         3.1. mask_key (str)
-        3.2. mask_callid (integer)
-        3.3. uparam_name (str)
-        3.4. uparam_prefix (str)
-        3.5. vparam_name (str)
-        3.6. vparam_prefix (str)
+        3.2. mask_ip (str)
+        3.3. mask_callid (integer)
+        3.4. uparam_name (str)
+        3.5. uparam_prefix (str)
+        3.6. vparam_name (str)
+        3.7. vparam_prefix (str)
+        3.8. callid_prefix (str)
 
    4. Exported Functions
 
@@ -104,11 +110,13 @@ Chapter 1. Admin Guide
 3. Exported Parameters
 
    3.1. mask_key (str)
-   3.2. mask_callid (integer)
-   3.3. uparam_name (str)
-   3.4. uparam_prefix (str)
-   3.5. vparam_name (str)
-   3.6. vparam_prefix (str)
+   3.2. mask_ip (str)
+   3.3. mask_callid (integer)
+   3.4. uparam_name (str)
+   3.5. uparam_prefix (str)
+   3.6. vparam_name (str)
+   3.7. vparam_prefix (str)
+   3.8. callid_prefix (str)
 
 3.1. mask_key (str)
 
@@ -121,7 +129,20 @@ Chapter 1. Admin Guide
 modparam("topoh", "mask_key", "some secret here")
 ...
 
-3.2. mask_callid (integer)
+3.2. mask_ip (str)
+
+   IP address to be used in masked headers to build valid SIP URIs. Can be
+   any IP address, does not affect routing when used on the main SIP
+   server.
+
+   Default value is "10.1.1.10".
+
+   Example 1.2. Set mask_ip parameter
+...
+modparam("topoh", "mask_ip", "192.168.0.1")
+...
+
+3.3. mask_callid (integer)
 
    Whether to encode or not the call-id. Some SIP extensions include the
    call-id in SIP message payload or header, so it is safe to not encode
@@ -130,55 +151,66 @@ modparam("topoh", "mask_key", "some secret here")
 
    Default value is 0 (do not mask).
 
-   Example 1.2. Set mask_callid parameter
+   Example 1.3. Set mask_callid parameter
 ...
 modparam("topoh", "mask_callid", 1)
 ...
 
-3.3. uparam_name (str)
+3.4. uparam_name (str)
 
    Name of URI param where to store encoded value.
 
    Default value is "line".
 
-   Example 1.3. Set uparam_name parameter
+   Example 1.4. Set uparam_name parameter
 ...
 modparam("topoh", "uparam_name", "myparam")
 ...
 
-3.4. uparam_prefix (str)
+3.5. uparam_prefix (str)
 
    Prefix to be added in encoded URI params.
 
    Default value is "sr-".
 
-   Example 1.4. Set uparam_prefix parameter
+   Example 1.5. Set uparam_prefix parameter
 ...
 modparam("topoh", "uparam_prefix", "xyz")
 ...
 
-3.5. vparam_name (str)
+3.6. vparam_name (str)
 
    Name of Via param where to store encoded value.
 
    Default value is "branch".
 
-   Example 1.5. Set vparam_name parameter
+   Example 1.6. Set vparam_name parameter
 ...
 modparam("topoh", "vparam_name", "myv")
 ...
 
-3.6. vparam_prefix (str)
+3.7. vparam_prefix (str)
 
    Prefix to be added in encoded Via params.
 
    Default value is "z9hG4bKsr-".
 
-   Example 1.6. Set vparam_prefix parameter
+   Example 1.7. Set vparam_prefix parameter
 ...
 modparam("topoh", "vparam_prefix", "xyz")
 ...
 
+3.8. callid_prefix (str)
+
+   Prefix to be added in encoded Call-ID: headers.
+
+   Default value is "!!:".
+
+   Example 1.8. Set callid_prefix parameter
+...
+modparam("topoh", "callid_prefix", "***")
+...
+
 4. Exported Functions
 
    4.1.

+ 40 - 0
modules/topoh/doc/topoh_admin.xml

@@ -82,6 +82,27 @@
 ...
 modparam("topoh", "mask_key", "some secret here")
 ...
+</programlisting>
+		</example>
+	</section>
+	<section>
+		<title><varname>mask_ip</varname> (str)</title>
+		<para>
+		IP address to be used in masked headers to build valid
+		SIP URIs. Can be any IP address, does not affect routing
+		when used on the main SIP server.
+		</para>
+		<para>
+		<emphasis>
+			Default value is "10.1.1.10".
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>mask_ip</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("topoh", "mask_ip", "192.168.0.1")
+...
 </programlisting>
 		</example>
 	</section>
@@ -181,6 +202,25 @@ modparam("topoh", "vparam_name", "myv")
 ...
 modparam("topoh", "vparam_prefix", "xyz")
 ...
+</programlisting>
+		</example>
+	</section>
+	<section>
+		<title><varname>callid_prefix</varname> (str)</title>
+		<para>
+		Prefix to be added in encoded Call-ID: headers.
+		</para>
+		<para>
+		<emphasis>
+			Default value is "!!:".
+		</emphasis>
+		</para>
+		<example>
+		<title>Set <varname>callid_prefix</varname> parameter</title>
+		<programlisting format="linespecific">
+...
+modparam("topoh", "callid_prefix", "***")
+...
 </programlisting>
 		</example>
 	</section>

+ 132 - 4
modules/topoh/th_msg.c

@@ -24,6 +24,7 @@
 #include "../../mem/mem.h"
 #include "../../data_lump.h"
 #include "../../forward.h"
+#include "../../trim.h"
 #include "../../msg_translator.h"
 #include "../../parser/parse_rr.h"
 #include "../../parser/parse_uri.h"
@@ -32,6 +33,7 @@
 #include "../../parser/parse_to.h"
 #include "../../parser/parse_via.h"
 #include "../../parser/contact/parse_contact.h"
+#include "../../parser/parse_refer_to.h"
 #include "th_mask.h"
 #include "th_msg.h"
 
@@ -39,6 +41,7 @@ extern str th_cookie_name;
 extern str th_cookie_value;
 extern str th_via_prefix;
 extern str th_uri_prefix;
+extern str th_callid_prefix;
 
 extern str th_ip;
 extern str th_uparam_name;
@@ -208,8 +211,8 @@ int th_mask_callid(sip_msg_t *msg)
 		return -1;
 	}
 				
-	out.s = th_mask_encode(msg->callid->body.s, msg->callid->body.len, 0,
-						&out.len);
+	out.s = th_mask_encode(msg->callid->body.s, msg->callid->body.len,
+				&th_callid_prefix, &out.len);
 	if(out.s==NULL)
 	{
 		LM_ERR("cannot encode callid\n");
@@ -444,8 +447,8 @@ int th_unmask_callid(sip_msg_t *msg)
 		return -1;
 	}
 				
-	out.s = th_mask_decode(msg->callid->body.s, msg->callid->body.len, 0, 0,
-						&out.len);
+	out.s = th_mask_decode(msg->callid->body.s, msg->callid->body.len,
+					&th_callid_prefix, 0, &out.len);
 	if(out.s==NULL)
 	{
 		LM_ERR("cannot decode callid\n");
@@ -667,6 +670,131 @@ int th_unmask_ruri(sip_msg_t *msg)
 	return 0;
 }
 
+int th_unmask_refer_to(sip_msg_t *msg)
+{
+	str eval;
+	str *uri;
+	int ulen;
+	struct lump* l;
+	str out;
+
+	if(!((get_cseq(msg)->method_id)&(METHOD_REFER)))
+		return 0;
+
+	if(parse_refer_to_header(msg)==-1)
+	{
+		LM_DBG("no Refer-To header\n");
+		return 0;
+	}
+	if(msg->refer_to==NULL || get_refer_to(msg)==NULL)
+	{
+		LM_DBG("Refer-To header not found\n");
+		return 0;
+	}
+
+	uri = &(get_refer_to(msg)->uri);
+	if(th_get_uri_param_value(uri, &th_uparam_name, &eval)<0
+			|| eval.len<=0)
+		return -1;
+
+	out.s = th_mask_decode(eval.s, eval.len,
+				&th_uparam_prefix, 0, &out.len);
+	if(out.s==NULL)
+	{
+		LM_ERR("cannot decode r-uri\n");
+		return -1;
+	}
+
+	LM_DBG("+decoded: %d: [%.*s]\n", out.len, out.len, out.s);
+	for(ulen=0; ulen<uri->len; ulen++)
+	{
+		if(uri->s[ulen]=='?')
+			break;
+	}
+
+	l=del_lump(msg, uri->s-msg->buf, ulen, 0);
+	if (l==0)
+	{
+		LM_ERR("failed deleting r-uri\n");
+		pkg_free(out.s);
+		return -1;
+	}
+	if (insert_new_lump_after(l, out.s, out.len, 0)==0)
+	{
+		LM_ERR("could not insert new lump\n");
+		pkg_free(out.s);
+		return -1;
+	}
+
+	return 0;
+}
+
+int th_update_hdr_replaces(sip_msg_t *msg)
+{
+	struct hdr_field *hf = NULL;
+	str replaces;
+	str rcallid;
+	struct lump* l;
+	str out;
+
+	LM_DBG("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n");
+	if(th_param_mask_callid==0)
+		return 0;
+
+	if(!((get_cseq(msg)->method_id)&(METHOD_INVITE)))
+		return 0;
+
+	for (hf=msg->headers; hf; hf=hf->next)
+	{
+		if (hf->name.len==8 && strncasecmp(hf->name.s, "Replaces", 8)==0)
+			break;
+	}
+
+	if(hf==NULL)
+		return 0;
+
+	replaces = hf->body;
+	trim(&replaces);
+	rcallid.s = replaces.s;
+	for(rcallid.len=0; rcallid.len<replaces.len; rcallid.len++)
+	{
+		if(rcallid.s[rcallid.len]==';')
+			break;
+	}
+
+	if(rcallid.len>th_callid_prefix.len
+			&& strncmp(rcallid.s, th_callid_prefix.s, th_callid_prefix.len)==0)
+	{
+		/* value encoded - decode it */
+		out.s = th_mask_decode(rcallid.s, rcallid.len,
+					&th_callid_prefix, 0, &out.len);
+	} else {
+		/* value decoded - encode it */
+		out.s = th_mask_encode(rcallid.s, rcallid.len,
+				&th_callid_prefix, &out.len);
+	}
+	if(out.s==NULL)
+	{
+		LM_ERR("cannot update Replaces callid\n");
+		return -1;
+	}
+
+	l=del_lump(msg, rcallid.s-msg->buf, rcallid.len, 0);
+	if (l==0)
+	{
+		LM_ERR("failed deleting Replaces callid\n");
+		pkg_free(out.s);
+		return -1;
+	}
+	if (insert_new_lump_after(l, out.s, out.len, 0)==0) {
+		LM_ERR("could not insert new lump\n");
+		pkg_free(out.s);
+		return -1;
+	}
+
+	return 0;
+}
+
 char* th_msg_update(sip_msg_t *msg, unsigned int *olen)
 {
 	struct dest_info dst;

+ 2 - 0
modules/topoh/th_msg.h

@@ -32,6 +32,8 @@ int th_unmask_callid(sip_msg_t *msg);
 int th_flip_record_route(sip_msg_t *msg, int mode);
 int th_unmask_ruri(sip_msg_t *msg);
 int th_unmask_route(sip_msg_t *msg);
+int th_unmask_refer_to(sip_msg_t *msg);
+int th_update_hdr_replaces(sip_msg_t *msg);
 char* th_msg_update(sip_msg_t *msg, unsigned int *olen);
 int th_add_via_cookie(sip_msg_t *msg, struct via_body *via);
 int th_add_hdr_cookie(sip_msg_t *msg);

+ 7 - 1
modules/topoh/topoh_mod.c

@@ -41,12 +41,13 @@ MODULE_VERSION
 str _th_key = { "aL9.n8~Hm]Z", 0 };
 str th_cookie_name = {"TH", 0};
 str th_cookie_value = {0, 0};
-str th_ip = {"10.1.1.2", 0};
+str th_ip = {"10.1.1.10", 0};
 str th_uparam_name = {"line", 0};
 str th_uparam_prefix = {"sr-", 0};
 str th_vparam_name = {"branch", 0};
 str th_vparam_prefix = {"z9hG4bKsr-", 0};
 
+str th_callid_prefix = {"!!:", 3};
 str th_via_prefix = {0, 0};
 str th_uri_prefix = {0, 0};
 
@@ -60,11 +61,13 @@ static int mod_init(void);
 
 static param_export_t params[]={
 	{"mask_key",		STR_PARAM, &_th_key.s},
+	{"mask_ip",			STR_PARAM, &th_ip.s},
 	{"mask_callid",		INT_PARAM, &th_param_mask_callid},
 	{"uparam_name",		STR_PARAM, &th_uparam_name.s},
 	{"uparam_prefix",	STR_PARAM, &th_uparam_prefix.s},
 	{"vparam_name",		STR_PARAM, &th_vparam_name.s},
 	{"vparam_prefix",	STR_PARAM, &th_vparam_prefix.s},
+	{"callid_prefix",	STR_PARAM, &th_callid_prefix.s},
 	{0,0,0}
 };
 
@@ -96,6 +99,7 @@ static int mod_init(void)
 	th_uparam_prefix.len = strlen(th_uparam_prefix.s);
 	th_vparam_name.len = strlen(th_vparam_name.s);
 	th_vparam_prefix.len = strlen(th_vparam_prefix.s);
+	th_callid_prefix.len = strlen(th_callid_prefix.s);
 
 	/* 'SIP/2.0/UDP ' + ip + ';' + param + '=' + prefix (+ '\0') */
 	th_via_prefix.len = 12 + th_ip.len + 1 + th_vparam_name.len + 1
@@ -204,6 +208,7 @@ int th_msg_received(void *data)
 			/* dialog request */
 			th_unmask_ruri(&msg);
 			th_unmask_route(&msg);
+			th_unmask_refer_to(&msg);
 			if(direction==1)
 			{
 				th_unmask_callid(&msg);
@@ -296,6 +301,7 @@ int th_msg_sent(void *data)
 			}
 		} else {
 			/* initial request */
+			th_update_hdr_replaces(&msg);
 			th_mask_callid(&msg);
 		}
 	} else {

+ 10 - 0
modules_k/db_oracle/Makefile

@@ -66,3 +66,13 @@ DEFS+=-DOPENSER_MOD_INTERFACE
 SERLIBPATH=../../lib
 SER_LIBS+=$(SERLIBPATH)/srdb1/srdb1
 include ../../Makefile.modules
+
+ifeq ($(INSTALL_FLAVOUR),kamailio)
+# extra install for kamailio
+
+install-oracle-scripts: $(bin_prefix)/$(bin_dir)
+		ORACLEON=yes make -C ../../utils/kamctl/ install-modules
+
+install-scripts: install-oracle-scripts
+
+endif # INSTALL_FLAVOUR

+ 1 - 1
modules_k/db_oracle/asynch.c

@@ -66,7 +66,7 @@ static int set_tv(unsigned type, const char* val, struct timeval* tv)
 	unsigned long s, ms;
 	double dv;
 
-	if (type != STR_PARAM) {
+	if (PARAM_TYPE_MASK(type) != STR_PARAM) {
 		LM_ERR("type of parameter is no STR\n");
 		return -1;
 	}

+ 10 - 0
modules_k/db_text/Makefile

@@ -19,3 +19,13 @@ SERLIBPATH=../../lib
 SER_LIBS+=$(SERLIBPATH)/srdb1/srdb1
 SER_LIBS+=$(SERLIBPATH)/kcore/kcore
 include ../../Makefile.modules
+
+ifeq ($(INSTALL_FLAVOUR),kamailio)
+# extra install for kamailio
+
+install-dbtext-scripts: $(bin_prefix)/$(bin_dir)
+		DBTEXTON=yes make -C ../../utils/kamctl/ install-modules
+
+install-scripts: install-dbtext-scripts
+
+endif # INSTALL_FLAVOUR

+ 15 - 0
modules_k/dialog/dialog.c

@@ -89,6 +89,9 @@ static int db_fetch_rows = 200;
 
 str dlg_bridge_controller = {"sip:[email protected]", 27};
 
+str ruri_pvar_param = {"$ru", 3};
+pv_elem_t * ruri_param_model = NULL;
+
 /* statistic variables */
 int dlg_enable_stats = 1;
 int active_dlgs_cnt = 0;
@@ -204,6 +207,7 @@ static param_export_t mod_params[]={
 	{ "profiles_with_value",   STR_PARAM, &profiles_wv_s            },
 	{ "profiles_no_value",     STR_PARAM, &profiles_nv_s            },
 	{ "bridge_controller",     STR_PARAM, &dlg_bridge_controller.s  },
+	{ "ruri_pvar",             STR_PARAM, &ruri_pvar_param.s        },
 	{ 0,0,0 }
 };
 
@@ -438,6 +442,17 @@ static int mod_init(void)
 		return -1;
 	}
 
+	if (ruri_pvar_param.s==NULL || *ruri_pvar_param.s=='\0') {
+		LM_ERR("invalid r-uri PV string\n");
+		return -1;
+	}
+	ruri_pvar_param.len = strlen(ruri_pvar_param.s);
+	if(pv_parse_format(&ruri_pvar_param, &ruri_param_model) < 0
+				|| ruri_param_model==NULL) {
+		LM_ERR("malformed r-uri PV string: %s\n", ruri_pvar_param.s);
+		return -1;
+	}
+
 	/* update the len of the extra headers */
 	if (dlg_extra_hdrs.s)
 		dlg_extra_hdrs.len = strlen(dlg_extra_hdrs.s);

+ 16 - 7
modules_k/dialog/dlg_db_handler.c

@@ -60,6 +60,7 @@ str to_sock_column			=	str_init(TO_SOCK_COL);
 str from_sock_column		=	str_init(FROM_SOCK_COL);
 str sflags_column			=	str_init(SFLAGS_COL);
 str toroute_column			=	str_init(TOROUTE_COL);
+str req_uri_column			=	str_init(REQ_URI_COL);
 str dialog_table_name		=	str_init(DIALOG_TABLE_NAME);
 int dlg_db_mode				=	DB_MODE_NONE;
 
@@ -196,7 +197,7 @@ static int select_entire_dialog_table(db1_res_t ** res, int fetch_num_rows)
 			&from_cseq_column,	&to_cseq_column,	&from_route_column,
 			&to_route_column, 	&from_contact_column, &to_contact_column,
 			&from_sock_column,	&to_sock_column,    &sflags_column,
-			&toroute_column };
+			&toroute_column,	&req_uri_column };
 
 	if(use_dialog_table() != 0){
 		return -1;
@@ -262,7 +263,7 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
 	db_row_t * rows;
 	int i, nr_rows;
 	struct dlg_cell *dlg;
-	str callid, from_uri, to_uri, from_tag, to_tag;
+	str callid, from_uri, to_uri, from_tag, to_tag, req_uri;
 	str cseq1, cseq2, contact1, contact2, rroute1, rroute2;
 	unsigned int next_id;
 	
@@ -302,8 +303,10 @@ static int load_dialog_info_from_db(int dlg_hash_size, int fetch_num_rows)
 			GET_STR_VALUE(from_uri, values, 3, 1, 0);
 			GET_STR_VALUE(from_tag, values, 4, 1, 0);
 			GET_STR_VALUE(to_uri, values, 5, 1, 0);
+			GET_STR_VALUE(req_uri, values, 20, 1, 0);
 
-			if((dlg=build_new_dlg(&callid, &from_uri, &to_uri, &from_tag))==0){
+			if((dlg=build_new_dlg(&callid, &from_uri, &to_uri, &from_tag,
+							&req_uri))==0){
 				LM_ERR("failed to build new dialog\n");
 				goto error;
 			}
@@ -453,7 +456,7 @@ int update_dialog_dbinfo(struct dlg_cell * cell)
 			&start_time_column,  &state_column,       &timeout_column,
 			&from_cseq_column,   &to_cseq_column,     &from_route_column,
 			&to_route_column,    &from_contact_column,&to_contact_column,
-			&sflags_column,      &toroute_column };
+			&sflags_column,      &toroute_column,     &req_uri_column };
 
 	if(use_dialog_table()!=0)
 		return -1;
@@ -467,7 +470,7 @@ int update_dialog_dbinfo(struct dlg_cell * cell)
 		VAL_TYPE(values+5) = VAL_TYPE(values+6) = VAL_TYPE(values+7) = 
 		VAL_TYPE(values+8) = VAL_TYPE(values+12) = VAL_TYPE(values+13) = 
 		VAL_TYPE(values+14) = VAL_TYPE(values+15) = VAL_TYPE(values+16)=
-		VAL_TYPE(values+17) = DB1_STR;
+		VAL_TYPE(values+17) = VAL_TYPE(values+20) = DB1_STR;
 
 		SET_NULL_FLAG(values, i, DIALOG_TABLE_COL_NO-6, 0);
 		VAL_TYPE(values+18) = VAL_TYPE(values+19) = DB1_INT;
@@ -513,6 +516,8 @@ int update_dialog_dbinfo(struct dlg_cell * cell)
 		VAL_INT(values+18)  = cell->sflags;
 		VAL_NULL(values+19) = 0;
 		VAL_INT(values+19)  = cell->toroute;
+		SET_STR_VALUE(values+20, cell->req_uri);
+		SET_PROPER_NULL_FLAG(cell->req_uri, 	values, 20);
 
 		if((dialog_dbf.insert(dialog_db_handle, insert_keys, values, 
 								DIALOG_TABLE_COL_NO)) !=0){
@@ -580,7 +585,7 @@ void dialog_update_db(unsigned int ticks, void * param)
 			&start_time_column,	&state_column,			&timeout_column,
 			&from_cseq_column,	&to_cseq_column,		&from_route_column,
 			&to_route_column, 	&from_contact_column, 	&to_contact_column,
-			&sflags_column,     &toroute_column };
+			&sflags_column,     &toroute_column, 		&req_uri_column };
 
 	if(use_dialog_table()!=0)
 		return;
@@ -593,7 +598,7 @@ void dialog_update_db(unsigned int ticks, void * param)
 	VAL_TYPE(values+5) = VAL_TYPE(values+6) = VAL_TYPE(values+7) = 
 	VAL_TYPE(values+8) = VAL_TYPE(values+12) = VAL_TYPE(values+13) = 
 	VAL_TYPE(values+14) = VAL_TYPE(values+15) = VAL_TYPE(values+16) = 
-	VAL_TYPE(values+17) = DB1_STR;
+	VAL_TYPE(values+17) = VAL_TYPE(values+20) = DB1_STR;
 
 	SET_NULL_FLAG(values, i, DIALOG_TABLE_COL_NO-6, 0);
 
@@ -651,6 +656,10 @@ void dialog_update_db(unsigned int ticks, void * param)
 				VAL_INT(values+18)		= cell->sflags;
 				VAL_INT(values+19)		= cell->toroute;
 
+				SET_STR_VALUE(values+20, cell->req_uri);
+				SET_PROPER_NULL_FLAG(cell->req_uri,
+					values, 20);
+
 				if((dialog_dbf.insert(dialog_db_handle, insert_keys, 
 				values, DIALOG_TABLE_COL_NO)) !=0){
 					LM_ERR("could not add another dialog to db\n");

+ 3 - 2
modules_k/dialog/dlg_db_handler.h

@@ -51,9 +51,10 @@
 #define TO_SOCK_COL				"callee_sock"
 #define SFLAGS_COL				"sflags"
 #define TOROUTE_COL				"toroute"
+#define REQ_URI_COL				"req_uri"
 #define DIALOG_TABLE_NAME		"dialog"
 
-#define DLG_TABLE_VERSION		3
+#define DLG_TABLE_VERSION		4
 
 /*every minute the dialogs' information will be refreshed*/
 #define DB_DEFAULT_UPDATE_PERIOD	60
@@ -62,7 +63,7 @@
 #define DB_MODE_DELAYED				2
 #define DB_MODE_SHUTDOWN			3
 
-#define DIALOG_TABLE_COL_NO 		20
+#define DIALOG_TABLE_COL_NO 		21
 
 
 extern str call_id_column; 

+ 9 - 1
modules_k/dialog/dlg_handlers.c

@@ -93,6 +93,7 @@ extern stat_var *processed_dlgs;	/*!< number of processed dialogs */
 extern stat_var *expired_dlgs;		/*!< number of expired dialogs */
 extern stat_var *failed_dlgs;		/*!< number of failed dialogs */
 
+extern pv_elem_t *ruri_param_model;	/*!< pv-string to get r-uri */
 
 static unsigned int CURR_DLG_LIFETIME = 0;	/*!< current dialog lifetime */
 static unsigned int CURR_DLG_STATUS = 0;	/*!< current dialog state */
@@ -533,6 +534,7 @@ int dlg_new_dialog(struct sip_msg *msg, struct cell *t)
 {
 	struct dlg_cell *dlg;
 	str s;
+	str req_uri;
 
 	if((msg->to==NULL && parse_headers(msg, HDR_TO_F,0)<0) || msg->to==NULL)
 	{
@@ -559,6 +561,12 @@ int dlg_new_dialog(struct sip_msg *msg, struct cell *t)
 	s = msg->callid->body;
 	trim(&s);
 
+	if (pv_printf_s(msg, ruri_param_model, &req_uri)<0) {
+		LM_ERR("error - cannot print the r-uri format\n");
+		return -1;
+	}
+	trim(&req_uri);
+
 	/* some sanity checks */
 	if (s.len==0 || get_from(msg)->tag_value.len==0) {
 		LM_ERR("invalid request -> callid (%d) or from TAG (%d) empty\n",
@@ -568,7 +576,7 @@ int dlg_new_dialog(struct sip_msg *msg, struct cell *t)
 
 	dlg = build_new_dlg(&s /*callid*/, &(get_from(msg)->uri) /*from uri*/,
 		&(get_to(msg)->uri) /*to uri*/,
-		&(get_from(msg)->tag_value)/*from_tag*/ );
+		&(get_from(msg)->tag_value)/*from_tag*/, &req_uri /*r-uri*/ );
 	if (dlg==0) {
 		LM_ERR("failed to create new dialog\n");
 		return -1;

+ 13 - 3
modules_k/dialog/dlg_hash.c

@@ -153,6 +153,9 @@ inline void destroy_dlg(struct dlg_cell *dlg)
 
 	run_dlg_callbacks( DLGCB_DESTROY , dlg, 0, DLG_DIR_NONE, 0);
 
+	if(dlg==get_current_dlg_pointer())
+		reset_current_dlg_pointer();
+
 	if (dlg->cbs.first)
 		destroy_dlg_callbacks_list(dlg->cbs.first);
 
@@ -172,6 +175,7 @@ inline void destroy_dlg(struct dlg_cell *dlg)
 		shm_free(dlg->cseq[DLG_CALLEE_LEG].s);
 
 	shm_free(dlg);
+	dlg = 0;
 }
 
 
@@ -214,17 +218,18 @@ void destroy_dlg_table(void)
  * \param from_uri dialog from uri
  * \param to_uri dialog to uri
  * \param from_tag dialog from tag
+ * \param req_uri dialog r-uri
  * \return created dialog structure on success, NULL otherwise
  */
 struct dlg_cell* build_new_dlg( str *callid, str *from_uri, str *to_uri,
-		str *from_tag)
+		str *from_tag, str *req_uri)
 {
 	struct dlg_cell *dlg;
 	int len;
 	char *p;
 
 	len = sizeof(struct dlg_cell) + callid->len + from_uri->len +
-		to_uri->len;
+		to_uri->len + req_uri->len;
 	dlg = (struct dlg_cell*)shm_malloc( len );
 	if (dlg==0) {
 		LM_ERR("no more shm mem (%d)\n",len);
@@ -252,7 +257,12 @@ struct dlg_cell* build_new_dlg( str *callid, str *from_uri, str *to_uri,
 	dlg->to_uri.s = p;
 	dlg->to_uri.len = to_uri->len;
 	memcpy( p, to_uri->s, to_uri->len);
-	p += to_uri->len;
+	p += to_uri->len; 
+
+	dlg->req_uri.s = p;
+	dlg->req_uri.len = req_uri->len;
+	memcpy( p, req_uri->s, req_uri->len);
+	p += req_uri->len;
 
 	if ( p!=(((char*)dlg)+len) ) {
 		LM_CRIT("buffer overflow\n");

+ 3 - 1
modules_k/dialog/dlg_hash.h

@@ -103,6 +103,7 @@ struct dlg_cell
 	str                  callid;		/*!< callid from SIP message */
 	str                  from_uri;		/*!< from uri from SIP message */
 	str                  to_uri;		/*!< to uri from SIP message */
+	str                  req_uri;		/*!< r-uri from SIP message */
 	str                  tag[2];		/*!< from tags of caller and to tag of callee */
 	str                  cseq[2];		/*!< CSEQ of caller and callee */
 	str                  route_set[2];	/*!< route set of caller and callee */
@@ -207,10 +208,11 @@ void destroy_dlg_table(void);
  * \param from_uri dialog from uri
  * \param to_uri dialog to uri
  * \param from_tag dialog from tag
+ * \param req_uri dialog r-uri
  * \return created dialog structure on success, NULL otherwise
  */
 struct dlg_cell* build_new_dlg(str *callid, str *from_uri,
-		str *to_uri, str *from_tag);
+		str *to_uri, str *from_tag, str *req_uri);
 
 
 /*!

+ 10 - 0
modules_k/dialog/dlg_profile.c

@@ -69,6 +69,16 @@ static struct dlg_profile_table* new_dlg_profile( str *name,
 		unsigned int size, unsigned int has_value);
 
 
+struct dlg_cell *get_current_dlg_pointer(void)
+{
+	return current_dlg_pointer;
+}
+
+void reset_current_dlg_pointer(void)
+{
+	current_dlg_pointer = NULL;
+}
+
 /*!
  * \brief Add profile definitions to the global list
  * \see new_dlg_profile

+ 4 - 0
modules_k/dialog/dlg_profile.h

@@ -79,6 +79,10 @@ struct dlg_profile_table {
 };
 
 
+struct dlg_cell *get_current_dlg_pointer(void);
+
+void reset_current_dlg_pointer(void);
+
 /*!
  * \brief Add profile definitions to the global list
  * \see new_dlg_profile

+ 4 - 3
modules_k/dialog/dlg_transfer.c

@@ -241,7 +241,8 @@ void dlg_bridge_tm_callback(struct cell *t, int type, struct tmcb_params *ps)
 
 	dlg = build_new_dlg(&s /*callid*/, &(get_from(msg)->uri) /*from uri*/,
 		&(get_to(msg)->uri) /*to uri*/,
-		&(get_from(msg)->tag_value)/*from_tag*/ );
+		&(get_from(msg)->tag_value)/*from_tag*/,
+		&(get_to(msg)->uri) /*use to as r-uri*/ );
 	if (dlg==0) {
 		LM_ERR("failed to create new dialog\n");
 		goto error;
@@ -383,11 +384,11 @@ int dlg_transfer(struct dlg_cell *dlg, str *to, int side)
 	if(side==DLG_CALLER_LEG)
 		ndlg = build_new_dlg(&dlg->callid /*callid*/,
 				&dlg->to_uri /*from uri*/, &dlg->from_uri /*to uri*/,
-				&dlg->tag[side]/*from_tag*/ );
+				&dlg->tag[side]/*from_tag*/, &dlg->req_uri /*req uri */ );
 	else
 		ndlg = build_new_dlg(&dlg->callid /*callid*/,
 				&dlg->from_uri /*from uri*/, &dlg->to_uri /*to uri*/,
-				&dlg->tag[side]/*from_tag*/ );
+				&dlg->tag[side]/*from_tag*/, &dlg->req_uri /*req uri */ );
 	if (ndlg==0) {
 		LM_ERR("failed to create new dialog\n");
 		goto error;

+ 68 - 92
modules_k/drouting/README

@@ -9,7 +9,7 @@ Anca-Maria Vamanu
    Copyright © 2005-2008 voice-system.ro
    Revision History
    Revision $Revision: 4473 $ $Date: 2008-07-12 00:16:22 +0300 (Sat, 12
-                              Jul 2008) $
+   Jul 2008) $
      __________________________________________________________________
 
    Table of Contents
@@ -44,13 +44,12 @@ Anca-Maria Vamanu
               3.6. sort_order (int)
               3.7. ruri_avp (str)
               3.8. attrs_avp (str)
-              3.9. define_blacklist (str)
-              3.10. use_domain (int)
-              3.11. drg_user_col (str)
-              3.12. drg_domain_col (str)
-              3.13. drg_grpid_col (str)
-              3.14. fetch_rows (int)
-              3.15. force_dns (int)
+              3.9. use_domain (int)
+              3.10. drg_user_col (str)
+              3.11. drg_domain_col (str)
+              3.12. drg_grpid_col (str)
+              3.13. fetch_rows (int)
+              3.14. force_dns (int)
 
         4. Exported Functions
 
@@ -86,18 +85,17 @@ Anca-Maria Vamanu
    1.6. Set sort_order parameter
    1.7. Set ruri_avp parameter
    1.8. Set attrs_avp parameter
-   1.9. Set define_blacklist parameter
-   1.10. Set use_domain parameter
-   1.11. Set drg_user_col parameter
-   1.12. Set drg_domain_col parameter
-   1.13. Set drg_grpid_col parameter
-   1.14. Set fetch_rows parameter
-   1.15. Set force_dns parameter
-   1.16. do_routing usage
-   1.17. use_next_gw usage
-   1.18. goes_to_gw usage
+   1.9. Set use_domain parameter
+   1.10. Set drg_user_col parameter
+   1.11. Set drg_domain_col parameter
+   1.12. Set drg_grpid_col parameter
+   1.13. Set fetch_rows parameter
+   1.14. Set force_dns parameter
+   1.15. do_routing usage
+   1.16. use_next_gw usage
+   1.17. goes_to_gw usage
+   1.18. is_from_gw usage
    1.19. is_from_gw usage
-   1.20. is_from_gw usage
 
 Chapter 1. Admin Guide
 
@@ -131,13 +129,12 @@ Chapter 1. Admin Guide
         3.6. sort_order (int)
         3.7. ruri_avp (str)
         3.8. attrs_avp (str)
-        3.9. define_blacklist (str)
-        3.10. use_domain (int)
-        3.11. drg_user_col (str)
-        3.12. drg_domain_col (str)
-        3.13. drg_grpid_col (str)
-        3.14. fetch_rows (int)
-        3.15. force_dns (int)
+        3.9. use_domain (int)
+        3.10. drg_user_col (str)
+        3.11. drg_domain_col (str)
+        3.12. drg_grpid_col (str)
+        3.13. fetch_rows (int)
+        3.14. force_dns (int)
 
    4. Exported Functions
 
@@ -204,10 +201,6 @@ Chapter 1. Admin Guide
        scripting route triggering when rules are matched
      * bidirectional behavior - inbound and outbound processing (strip and
        prefixing when sending and receiving from a destination/GW)
-     * blacklisting - the module allows definition of backlists based on
-       the destination IPs. This blacklists are to be used to prevent
-       malicious forwarding to GWs (based on DNS lookups) when the script
-       logic does none-GE forwarding (like foreign domains).
 
 1.3. Performance
 
@@ -310,18 +303,18 @@ Chapter 1. Admin Guide
        draft 09):
        Table 1.4. Time recurrence attributes
 
-     Attribute                            Description
-     dastard    Start of interval (RFC 2445 DATE-TIME)
-     duration   Length of interval (RFC 2445 DURATION)
-     freq       Frequency of recurrence (secondly,minutely,hourly, daily,weekly,
-                monthly, or yearly).
-     until      bound of recurrence (RFC 2445 DATE-TIME)
-     interval   How often the recurrence repeats
-     byday      List of days of the week
-     bymonthday List of days of the month
-     byyearday  List of days of the year
-     byweekno   List of weeks of the year
-     bymonth    List of months of the year
+   Attribute Description
+   dastard Start of interval (RFC 2445 DATE-TIME)
+   duration Length of interval (RFC 2445 DURATION)
+   freq Frequency of recurrence (secondly,minutely,hourly, daily,weekly,
+   monthly, or yearly).
+   until bound of recurrence (RFC 2445 DATE-TIME)
+   interval How often the recurrence repeats
+   byday List of days of the week
+   bymonthday List of days of the month
+   byyearday List of days of the year
+   byweekno List of weeks of the year
+   bymonth List of months of the year
        The value stored in database has the format of:
        <dtstart>|<duration>|<freq>|<until>|<interval>|<byday>|<bymonthday>
        |<byyearday>|<byweekno>|<bymonth>
@@ -494,13 +487,12 @@ Chapter 1. Admin Guide
    3.6. sort_order (int)
    3.7. ruri_avp (str)
    3.8. attrs_avp (str)
-   3.9. define_blacklist (str)
-   3.10. use_domain (int)
-   3.11. drg_user_col (str)
-   3.12. drg_domain_col (str)
-   3.13. drg_grpid_col (str)
-   3.14. fetch_rows (int)
-   3.15. force_dns (int)
+   3.9. use_domain (int)
+   3.10. drg_user_col (str)
+   3.11. drg_domain_col (str)
+   3.12. drg_grpid_col (str)
+   3.13. fetch_rows (int)
+   3.14. force_dns (int)
 
 3.1. db_url(str)
 
@@ -511,7 +503,7 @@ Chapter 1. Admin Guide
    Example 1.1. Set db_url parameter
 ...
 modparam("drouting", "db_url",
-        "mysql://opensips:opensipsrw@localhost/opensips")
+        "mysql://openser:openserrw@localhost/openser")
 ...
 
 3.2. drd_table(str)
@@ -614,79 +606,64 @@ modparam("drouting", "attrs_avp", '$avp(dr_attrs)')
 modparam("drouting", "atrrs_avp", '$avp(i:67)')
 ...
 
-3.9. define_blacklist (str)
-
-   Defines a backlist based on a list of GW types - the list will contain
-   the IPs (no port, all protocols) of the GWs with the specified types.
-
-   Multiple instances of this param are allowed.
-
-   Default value is "NULL".
-
-   Example 1.9. Set define_blacklist parameter
-...
-modparam("drouting", "define_blacklist", 'bl_name= 3,5,25,23')
-modparam("drouting", "define_blacklist", 'list= 4,2')
-...
-
-3.10. use_domain (int)
+3.9. use_domain (int)
 
    Flag to configure whether to use domain match when querying database
    for user's routing group.
 
    Default value is "1".
 
-   Example 1.10. Set use_domain parameter
+   Example 1.9. Set use_domain parameter
 ...
 modparam("drouting", "use_domain", 0)
 ...
 
-3.11. drg_user_col (str)
+3.10. drg_user_col (str)
 
    The name of the column in group db table where the username is stored.
 
    Default value is "username".
 
-   Example 1.11. Set drg_user_col parameter
+   Example 1.10. Set drg_user_col parameter
 ...
 modparam("drouting", "drg_user_col", "user")
 ...
 
-3.12. drg_domain_col (str)
+3.11. drg_domain_col (str)
 
    The name of the column in group db table where the domain is stored.
 
    Default value is "domain".
 
-   Example 1.12. Set drg_domain_col parameter
+   Example 1.11. Set drg_domain_col parameter
 ...
 modparam("drouting", "drg_domain_col", "host")
 ...
 
-3.13. drg_grpid_col (str)
+3.12. drg_grpid_col (str)
 
    The name of the column in group db table where the group id is stored.
 
    Default value is "groupid".
 
-   Example 1.13. Set drg_grpid_col parameter
+   Example 1.12. Set drg_grpid_col parameter
 ...
 modparam("drouting", "drg_grpid_col", "grpid")
 ...
 
-3.14. fetch_rows (int)
+3.13. fetch_rows (int)
 
    The number of rows that should be fetched from the result of a query in
    rules db table.
 
    Default value is "2000".
 
-   Example 1.14. Set fetch_rows parameter
+   Example 1.13. Set fetch_rows parameter
 ...
 modparam("drouting", "fetch_rows", 1500)
 ...
 
-3.15. force_dns (int)
+3.14. force_dns (int)
 
    Force DNS resolving of GW/destination names (if not IPs) during
    startup. If not enabled, the GW name will be blindly used during
@@ -694,7 +671,7 @@ modparam("drouting", "fetch_rows", 1500)
 
    Default value is "1 (enabled)".
 
-   Example 1.15. Set force_dns parameter
+   Example 1.14. Set force_dns parameter
 ...
 modparam("drouting", "force_dns", 0)
 ...
@@ -707,7 +684,7 @@ modparam("drouting", "force_dns", 0)
    4.4. is_from_gw([type])
    4.5. is_from_gw( type, [flag])
 
-4.1.  do_routing("[groupID]")
+4.1. do_routing("[groupID]")
 
    Function to trigger routing of the message according to the rules in
    the database table and the configured parameters.
@@ -719,7 +696,7 @@ modparam("drouting", "force_dns", 0)
    specification. If none specified, the function will automatically try
    to query the dr_group table to get this information.
 
-   Example 1.16. do_routing usage
+   Example 1.15. do_routing usage
 ...
 do_routing();
 ...
@@ -727,7 +704,7 @@ do_routing("0");
 ...
 do_routing("$avp(i:10)");
 
-4.2.  use_next_gw()/next_routing()
+4.2. use_next_gw()/next_routing()
 
    The function takes the next available destination (set by do_routing,
    as alternative destinations) and push it into RURI. Note that the
@@ -742,7 +719,7 @@ do_routing("$avp(i:10)");
    is no other alternative destinations are found or in case of internal
    processing error.
 
-   Example 1.17. use_next_gw usage
+   Example 1.16. use_next_gw usage
 ...
 if (use_next_gw()) {
         t_relay();
@@ -750,7 +727,7 @@ if (use_next_gw()) {
 }
 ...
 
-4.3.  goes_to_gw([type])
+4.3. goes_to_gw([type])
 
    Function returns true if the destination of the current request
    (destination URI or Request URI) points (as IP) to one of the gateways.
@@ -763,7 +740,7 @@ if (use_next_gw()) {
    The function can take one optional parameter:
      * type (optional) - GW/destination type to be checked
 
-   Example 1.18. goes_to_gw usage
+   Example 1.17. goes_to_gw usage
 ...
 if (goes_to_gw("1")) {
         sl_send_reply("403","Forbidden");
@@ -771,7 +748,7 @@ if (goes_to_gw("1")) {
 }
 ...
 
-4.4.  is_from_gw([type])
+4.4. is_from_gw([type])
 
    The function checks if the sender of the message is a gateway from a
    certain group.
@@ -784,13 +761,13 @@ if (goes_to_gw("1")) {
      * flags - if message is a request and the GW has a STRIP defined,
        then apply it if GW is source.
 
-   Example 1.19. is_from_gw usage
+   Example 1.18. is_from_gw usage
 ...
 if (is_from_gw("1") {
 }
 ...
 
-4.5.  is_from_gw( type, [flag])
+4.5. is_from_gw( type, [flag])
 
    The function checks if the sender of the message is a gateway from a
    certain group.
@@ -802,7 +779,7 @@ if (is_from_gw("1") {
      * flags (optional) - if message is a request and the GW has a STRIP
        defined, then apply it if GW is source.
 
-   Example 1.20. is_from_gw usage
+   Example 1.19. is_from_gw usage
 ...
 if (is_from_gw("3","1") {
 }
@@ -812,7 +789,7 @@ if (is_from_gw("3","1") {
 
    5.1. dr_reload
 
-5.1.  dr_reload
+5.1. dr_reload
 
    Command to reload routing rules from database.
 
@@ -824,11 +801,10 @@ if (is_from_gw("3","1") {
 
 6. Installation
 
-   The module requires 3 table in OpenSIPS database: dr_groups,
+   The module requires 3 table in Kamailio database: dr_groups,
    dr_gateways, dr_rules. The SQL syntax to create them can be found in
-   drouting-create.sql script in the database directories in the
-   opensips/scripts folder. You can also find the complete database
-   documentation on the project webpage,
+   drouting-create.sql script in kamctl db directories. You can also find
+   the complete database documentation on the project webpage,
    http://www.kamailio.org/docs/db-tables/kamailio-db-devel.html.
 
 Chapter 2. Developer Guide

+ 4 - 4
modules_k/drouting/doc/drouting_admin.xml

@@ -823,7 +823,7 @@
 		<programlisting format="linespecific">
 ...
 modparam("drouting", "db_url", 
-	"mysql://opensips:opensipsrw@localhost/opensips")
+	"mysql://openser:openserrw@localhost/openser")
 ...
 </programlisting>
 		</example>
@@ -1319,10 +1319,10 @@ if (is_from_gw("3","1") {
 <section>
 	<title>Installation</title>
 	<para>
-	The module requires 3 table in OpenSIPS database: dr_groups,
+	The module requires 3 table in &kamailio; database: dr_groups,
 	dr_gateways, dr_rules. The SQL syntax to create them can be
-	found in drouting-create.sql script in the database directories
-	in the opensips/scripts folder. You can also find the complete
+	found in drouting-create.sql script in kamctl db directories.
+	You can also find the complete
 	database documentation on the project webpage, &kamailiodbdocslink;.
 	</para>
 </section>

+ 21 - 9
modules_k/drouting/dr_load.c

@@ -34,6 +34,7 @@
 
 
 #include "../../dprint.h"
+#include "../../route.h"
 //#include "../../db/db.h"
 #include "../../mem/shm_mem.h"
 
@@ -280,7 +281,7 @@ rt_data_t* dr_load_routing_info( db_func_t *dr_dbf, db1_con_t* db_hdl,
 							str *drd_table, str *drl_table, str* drr_table )
 {
 	int    int_vals[4];
-	char * str_vals[4];
+	char * str_vals[5];
 	str tmp;
 	db_key_t columns[7];
 	db1_res_t* res;
@@ -509,31 +510,41 @@ rt_data_t* dr_load_routing_info( db_func_t *dr_dbf, db1_con_t* db_hdl,
 			check_val( ROW_VALUES(row)+4, DB1_INT, 1, 0);
 			int_vals[2] = VAL_INT   (ROW_VALUES(row)+4);
 			/* ROUTE_ID column */
-			check_val( ROW_VALUES(row)+5, DB1_INT, 1, 0);
-			int_vals[3] = VAL_INT   (ROW_VALUES(row)+5);
+			check_val( ROW_VALUES(row)+5, DB1_STRING, 1, 0);
+			str_vals[3] = (char*)VAL_STRING(ROW_VALUES(row)+5);
 			/* DSTLIST column */
 			check_val( ROW_VALUES(row)+6, DB1_STRING, 1, 1);
-			str_vals[3] = (char*)VAL_STRING(ROW_VALUES(row)+6);
+			str_vals[4] = (char*)VAL_STRING(ROW_VALUES(row)+6);
 			/* parse the time definition */
 			if ((time_rec=parse_time_def(str_vals[2]))==0) {
 				LM_ERR("bad time definition <%s> for rule id %d -> skipping\n",
 					str_vals[2], int_vals[0]);
 				continue;
 			}
+			/* lookup for the script route ID */
+			if (str_vals[3][0] && str_vals[3][0]!='0') {
+				int_vals[3] =  route_lookup(&main_rt, str_vals[3]);
+				if (int_vals[3]==-1) {
+					LM_WARN("route <%s> does not exist\n",str_vals[3]);
+					int_vals[3] = 0;
+				}
+			} else {
+				int_vals[3] = 0;
+			}
 			/* is gw_list a list or a list id? */
-			if (str_vals[3][0]=='#') {
-				s_id.s = str_vals[3]+1;
+			if (str_vals[4][0]=='#') {
+				s_id.s = str_vals[4]+1;
 				s_id.len = strlen(s_id.s);
 				if ( str2int( &s_id, &id)!=0 ||
-				(str_vals[3]=get_tmp_gw_list(id))==NULL ) {
+				(str_vals[4]=get_tmp_gw_list(id))==NULL ) {
 					LM_ERR("invalid reference to a GW list <%s> -> skipping\n",
-						str_vals[3]);
+						str_vals[4]);
 					continue;
 				}
 			}
 			/* build the routing rule */
 			if ((ri = build_rt_info( int_vals[2], time_rec, int_vals[3],
-					str_vals[3], rdata->pgw_l))== 0 ) {
+					str_vals[4], rdata->pgw_l))== 0 ) {
 				LM_ERR("failed to add routing info for rule id %d -> "
 					"skipping\n", int_vals[0]);
 				tmrec_free( time_rec );
@@ -573,5 +584,6 @@ error:
 		dr_dbf->free_result(db_hdl, res);
 	if (rdata)
 		free_rt_data( rdata, 1 );
+	rdata = NULL;
 	return 0;
 }

+ 101 - 0
modules_k/htable/htable.c

@@ -33,6 +33,8 @@
 #include "../../route.h"
 #include "../../dprint.h"
 #include "../../ut.h"
+#include "../../rpc.h"
+#include "../../rpc_lookup.h"
 #include "../../lib/kmi/mi.h"
 #include "../../lib/kcore/faked_msg.h"
 
@@ -46,6 +48,8 @@ MODULE_VERSION
 
 int  ht_timer_interval = 20;
 
+static int htable_init_rpc(void);
+
 /** module functions */
 static int ht_print(struct sip_msg*, char*, char*);
 static int mod_init(void);
@@ -134,6 +138,11 @@ static int mod_init(void)
 		LM_ERR("failed to register MI commands\n");
 		return -1;
 	}
+	if(htable_init_rpc()!=0)
+	{
+		LM_ERR("failed to register RPC commands\n");
+		return -1;
+	}
 
 	if(ht_shm_init()!=0)
 		return -1;
@@ -444,3 +453,95 @@ error:
 	return 0;
 }
 
+static const char* htable_dump_doc[2] = {
+	"Dump the contents of hash table.",
+	0
+};
+
+static void  htable_rpc_dump(rpc_t* rpc, void* c)
+{
+	str htname;
+	ht_t *ht;
+	ht_cell_t *it;
+	int i;
+	void* th;
+	void* ih;
+	void* vh;
+
+	if (rpc->scan(c, "S", &htname) < 1)
+	{
+		rpc->fault(c, 500, "No htable name given");
+		return;
+	}
+	ht = ht_get_table(&htname);
+	if(ht==NULL)
+	{
+		rpc->fault(c, 500, "No such htable");
+		return;
+	}
+	for(i=0; i<ht->htsize; i++)
+	{
+		lock_get(&ht->entries[i].lock);
+		it = ht->entries[i].first;
+		if(it)
+		{
+			/* add entry node */
+			if (rpc->add(c, "{", &th) < 0)
+			{
+				rpc->fault(c, 500, "Internal error creating rpc");
+				return;
+			}
+			if(rpc->struct_add(th, "dd{",
+							"entry", i,
+							"size",  (int)ht->entries[i].esize,
+							"slot",  &ih)<0)
+			{
+				rpc->fault(c, 500, "Internal error creating rpc");
+				return;
+			}
+			while(it)
+			{
+				if(rpc->struct_add(ih, "{",
+							"item", &vh)<0)
+				{
+					rpc->fault(c, 500, "Internal error creating rpc");
+					return;
+				}
+				if(it->flags&AVP_VAL_STR) {
+					if(rpc->struct_add(vh, "SS",
+							"name",  &it->name.s,
+							"value", &it->value.s)<0)
+					{
+						rpc->fault(c, 500, "Internal error adding item");
+						return;
+					}
+				} else {
+					if(rpc->struct_add(vh, "Sd",
+							"name",  &it->name.s,
+							"value", (int)it->value.n))
+					{
+						rpc->fault(c, 500, "Internal error adding item");
+						return;
+					}
+				}
+				it = it->next;
+			}
+		}
+		lock_release(&ht->entries[i].lock);
+	}
+}
+
+rpc_export_t htable_rpc[] = {
+	{"htable.dump", htable_rpc_dump, htable_dump_doc, 0},
+	{0, 0, 0, 0}
+};
+
+static int htable_init_rpc(void)
+{
+	if (rpc_register_array(htable_rpc)!=0)
+	{
+		LM_ERR("failed to register RPC commands\n");
+		return -1;
+	}
+	return 0;
+}

+ 3 - 0
modules_k/nat_traversal/Makefile

@@ -12,5 +12,8 @@ LIBS=
 
 DEFS+=-DOPENSER_MOD_INTERFACE
 
+SERLIBPATH=../../lib
+SER_LIBS+=$(SERLIBPATH)/kcore/kcore
+
 include ../../Makefile.modules
 

+ 1 - 0
modules_k/nat_traversal/nat_traversal.c

@@ -49,6 +49,7 @@
 #include "../../parser/parse_uri.h"
 #include "../../parser/parse_expires.h"
 #include "../../parser/contact/parse_contact.h"
+#include "../../lib/kcore/statistics.h"
 #include "../dialog/dlg_load.h"
 #include "../../modules/tm/tm_load.h"
 #include "../sl/sl_cb.h"

+ 4 - 2
modules_k/nathelper/nathelper.c

@@ -2985,12 +2985,14 @@ force_rtp_proxy(struct sip_msg* msg, char* str1, char* str2, int offer)
 			FORCE_RTP_PROXY_RET (-1);
 		}
 		create = 0;
-		if (swap != 0 || (msg->first_line.type == SIP_REPLY && offer != 0)) {
+		if (swap != 0 || (msg->first_line.type == SIP_REPLY && offer != 0)
+				|| (msg->first_line.type == SIP_REQUEST && offer == 0)) {
 			tmp = from_tag;
 			from_tag = to_tag;
 			to_tag = tmp;
 		}
-	} else if (swap != 0 || (msg->first_line.type == SIP_REPLY && offer != 0)) {
+	} else if (swap != 0 || (msg->first_line.type == SIP_REPLY && offer != 0)
+			|| (msg->first_line.type == SIP_REQUEST && offer == 0)) {
 		if (to_tag.len == 0) {
 			FORCE_RTP_PROXY_RET (-1);
 		}

+ 2 - 1
modules_k/nathelper/nhelpr_funcs.c

@@ -406,7 +406,8 @@ get_contact_uri(struct sip_msg* _m, struct sip_uri *uri, contact_t** _c)
                 return -1;
 
         if (parse_uri((*_c)->uri.s, (*_c)->uri.len, uri) < 0 || uri->host.len <= 0) {
-                LM_ERR("failed to parse Contact URI\n");
+                LM_ERR("failed to parse Contact URI [%.*s]\n",
+                        (*_c)->uri.len, ((*_c)->uri.s)?(*_c)->uri.s:"");
                 return -1;
         }
         return 0;

+ 4 - 2
modules_k/perl/Makefile

@@ -52,8 +52,8 @@ perlpod: doc/perl_pod.sgml
 doc/perl_pod.sgml: openserxs.xs
 	cat $(PODFILES) | pod2docbook --doctype=chapter --title='OpenSER Perl API' --no-header - doc/perl_pod.sgml
 
-install_module_custom:
-	echo "installing Perl OpenSER packages ..."
+install-perl-scripts:
+	echo "installing Perl Kamailio (OpenSER) packages ..."
 	mkdir -p $(modules_prefix)/$(lib_dir)/perl
 	$(INSTALL_CFG) lib/perl/*.pm $(modules_prefix)/$(lib_dir)/perl
 	mkdir -p $(modules_prefix)/$(lib_dir)/perl/OpenSER
@@ -72,3 +72,5 @@ install_module_custom:
 	$(INSTALL_CFG) lib/perl/OpenSER/VDB/Adapter/*.pm \
 		$(modules_prefix)/$(lib_dir)/perl/OpenSER/VDB/Adapter
 
+install-scripts: install-perl-scripts
+

+ 11 - 8
modules_k/presence/subscribe.c

@@ -802,7 +802,7 @@ int extract_sdialog_info(subs_t* subs,struct sip_msg* msg, int mexp,
 	else
 	{
 		memset( &TO , 0, sizeof(TO) );
-		if( !parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO));
+		if( !parse_to(msg->to->body.s,msg->to->body.s + msg->to->body.len + 1, &TO))
 		{
 			LM_DBG("'To' header NOT parsed\n");
 			goto error;
@@ -1030,16 +1030,19 @@ int get_stored_info(struct sip_msg* msg, subs_t* subs, int* reply_code,
 	{
 		lock_get(&subs_htable[i].lock);
 		s= search_shtable(subs_htable, subs->callid,subs->to_tag,subs->from_tag, i);
-		if (s && !EVENT_DIALOG_SLA(s->event->evp))
+		if (s)
 		{
-			pres_uri.s= (char*)pkg_malloc(s->pres_uri.len* sizeof(char));
-			if(pres_uri.s== NULL)
+			if(!EVENT_DIALOG_SLA(s->event->evp))
 			{
-				lock_release(&subs_htable[i].lock);
-				ERR_MEM(PKG_MEM_STR);
+				pres_uri.s= (char*)pkg_malloc(s->pres_uri.len* sizeof(char));
+				if(pres_uri.s== NULL)
+				{
+					lock_release(&subs_htable[i].lock);
+					ERR_MEM(PKG_MEM_STR);
+				}
+				memcpy(pres_uri.s, s->pres_uri.s, s->pres_uri.len);
+				pres_uri.len= s->pres_uri.len;
 			}
-			memcpy(pres_uri.s, s->pres_uri.s, s->pres_uri.len);
-			pres_uri.len= s->pres_uri.len;
 			goto found_rec;
 		}
 		lock_release(&subs_htable[i].lock);

+ 2 - 1
modules_k/presence/utils_func.h

@@ -50,7 +50,8 @@
 
 
 #define EVENT_DIALOG_SLA(ev) \
-	((ev)->type == EVENT_DIALOG && (ev)->params.dialog.sla)
+	((ev)->type == EVENT_DIALOG \
+		&& ((ev)->params.dialog.sla || (ev)->params.dialog.ma))
 
 
 static inline int uandd_to_uri(str user,  str domain, str *out)

+ 7 - 4
modules_k/presence_xml/README

@@ -90,10 +90,13 @@ Chapter 1. Admin Guide
 
    The module does specific handling for notify-subscribe events using xml
    bodies. It is used with the general event handling module, presence. It
-   constructs and adds 3 events to it: presence, presence.winfo,
-   dialog;sla. By default all these events will be handled. If you do want
-   to activate only certain events then disable the unneeded events via
-   the module parameters.
+   constructs and adds 3 events to it:
+     * presence - SIMPLE status presence: RFC 3856
+     * presence.winfo - SIMPLE watcher info: RFC 3857
+     * dialog;sla (or dialog;ma) - Bridged Line Appearances (BLA) (or
+       Multiple Line Appearances (MLA)): draft-anil-sipping-bla
+
+   You can control which events are enabled via module parameters.
 
    This module takes the XCAP permission rule documents from xcap_table.
    The presence permission rules are interpreted according to the

+ 19 - 5
modules_k/presence_xml/doc/presence_xml_admin.xml

@@ -16,11 +16,25 @@
 	<section>
 	<title>Overview</title>
 	<para> 
-	The module does specific handling for notify-subscribe events using xml bodies.
-	It is used with the general event handling module, presence. It constructs and adds
-	3 events to it: presence, presence.winfo, dialog;sla. By default all these events
-	will be handled. If you do want to activate only certain events then disable the
-	unneeded events via the module parameters.
+		The module does specific handling for notify-subscribe events using xml
+		bodies. It is used with the general event handling module, presence.
+		It constructs and adds 3 events to it:
+		<itemizedlist>
+			<listitem>
+				<para>presence - SIMPLE status presence: RFC 3856</para>
+			</listitem>
+			<listitem>
+				<para>presence.winfo - SIMPLE watcher info: RFC 3857</para>
+			</listitem>
+			<listitem>
+				<para>dialog;sla (or dialog;ma) - Bridged Line Appearances
+				(BLA) (or Multiple Line Appearances (MLA)):
+				draft-anil-sipping-bla</para>
+			</listitem>
+		</itemizedlist>
+	</para>
+	<para>
+	You can control which events are enabled via module parameters.
 	</para>
 	<para>
 	This module takes the XCAP permission rule documents from xcap_table.

+ 13 - 3
modules_k/pua_dialoginfo/dialog_publish.c

@@ -55,7 +55,8 @@ void print_publ(publ_info_t* p)
 }	
 
 str* build_dialoginfo(char *state, str *entity, str *peer, str *callid, 
-	unsigned int initiator, str *localtag, str *remotetag)
+	unsigned int initiator, str *localtag, str *remotetag,
+	str *localtarget, str *remotetarget)
 {
 	xmlDocPtr  doc = NULL; 
 	xmlNodePtr root_node = NULL;
@@ -187,6 +188,10 @@ str* build_dialoginfo(char *state, str *entity, str *peer, str *callid,
 			LM_ERR("while adding child\n");
 			goto error;
 		}
+		if (remotetarget && remotetarget->s) {
+			memcpy(buf, remotetarget->s, remotetarget->len);
+			buf[remotetarget->len]= '\0';
+		}
 		xmlNewProp(tag_node, BAD_CAST "uri", BAD_CAST buf);
 
 		/* local tag*/	
@@ -216,6 +221,10 @@ str* build_dialoginfo(char *state, str *entity, str *peer, str *callid,
 			LM_ERR("while adding child\n");
 			goto error;
 		}
+		if (localtarget && localtarget->s) {
+			memcpy(buf, localtarget->s, localtarget->len);
+			buf[localtarget->len]= '\0';
+		}
 		xmlNewProp(tag_node, BAD_CAST "uri", BAD_CAST buf);
 	}
 
@@ -251,7 +260,8 @@ error:
 }	
 
 void dialog_publish(char *state, str *entity, str *peer, str *callid, 
-	unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag)
+	unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag,
+	str *localtarget, str *remotetarget)
 {
 	str* body= NULL;
 	str uri= {NULL, 0};
@@ -273,7 +283,7 @@ void dialog_publish(char *state, str *entity, str *peer, str *callid,
 	content_type.s= "application/dialog-info+xml";
 	content_type.len= 27;
 
-	body= build_dialoginfo(state, entity, peer, callid, initiator, localtag, remotetag);
+	body= build_dialoginfo(state, entity, peer, callid, initiator, localtag, remotetag, localtarget, remotetarget);
 	if(body == NULL || body->s == NULL)
 		goto error;
 	

+ 51 - 14
modules_k/pua_dialoginfo/pua_dialoginfo.c

@@ -41,6 +41,7 @@
 #include "../../mem/shm_mem.h"
 #include "../../parser/msg_parser.h"
 #include "../../parser/parse_to.h"
+#include "../../parser/contact/parse_contact.h"
 #include "../../str.h"
 #include "../../mem/mem.h"
 #include "../../pt.h"
@@ -57,6 +58,7 @@ MODULE_VERSION
 #define DEF_INCLUDE_TAGS 1
 #define DEF_OVERRIDE_LIFETIME 0
 #define DEF_CALLER_ALWAYS_CONFIRMED 0
+#define DEF_INCLUDE_REQ_URI 0
 
 /* define PUA_DIALOGINFO_DEBUG to activate more verbose 
  * logging and dialog info callback debugging
@@ -73,6 +75,7 @@ int include_localremote = DEF_INCLUDE_LOCALREMOTE;
 int include_tags        = DEF_INCLUDE_TAGS;
 int override_lifetime   = DEF_OVERRIDE_LIFETIME;
 int caller_confirmed    = DEF_CALLER_ALWAYS_CONFIRMED;
+int include_req_uri     = DEF_INCLUDE_REQ_URI;
 
 
 send_publish_t pua_send_publish;
@@ -92,6 +95,7 @@ static param_export_t params[]={
 	{"include_tags",        INT_PARAM, &include_tags },
 	{"override_lifetime",   INT_PARAM, &override_lifetime },
 	{"caller_confirmed",    INT_PARAM, &caller_confirmed },
+	{"include_req_uri",     INT_PARAM, &include_req_uri },
 	{0, 0, 0 }
 };
 
@@ -195,25 +199,46 @@ static void
 __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
 {
 	str tag = {0,0};
+	str uri = {0,0};
+	str target = {0,0};
+
 	struct dlginfo_cell *dlginfo = (struct dlginfo_cell*)*_params->param;
 
+	if (include_req_uri) {
+		uri = dlginfo->req_uri;
+	} else {
+		uri = dlginfo->to_uri;
+	}
+
 	switch (type) {
 	case DLGCB_FAILED:
 	case DLGCB_TERMINATED:
 	case DLGCB_EXPIRED:
 		LM_DBG("dialog over, from=%.*s\n", dlginfo->from_uri.len, dlginfo->from_uri.s);
-		dialog_publish("terminated", &(dlginfo->from_uri), &(dlginfo->to_uri), &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0);
-		dialog_publish("terminated", &(dlginfo->to_uri), &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0);
+		dialog_publish("terminated", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target);
+		dialog_publish("terminated", &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact));
 		break;
 	case DLGCB_CONFIRMED:
 	case DLGCB_REQ_WITHIN:
 		LM_DBG("dialog confirmed, from=%.*s\n", dlginfo->from_uri.len, dlginfo->from_uri.s);
-		dialog_publish("confirmed", &(dlginfo->from_uri), &(dlginfo->to_uri), &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0);
-		dialog_publish("confirmed", &(dlginfo->to_uri), &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0);
+		dialog_publish("confirmed", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target);
+		dialog_publish("confirmed", &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact));
 		break;
 	case DLGCB_EARLY:
 		LM_DBG("dialog is early, from=%.*s\n", dlginfo->from_uri.len, dlginfo->from_uri.s);
 		if (include_tags) {
+			/* get remotetarget */
+			if ( !_params->msg->contact && ((parse_headers(_params->msg, HDR_CONTACT_F,0)<0) || !_params->msg->contact) ) {
+				LM_ERR("bad reply or missing CONTACT hdr\n");
+			} else {
+				if ( parse_contact(_params->msg->contact)<0 ||
+						((contact_body_t *)_params->msg->contact->parsed)->contacts==NULL ||
+						((contact_body_t *)_params->msg->contact->parsed)->contacts->next!=NULL ) {
+					LM_ERR("Malformed CONTACT hdr\n");
+				} else {
+					target = ((contact_body_t *)_params->msg->contact->parsed)->contacts->uri;
+				}
+			}
 			/* get to tag*/
 			if ( !_params->msg->to && ((parse_headers(_params->msg, HDR_TO_F,0)<0) || !_params->msg->to) ) {
 				LM_ERR("bad reply or missing TO hdr :-/\n");
@@ -228,24 +253,28 @@ __dialog_sendpublish(struct dlg_cell *dlg, int type, struct dlg_cb_params *_para
 				}
 			}
 			if (caller_confirmed) {
-				dialog_publish("confirmed", &(dlginfo->from_uri), &(dlginfo->to_uri), &(dlginfo->callid), 1, dlginfo->lifetime, &(dlginfo->from_tag), &tag);
+				dialog_publish("confirmed", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, &(dlginfo->from_tag), &tag, &(dlginfo->from_contact), &target);
 			} else {
-				dialog_publish("early", &(dlginfo->from_uri), &(dlginfo->to_uri), &(dlginfo->callid), 1, dlginfo->lifetime, &(dlginfo->from_tag), &tag);
+				dialog_publish("early", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, &(dlginfo->from_tag), &tag, &(dlginfo->from_contact), &target);
 			}
-			dialog_publish("early", &(dlginfo->to_uri), &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, &tag, &(dlginfo->from_tag));
+			dialog_publish("early", &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, &tag, &(dlginfo->from_tag), &target, &(dlginfo->from_contact));
+
 		} else {
 			if (caller_confirmed) {
-				dialog_publish("confirmed", &(dlginfo->from_uri), &(dlginfo->to_uri), &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0);
+				dialog_publish("confirmed", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target);
+
 			} else {
-				dialog_publish("early", &(dlginfo->from_uri), &(dlginfo->to_uri), &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0);
+				dialog_publish("early", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target);
 			}
-			dialog_publish("early", &(dlginfo->to_uri), &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0);
+			dialog_publish("early", &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact));
+
 		}
 		break;
 	default:
 		LM_ERR("unhandled dialog callback type %d received, from=%.*s\n", type, dlginfo->from_uri.len, dlginfo->from_uri.s);
-		dialog_publish("terminated", &(dlginfo->from_uri), &(dlginfo->to_uri), &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0);
-		dialog_publish("terminated", &(dlginfo->to_uri), &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0);
+		dialog_publish("terminated", &(dlginfo->from_uri), &uri, &(dlginfo->callid), 1, dlginfo->lifetime, 0, 0, &(dlginfo->from_contact), &target);
+		dialog_publish("terminated", &uri, &(dlginfo->from_uri), &(dlginfo->callid), 0, dlginfo->lifetime, 0, 0, &target, &(dlginfo->from_contact));
+
 	}
 }
 
@@ -266,7 +295,9 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
 			dlg->from_uri.len + 
 			dlg->to_uri.len + 
 			dlg->callid.len + 
-			dlg->tag[0].len;
+			dlg->tag[0].len +
+			dlg->req_uri.len +
+			dlg->contact[0].len;
 
     dlginfo = (struct dlginfo_cell*)shm_malloc( len );
     if (dlginfo==0) {
@@ -285,10 +316,16 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
 	dlginfo->callid.len   = dlg->callid.len;
 	dlginfo->from_tag.s   = dlginfo->callid.s + dlg->callid.len;
 	dlginfo->from_tag.len = dlg->tag[0].len;
+	dlginfo->req_uri.s    = dlginfo->from_tag.s + dlginfo->from_tag.len;
+	dlginfo->req_uri.len  = dlg->req_uri.len;
+	dlginfo->from_contact.s   = dlginfo->req_uri.s + dlginfo->req_uri.len;
+	dlginfo->from_contact.len = dlg->contact[0].len;
 	memcpy(dlginfo->from_uri.s, dlg->from_uri.s, dlg->from_uri.len);
 	memcpy(dlginfo->to_uri.s, dlg->to_uri.s, dlg->to_uri.len);
 	memcpy(dlginfo->callid.s, dlg->callid.s, dlg->callid.len);
 	memcpy(dlginfo->from_tag.s, dlg->tag[0].s, dlg->tag[0].len);
+	memcpy(dlginfo->req_uri.s, dlg->req_uri.s, dlg->req_uri.len);
+	memcpy(dlginfo->from_contact.s, dlg->contact[0].s, dlg->contact[0].len);
 	
 	/* register dialog callbacks which triggers sending PUBLISH */
 	if (dlg_api.register_dlgcb(dlg, 
@@ -311,7 +348,7 @@ __dialog_created(struct dlg_cell *dlg, int type, struct dlg_cb_params *_params)
 	}
 #endif
 
-	dialog_publish("Trying", &(dlg->from_uri), &(dlg->to_uri), &(dlg->callid), 1, dlginfo->lifetime, 0, 0);
+	dialog_publish("Trying", &(dlg->from_uri), (include_req_uri)?&(dlg->req_uri):&(dlg->to_uri), &(dlg->callid), 1, dlginfo->lifetime, 0, 0, 0, 0);
 }
 
 

+ 4 - 1
modules_k/pua_dialoginfo/pua_dialoginfo.h

@@ -30,7 +30,8 @@
 extern send_publish_t pua_send_publish;
 
 void dialog_publish(char *state, str *entity, str *peer, str *callid, 
-	unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag);
+	unsigned int initiator, unsigned int lifetime, str *localtag, str *remotetag,
+	str *localtarget, str *remotetarget);
 
 /* store the important data locally to avoid reading the data from the 
    dlg_cell during the callback (as this could create a race condition 
@@ -41,6 +42,8 @@ struct dlginfo_cell {
 	str callid;
 	str from_tag;
 /*	str *to_tag; */
+	str req_uri;
+	str from_contact;
 	unsigned int lifetime;	
 };
 

+ 2 - 5
modules_k/pv/pv.c

@@ -68,6 +68,8 @@ static pv_export_t mod_pvs[] = {
 	{ {"sel", sizeof("sel")-1}, /* select */
 		PVT_OTHER, pv_get_select, 0,
 		pv_parse_select_name, 0, 0, 0 },
+	{{"snd", (sizeof("snd")-1)}, PVT_OTHER, pv_get_snd, 0,
+		pv_parse_snd_name, 0, 0, 0},
 
 	{{"avp", (sizeof("avp")-1)}, PVT_AVP, pv_get_avp, pv_set_avp,
 		pv_parse_avp_name, pv_parse_index, 0, 0},
@@ -420,11 +422,6 @@ static int mod_init(void)
 		return -1;
 	}
 
-	if(init_shvars()<0)
-	{
-		LM_ERR("init shvars failed\n");
-		return -1;
-	}
 	return 0;
 }
 

+ 82 - 0
modules_k/pv/pv_branch.c

@@ -22,6 +22,7 @@
 
 
 #include "../../dset.h"
+#include "../../onsend.h"
 
 #include "pv_branch.h"
 
@@ -141,3 +142,84 @@ error:
 	return -1;
 }
 
+int pv_get_snd(struct sip_msg *msg, pv_param_t *param,
+		pv_value_t *res)
+{
+	struct onsend_info* snd_inf;
+	str s;
+
+	snd_inf=get_onsend_info();
+	if (! likely(snd_inf && snd_inf->send_sock))
+		return pv_get_null(msg, param, res);
+
+	switch(param->pvn.u.isname.name.n)
+	{
+		case 1: /* af */
+			return pv_get_uintval(msg, param, res,
+					(int)snd_inf->send_sock->address.af);
+		case 2: /* port */
+			return pv_get_uintval(msg, param, res,
+					(int)snd_inf->send_sock->port_no);
+		case 3: /* proto */
+			return pv_get_uintval(msg, param, res,
+					(int)snd_inf->send_sock->proto);
+		case 4: /* buf */
+			s.s   = snd_inf->buf;
+			s.len = snd_inf->len;
+			return pv_get_strval(msg, param, res, &s);
+		case 5: /* len */
+			return pv_get_uintval(msg, param, res,
+					(int)snd_inf->len);
+		default:
+			/* 0 - ip */
+			return pv_get_strval(msg, param, res,
+					&snd_inf->send_sock->address_str);
+	}
+
+	return 0;
+}
+
+int pv_parse_snd_name(pv_spec_p sp, str *in)
+{
+	if(sp==NULL || in==NULL || in->len<=0)
+		return -1;
+
+	switch(in->len)
+	{
+		case 2:
+			if(strncmp(in->s, "ip", 2)==0)
+				sp->pvp.pvn.u.isname.name.n = 0;
+			else if(strncmp(in->s, "af", 2)==0)
+				sp->pvp.pvn.u.isname.name.n = 1;
+			else goto error;
+		break;
+		case 3:
+			if(strncmp(in->s, "buf", 3)==0)
+				sp->pvp.pvn.u.isname.name.n = 4;
+			else if(strncmp(in->s, "len", 3)==0)
+				sp->pvp.pvn.u.isname.name.n = 5;
+			else goto error;
+		break;
+		case 4:
+			if(strncmp(in->s, "port", 4)==0)
+				sp->pvp.pvn.u.isname.name.n = 2;
+			else goto error;
+		break;
+		case 5:
+			if(strncmp(in->s, "proto", 5)==0)
+				sp->pvp.pvn.u.isname.name.n = 3;
+			else goto error;
+		break;
+		default:
+			goto error;
+	}
+	sp->pvp.pvn.type = PV_NAME_INTSTR;
+	sp->pvp.pvn.u.isname.type = 0;
+
+	return 0;
+
+error:
+	LM_ERR("unknown PV time name %.*s\n", in->len, in->s);
+	return -1;
+}
+

+ 4 - 0
modules_k/pv/pv_branch.h

@@ -31,5 +31,9 @@ int pv_set_branchx(struct sip_msg* msg, pv_param_t *param,
 		int op, pv_value_t *val);
 int pv_parse_branchx_name(pv_spec_p sp, str *in);
 
+int pv_get_snd(struct sip_msg *msg, pv_param_t *param,
+		pv_value_t *res);
+int pv_parse_snd_name(pv_spec_p sp, str *in);
+
 #endif
 

+ 1 - 1
modules_k/pv/pv_core.c

@@ -205,7 +205,7 @@ int pv_get_xuri_attr(struct sip_msg *msg, struct sip_uri *parsed_uri,
 	} else if(param->pvn.u.isname.name.n==4) /* protocol */ {
 		if(parsed_uri->transport_val.s==NULL)
 			return pv_get_udp(msg, param, res);
-		return pv_get_strintval(msg, param, res, &parsed_uri->transport,
+		return pv_get_strintval(msg, param, res, &parsed_uri->transport_val,
 				(int)parsed_uri->proto);
 	}
 	LM_ERR("unknown specifier\n");

+ 42 - 159
modules_k/pv/pv_shv.c

@@ -28,6 +28,8 @@
 
 #include "../../dprint.h"
 #include "../../mem/mem.h"
+#include "../../mem/shm_mem.h"
+#include "../../shm_init.h"
 #include "../../ut.h"
 #include "../../pvar.h"
 
@@ -38,9 +40,6 @@ gen_lock_set_t* shvar_locks=0;
 
 static sh_var_t *sh_vars = 0;
 static str shv_cpy = {0, 0};
-static script_var_t *sh_local_vars = 0;
-static pv_spec_list_t *sh_pv_list = 0;
-static int shvar_initialized = 0;
 
 /*
  * Initialize locks
@@ -48,6 +47,11 @@ static int shvar_initialized = 0;
 int shvar_init_locks(void)
 {
 	int i;
+
+	/* already initialized */
+	if(shvar_locks!=0)
+		return 0;
+
 	i = shvar_locks_no;
 	do {
 		if ((( shvar_locks=lock_set_alloc(i))!=0)&&
@@ -146,6 +150,18 @@ sh_var_t* add_shvar(str *name)
 	if(name==0 || name->s==0 || name->len<=0)
 		return 0;
 
+	if(!shm_initialized())
+	{
+		LM_ERR("shm not intialized - cannot define shm now\n");
+		return 0;
+	}
+
+	if(shvar_init_locks()!=0)
+	{
+		LM_ERR("cannot init shv locks\n");
+		return 0;
+	}
+
 	for(sit=sh_vars; sit; sit=sit->next)
 	{
 		if(sit->name.len==name->len
@@ -189,131 +205,6 @@ sh_var_t* add_shvar(str *name)
 	return sit;
 }
 
-script_var_t* add_local_shvar(str *name)
-{
-	script_var_t *it;
-
-	if(name==0 || name->s==0 || name->len<=0)
-		return 0;
-
-	for(it=sh_local_vars; it; it=it->next)
-	{
-		if(it->name.len==name->len
-				&& strncmp(name->s, it->name.s, name->len)==0)
-			return it;
-	}
-	it = (script_var_t*)pkg_malloc(sizeof(script_var_t));
-	if(it==0)
-	{
-		LM_ERR("out of pkg mem\n");
-		return 0;
-	}
-	memset(it, 0, sizeof(script_var_t));
-	it->name.s = (char*)pkg_malloc((name->len+1)*sizeof(char));
-
-	if(it->name.s==0)
-	{
-		LM_ERR("out of pkg mem!\n");
-		return 0;
-	}
-	it->name.len = name->len;
-	strncpy(it->name.s, name->s, name->len);
-	it->name.s[it->name.len] = '\0';
-
-	it->next = sh_local_vars;
-
-	sh_local_vars = it;
-
-	return it;
-}
-
-
-int init_shvars(void)
-{
-	script_var_t *lit = 0;
-	sh_var_t *sit = 0;
-	pv_spec_list_t *pvi = 0;
-	pv_spec_list_t *pvi0 = 0;
-
-	if(shvar_init_locks()!=0)
-		return -1;
-
-	LM_DBG("moving shvars in share memory\n");
-	for(lit=sh_local_vars; lit; lit=lit->next)
-	{
-		sit = (sh_var_t*)shm_malloc(sizeof(sh_var_t));
-		if(sit==0)
-		{
-			LM_ERR("out of sh mem\n");
-			return -1;
-		}
-		memset(sit, 0, sizeof(sh_var_t));
-		sit->name.s = (char*)shm_malloc((lit->name.len+1)*sizeof(char));
-
-		if(sit->name.s==0)
-		{
-			LM_ERR("out of pkg mem!\n");
-			shm_free(sit);
-			return -1;
-		}
-		sit->name.len = lit->name.len;
-		strncpy(sit->name.s, lit->name.s, lit->name.len);
-		sit->name.s[sit->name.len] = '\0';
-
-		if(sh_vars!=0)
-			sit->n = sh_vars->n + 1;
-		else
-			sit->n = 1;
-
-#ifdef GEN_LOCK_T_PREFERED
-		sit->lock = &shvar_locks->locks[sit->n%shvar_locks_no];
-#else
-		sit->lockidx = sit->n%shvar_locks_no;
-#endif
-
-		if(set_shvar_value(sit, &lit->v.value, lit->v.flags)==NULL)
-		{
-			shm_free(sit->name.s);
-			shm_free(sit);
-			return -1;
-		}
-
-		pvi0 = 0;
-		pvi = sh_pv_list;
-		while(pvi!=NULL)
-		{
-			if(pvi->spec->pvp.pvn.u.dname == lit)
-			{
-				pvi->spec->pvp.pvn.u.dname = (void*)sit;
-				if(pvi0!=NULL)
-				{
-					pvi0->next = pvi->next;
-					pkg_free(pvi);
-					pvi = pvi0->next;
-				} else {
-					sh_pv_list = pvi->next;
-					pkg_free(pvi);
-					pvi = sh_pv_list;
-				}
-			} else {
-				pvi0 = pvi;
-				pvi = pvi->next;
-			}
-		}
-
-		sit->next = sh_vars;
-		sh_vars = sit;
-	}
-	destroy_vars_list(sh_local_vars);
-	if(sh_pv_list != NULL)
-	{
-		LM_ERR("sh_pv_list not null!\n");
-		return -1;
-	}
-	shvar_initialized = 1;
-	return 0;
-}
-
 /* call it with lock set */
 sh_var_t* set_shvar_value(sh_var_t* shv, int_str *value, int flags)
 {
@@ -432,36 +323,18 @@ void destroy_shvars(void)
 /********* PV functions *********/
 int pv_parse_shvar_name(pv_spec_p sp, str *in)
 {
-	pv_spec_list_t *pvi = 0;
-	
 	if(in==NULL || in->s==NULL || sp==NULL)
 		return -1;
 	
 	sp->pvp.pvn.type = PV_NAME_PVAR;
-	if(shvar_initialized)
-		sp->pvp.pvn.u.dname = (void*)add_shvar(in);
-	else
-		sp->pvp.pvn.u.dname = (void*)add_local_shvar(in);
+	sp->pvp.pvn.u.dname = (void*)add_shvar(in);
+
 	if(sp->pvp.pvn.u.dname==NULL)
 	{
-		LM_ERR("cannot register shvar [%.*s] (%d)\n", in->len, in->s,
-				shvar_initialized);
+		LM_ERR("cannot register shvar [%.*s]\n", in->len, in->s);
 		return -1;
 	}
 
-	if(shvar_initialized==0)
-	{
-		pvi = (pv_spec_list_t*)pkg_malloc(sizeof(pv_spec_list_t));
-		if(pvi == NULL)
-		{
-			LM_ERR("cannot index shvar [%.*s]\n", in->len, in->s);
-			return -1;
-		}
-		pvi->spec = sp;
-		pvi->next = sh_pv_list;
-		sh_pv_list = pvi;
-	}
-
 	return 0;
 }
 
@@ -749,10 +622,14 @@ int param_set_xvar( modparam_t type, void* val, int mode)
 	int_str isv;
 	int flags;
 	int ival;
-	script_var_t *sv;
+	script_var_t *pkv;
+	sh_var_t *shv;
 
-	if(shvar_initialized!=0)
+	if(!shm_initialized()!=0)
+	{
+		LM_ERR("shm not initialized - cannot set value for PVs\n");
 		goto error;
+	}
 
 	s.s = (char*)val;
 	if(s.s == NULL || s.s[0] == '\0')
@@ -785,14 +662,19 @@ int param_set_xvar( modparam_t type, void* val, int mode)
 			goto error;
 		isv.n = ival;
 	}
-	if(mode==0)
-		sv = add_var(&s);
-	else
-		sv = add_local_shvar(&s);
-	if(sv==NULL)
-		goto error;
-	if(set_var_value(sv, &isv, flags)==NULL)
-		goto error;
+	if(mode==0) {
+		pkv = add_var(&s);
+		if(pkv==NULL)
+			goto error;
+		if(set_var_value(pkv, &isv, flags)==NULL)
+			goto error;
+	} else {
+		shv = add_shvar(&s);
+		if(shv==NULL)
+			goto error;
+		if(set_shvar_value(shv, &isv, flags)==NULL)
+			goto error;
+	}
 	
 	return 0;
 error:
@@ -810,3 +692,4 @@ int param_set_shvar( modparam_t type, void* val)
 	return param_set_xvar(type, val, 1);
 }
 
+/* vi: set ts=4 sw=4 tw=79:ai:cindent: */

+ 0 - 1
modules_k/pv/pv_shv.h

@@ -41,7 +41,6 @@ typedef struct sh_var {
 	struct sh_var *next;
 } sh_var_t, *sh_var_p;
 
-int init_shvars(void);
 sh_var_t* set_shvar_value(sh_var_t *shv, int_str *value, int flags);
 sh_var_t* get_shvar_by_name(str *name);
 

+ 1 - 1
modules_k/snmpstats/snmpObjects.c

@@ -611,7 +611,7 @@ static int set_if_valid_threshold(modparam_t type, void *val, char *varStr,
 		return -1;
 	}
 
-	if (type != INT_PARAM) {
+	if (PARAM_TYPE_MASK(type) != INT_PARAM) {
 		LM_ERR("%s called with type %d instead of %d!\n",
 				varStr, type, INT_PARAM);
 		return -1;

+ 1 - 1
modules_k/snmpstats/utilities.c

@@ -78,7 +78,7 @@ int stringHandlerSanityCheck( modparam_t type, void *val, char *parameterName)
 	char *theString = (char *)val;
 
 	/* Make sure the function was called correctly. */
-	if (type != STR_PARAM) {
+	if (PARAM_TYPE_MASK(type) != STR_PARAM) {
 		LM_ERR("the %s parameter was assigned a type %d instead of %d\n",
 				parameterName, type, STR_PARAM);
 		return 0;

+ 3 - 3
modules_k/uac/auth.c

@@ -232,9 +232,9 @@ static inline struct hdr_field *get_autenticate_hdr(struct sip_msg *rpl,
 	}
 	for( hdr=rpl->headers ; hdr ; hdr=hdr->next )
 	{
-		if ( hdr->type!=HDR_OTHER_T )
-			continue;
-		if (cmp_hdrname_str(&hdr->name, &hdr_name)==0)
+		if((rpl_code==WWW_AUTH_CODE && hdr->type==HDR_WWW_AUTHENTICATE_T)
+				|| (rpl_code==PROXY_AUTH_CODE
+					&& hdr->type==HDR_PROXY_AUTHENTICATE_T))
 			return hdr;
 	}
 

+ 1 - 0
modules_k/uac/uac_send.c

@@ -383,6 +383,7 @@ int uac_req_send(struct sip_msg *msg, char *s1, char *s2)
 	uac_r.method = &_uac_req.s_method;
 	uac_r.headers = (_uac_req.s_hdrs.len <= 0) ? NULL : &_uac_req.s_hdrs;
 	uac_r.body = (_uac_req.s_body.len <= 0) ? NULL : &_uac_req.s_body;
+	uac_r.cb_flags =(_uac_req.onreply > 0) ? TMCB_LOCAL_COMPLETED : 0;
 	uac_r.cb  = (_uac_req.onreply > 0) ? uac_send_tm_callback : NULL;
 	/* Callback function */
 	uac_r.cbp = (_uac_req.onreply > 0) ? (void*)(long)_uac_req.onreply : 0;

+ 8 - 0
modules_k/usrloc/ul_mod.c

@@ -55,6 +55,7 @@
 #include "ul_mod.h"
 #include "../../sr_module.h"
 #include "../../dprint.h"
+#include "../../rpc_lookup.h"
 #include "../../timer.h"     /* register_timer */
 #include "../../globals.h"   /* is_main */
 #include "../../ut.h"        /* str_init */
@@ -63,6 +64,7 @@
 #include "urecord.h"         /* {insert,delete,get}_ucontact */
 #include "ucontact.h"        /* update_ucontact */
 #include "ul_mi.h"
+#include "ul_rpc.h"
 #include "ul_callback.h"
 #include "usrloc.h"
 
@@ -228,6 +230,12 @@ static int mod_init(void)
 		return -1;
 	}
 
+	if (rpc_register_array(ul_rpc)!=0)
+	{
+		LM_ERR("failed to register RPC commands\n");
+		return -1;
+	}
+
 	/* Compute the lengths of string parameters */
 	user_col.len = strlen(user_col.s);
 	domain_col.len = strlen(domain_col.s);

+ 293 - 0
modules_k/usrloc/ul_rpc.c

@@ -0,0 +1,293 @@
+/*
+ * $Id$
+ *
+ * usrloc module
+ *
+ * Copyright (C) 2009 Daniel-Constantin Mierla (asipto.com).
+ *
+ * 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 "../../ip_addr.h"
+#include "../../dprint.h"
+
+#include "ul_rpc.h"
+#include "dlist.h"
+#include "ucontact.h"
+#include "udomain.h"
+
+static const char* ul_rpc_dump_doc[2] = {
+	"Dump user location tables",
+	0
+};
+
+static void ul_rpc_dump(rpc_t* rpc, void* ctx)
+{
+	struct urecord* r;
+	dlist_t* dl;
+	udomain_t* dom;
+	time_t t;
+	str brief = {0, 0};
+	str empty_str = {"[not set]", 9};
+	str state_str = {"[not set]", 9};
+	str socket_str = {"[not set]", 9};
+	int summary = 0;
+	ucontact_t* c;
+	void* th;
+	void* ah;
+	void* ih;
+	void* vh;
+	void* sh;
+	int max, n, i;
+
+	rpc->scan(ctx, "*S", &brief);
+
+	if(brief.len==5 && (strncmp(brief.s, "brief", 5)==0))
+		summary = 1;
+	
+	t = time(0);
+	for( dl=root ; dl ; dl=dl->next ) {
+		dom = dl->d;
+		if (rpc->add(ctx, "{", &th) < 0)
+		{
+			rpc->fault(ctx, 500, "Internal error creating top rpc");
+			return;
+		}
+		if(rpc->struct_add(th, "Sd{",
+					"Domain",  &dl->name,
+					"Size",    (int)dom->size,
+					"AoRs",    &ah)<0)
+		{
+			rpc->fault(ctx, 500, "Internal error creating inner struct");
+			return;
+		}
+		for(i=0,n=0,max=0; i<dom->size; i++) {
+			lock_ulslot( dom, i);
+			n += dom->table[i].n;
+			if(max<dom->table[i].n)
+				max= dom->table[i].n;
+			for( r = dom->table[i].first ; r ; r=r->next ) {
+				if(summary==1)
+				{
+					if(rpc->struct_add(ah, "S",
+							"AoR", &r->aor)<0)
+					{
+						unlock_ulslot( dom, i);
+						rpc->fault(ctx, 500, "Internal error creating aor struct");
+						return;
+					}
+				} else {
+					if(rpc->struct_add(ah, "S{",
+							"AoR", &r->aor,
+							"Contacts", &ih)<0)
+					{
+						unlock_ulslot( dom, i);
+						rpc->fault(ctx, 500, "Internal error creating aor struct");
+						return;
+					}
+					for( c=r->contacts ; c ; c=c->next)
+					{
+						if(rpc->struct_add(ih, "{",
+							"Contact", &vh)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500, "Internal error creating contact struct");
+							return;
+						}
+						if(rpc->struct_add(vh, "S",
+									"Address", &c->c)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding addr");
+								return;
+						}
+						if (c->expires == 0) {
+							if(rpc->struct_add(vh, "s",
+									"Expires", "permanent")<0)
+							{
+								unlock_ulslot( dom, i);
+								rpc->fault(ctx, 500,
+										"Internal error adding expire");
+								return;
+							}
+						} else if (c->expires == UL_EXPIRED_TIME) {
+							if(rpc->struct_add(vh, "s",
+									"Expires", "deleted")<0)
+							{
+								unlock_ulslot( dom, i);
+								rpc->fault(ctx, 500,
+										"Internal error adding expire");
+								return;
+							}
+						} else if (t > c->expires) {
+							if(rpc->struct_add(vh, "s",
+									"Expires", "expired")<0)
+							{
+								unlock_ulslot( dom, i);
+								rpc->fault(ctx, 500,
+										"Internal error adding expire");
+								return;
+							}
+						} else {
+							if(rpc->struct_add(vh, "d",
+									"Expires", (int)(c->expires - t))<0)
+							{
+								unlock_ulslot( dom, i);
+								rpc->fault(ctx, 500,
+										"Internal error adding expire");
+								return;
+							}
+						}
+						if (c->state == CS_NEW) {
+							state_str.s = "CS_NEW";
+							state_str.len = 6;
+						} else if (c->state == CS_SYNC) {
+							state_str.s = "CS_SYNC";
+							state_str.len = 7;
+						} else if (c->state== CS_DIRTY) {
+							state_str.s = "CS_DIRTY";
+							state_str.len = 8;
+						} else {
+							state_str.s = "CS_UNKNOWN";
+							state_str.len = 10;
+						}
+						if(c->sock)
+						{
+							socket_str.s = c->sock->sock_str.s;
+							socket_str.len = c->sock->sock_str.len;
+						}
+						if(rpc->struct_add(vh, "f",
+									"Q", c->q)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding q");
+							return;
+						}
+						if(rpc->struct_add(vh, "S",
+									"Call-ID", &c->callid)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding callid");
+							return;
+						}
+						if(rpc->struct_add(vh, "d",
+									"CSeq", c->cseq)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding cseq");
+							return;
+						}
+						if(rpc->struct_add(vh, "S",
+									"User-Agent",
+										(c->user_agent.len)?&c->user_agent:
+												&empty_str)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding user-agent");
+							return;
+						}
+						if(rpc->struct_add(vh, "S",
+									"Received",
+										(c->received.len)?&c->received:
+												&empty_str)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding received");
+							return;
+						}
+						if(rpc->struct_add(vh, "S",
+									"Path",
+										(c->path.len)?&c->path:
+												&empty_str)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding path");
+							return;
+						}
+						if(rpc->struct_add(vh, "S",
+									"State", &state_str)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding state");
+							return;
+						}
+						if(rpc->struct_add(vh, "d",
+									"Flags", c->flags)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding flags");
+							return;
+						}
+						if(rpc->struct_add(vh, "d",
+									"CFlags", c->cflags)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding cflags");
+							return;
+						}
+						if(rpc->struct_add(vh, "S",
+									"Socket", &socket_str)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding socket");
+							return;
+						}
+						if(rpc->struct_add(vh, "d",
+									"Methods", c->methods)<0)
+						{
+							unlock_ulslot( dom, i);
+							rpc->fault(ctx, 500,
+									"Internal error adding methods");
+							return;
+						}
+					}
+				}
+			}
+
+			unlock_ulslot( dom, i);
+		}
+
+		/* extra attributes node */
+		if(rpc->struct_add(th, "{",
+					"Stats",    &sh)<0)
+		{
+			rpc->fault(ctx, 500, "Internal error creating stats struct");
+			return;
+		}
+		if(rpc->struct_add(sh, "dd",
+				"Records", n,
+				"Max-Slots", max)<0)
+		{
+			rpc->fault(ctx, 500, "Internal error adding stats");
+			return;
+		}
+	}
+}
+
+rpc_export_t ul_rpc[] = {
+	{"ul.dump",   ul_rpc_dump,   ul_rpc_dump_doc,   0},
+	{0, 0, 0, 0}
+};
+
+

+ 28 - 0
modules_k/usrloc/ul_rpc.h

@@ -0,0 +1,28 @@
+/*
+ * $Id$
+ *
+ * usrloc module
+ *
+ * Copyright (C) 2009 Daniel-Constantin Mierla (asipto.com).
+ *
+ * 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 _UL_RPC_H_
+#define _UL_RPC_H_
+
+#include "../../rpc.h"
+
+extern rpc_export_t ul_rpc[];
+
+#endif

+ 1 - 1
modules_s/sanity/sanity.c

@@ -691,7 +691,7 @@ int check_parse_uris(struct sip_msg* _msg, int checks) {
 			parse_to(_msg->from->body.s, _msg->from->body.s + \
 					_msg->from->body.len + 1, ft_body);
 			if (ft_body->error == PARSE_ERROR) {
-				LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to parse From header\n");
+				LOG(L_WARN, "sanity_check(): check_parse_uris(): failed to parse From header [%.*s]\n", _msg->from->body.len, _msg->from->body.s);
 				pkg_free(ft_body);
 				if (_msg->REQ_METHOD != METHOD_ACK) {
 					if (sl.reply(_msg, 400, "Bad From header") == -1) {

+ 2 - 1
parser/msg_parser.c

@@ -333,7 +333,8 @@ int parse_headers(struct sip_msg* msg, hdr_flags_t flags, int next)
 		rest=get_hdr_field(tmp, end, hf);
 		switch (hf->type){
 			case HDR_ERROR_T:
-				LOG(L_INFO,"ERROR: bad header  field\n");
+				LOG(L_INFO,"ERROR: bad header field [%.*s]\n",
+					(end-tmp>20)?20:(end-tmp), tmp);
 				goto  error;
 			case HDR_EOH_T:
 				msg->eoh=tmp; /* or rest?*/

+ 9 - 0
parser/parse_param.c

@@ -99,6 +99,15 @@ static inline void parse_event_dialog_class(param_hooks_t* h, param_t* p)
 			h->event_dialog.sla = p;
 		}
 		break;
+
+	case 'm':
+	case 'M':
+		if ((p->name.len == 2) &&
+		    (!strncasecmp(p->name.s + 1, "a", 1))) {
+			p->type = P_MA;
+			h->event_dialog.ma = p;
+		}
+		break;
 	}
 }
 

+ 3 - 1
parser/parse_param.h

@@ -61,7 +61,8 @@ typedef enum ptype {
 	P_FROM_TAG,  /* Dialog event package: from-tag */
 	P_TO_TAG,    /* Dialog event package: to-tag */
 	P_ISD,       /* Dialog event package: include-session-description */
-	P_SLA        /* Dialog event package: sla */
+	P_SLA,       /* Dialog event package: sla */
+	P_MA         /* Dialog event package: ma */
 } ptype_t;
 
 
@@ -121,6 +122,7 @@ struct event_dialog_hooks {
 	struct param* to_tag;
 	struct param* include_session_description;
 	struct param* sla;
+	struct param* ma;
 };
 
 /*

+ 7 - 0
pkg/kamailio/debian-lenny/changelog

@@ -1,3 +1,10 @@
+kamailio (3.0.0-rc2) unstable; urgency=low
+
+  * update to 3.0.0-rc2 from upstream
+  * updated debian/rules to work with the new style module packaging
+
+ -- Jonas Bergler <[email protected]>  Wed, 18 Nov 2009 12:30:02 +1300
+
 kamailio (1.5.0-svn1) unstable; urgency=low
 
   * increment debian packaging for trunk

+ 0 - 3
pkg/kamailio/debian-lenny/patches/00list

@@ -1,3 +0,0 @@
-10_no_lib64_on_64_bits
-11_always_smp
-

+ 0 - 27
pkg/kamailio/debian-lenny/patches/10_no_lib64_on_64_bits.dpatch

@@ -1,27 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 10_no_lib64_on_64_bits.dpatch by  <[email protected]>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Debian uses /usr/lib even for 64bit architectures.
-
-@DPATCH@
-diff -urNad kamailio-1.2.0~/Makefile.defs kamailio-1.2.0/Makefile.defs
---- kamailio-1.2.0~/Makefile.defs	2007-02-24 12:35:45.000000000 +0100
-+++ kamailio-1.2.0/Makefile.defs	2007-02-24 16:26:45.886854110 +0100
-@@ -123,14 +123,12 @@
- bin-dir = sbin/
- 
- ARCH_B= $(shell echo $(ARCH) | sed -e 's/.*64.*/64b/')
--ifeq ($(ARCH_B),64b)
--	LIBDIR ?= lib64
--else
--	LIBDIR ?= lib
-+ifneq ($(ARCH_B),64b)
- 	# assume 32b - it is not really used further
- 	ARCH_B=32b
- endif
- 
-+LIBDIR ?= lib
- lib-dir = $(LIBDIR)/$(MAIN_NAME)
- modules-dir = $(LIBDIR)/$(MAIN_NAME)/modules/
- 

+ 0 - 24
pkg/kamailio/debian-lenny/patches/11_always_smp.dpatch

@@ -1,24 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 11_always_smp.dpatch by  <[email protected]>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Always build for SMP.
-
-@DPATCH@
-diff -urNad kamailio-1.2.0~/Makefile.defs kamailio-1.2.0/Makefile.defs
---- kamailio-1.2.0~/Makefile.defs	2007-02-24 16:28:43.152825070 +0100
-+++ kamailio-1.2.0/Makefile.defs	2007-02-24 16:28:46.123102964 +0100
-@@ -82,12 +82,7 @@
- 	endif
- endif
- 
--SMP_STR = $(shell uname -v | grep -i "SMP")
--ifeq (,$(SMP_STR))
--	ISSMP=no
--else
--	ISSMP=yes
--endif
-+ISSMP=yes
- 
- OSREL = $(shell uname -r)
- # numerical version (good for comparisons: A.B.C => A*1000000+B*1000+C)

+ 55 - 16
pkg/kamailio/debian-lenny/rules

@@ -73,6 +73,13 @@ ALL_MODULES = $(MYSQL_MODULES) $(POSTGRES_MODULES) $(UNIXODBC_MODULES) $(JABBER_
 # modules not in the "main" package or unstable modules
 EXCLUDED_MODULES = $(ALL_MODULES) pa osp
 
+# module directories
+MODULE_DIRS=modules modules_s modules_k
+
+# library directories for cleaning up duplicates
+DUP_LIBS_DIRS=$(CURDIR)/debian/kamailio/usr/lib/kamailio
+
+
 # the same but with path prepended (needed for modules="...")
 MYSQL_MOD_PATH=$(addprefix modules/, $(MYSQL_MODULES))
 POSTGRES_MOD_PATH=$(addprefix modules/, $(POSTGRES_MODULES))
@@ -146,7 +153,7 @@ build-stamp: patch-stamp configure-stamp
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) utils include_modules="db_berkeley"
 
 	# generate the man pages for modules
-	$(MAKE) modules-docbook-man include_modules="$(ALL_MODULES)"
+	#$(MAKE) modules-docbook-man include_modules="$(ALL_MODULES)"
 
 	touch build-stamp
 
@@ -172,58 +179,65 @@ install: build
 
 	# Add here commands to install the package into debian/kamailio
 	# kamailio base package
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install skip_modules="$(EXCLUDED_MODULES)" \
+	#CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install skip_modules="$(EXCLUDED_MODULES)" \
+	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install \
 		basedir=$(CURDIR)/debian/kamailio \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio \
 		cfg-target=/etc/kamailio/ \
 		doc-dir=share/doc/kamailio
 
-	find $(CURDIR)/debian/kamailio/etc/kamailio -type f -exec chmod -x {} \;
+	# find $(CURDIR)/debian/kamailio/etc/kamailio -type f -exec chmod -x {} \;
 	sed -i -e "s/^PATH.*//" $(CURDIR)/debian/kamailio/usr/sbin/kamctl
 
 	# install only the mysql module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(MYSQL_MOD_PATH)"  \
+	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(MYSQL_MOD_PATH)" \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-mysql-module \
 		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-mysql-module \
 		cfg-target=/etc/kamailio/ \
+		cfg-prefix=$(CURDIR)/debian/kamailio-mysql-module \
 		doc-dir=share/doc/kamailio-mysql-module
 
 	# install only the postgres module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(POSTGRES_MOD_PATH)"  \
+	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(POSTGRES_MOD_PATH)" \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-postgres-module \
 		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-postgres-module \
 		cfg-target=/etc/kamailio/ \
+		cfg-prefix=$(CURDIR)/debian/kamailio-postgres-module \
 		doc-dir=share/doc/kamailio-postgres-module
 
 	# install only the unixodbc module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(UNIXODBC_MOD_PATH)"  \
+	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(UNIXODBC_MOD_PATH)" \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-unixodbc-module \
 		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-unixodbc-module \
 		cfg-target=/etc/kamailio/ \
+		cfg-prefix=$(CURDIR)/debian/kamailio-unixodbc-module \
 		doc-dir=share/doc/kamailio-unixodbc-module
 
 	# install only the jabber module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(JABBER_MOD_PATH)"  \
+	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(JABBER_MOD_PATH)" \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-jabber-module \
 		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-jabber-module \
 		cfg-target=/etc/kamailio/ \
+		cfg-prefix=$(CURDIR)/debian/kamailio-jabber-module \
 		doc-dir=share/doc/kamailio-jabber-module
 
 	# install only the cpl module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(CPL_MOD_PATH)"  \
+	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(CPL_MOD_PATH)" \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-cpl-module \
 		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-cpl-module \
 		cfg-target=/etc/kamailio/ \
+		cfg-prefix=$(CURDIR)/debian/kamailio-cpl-module \
 		doc-dir=share/doc/kamailio-cpl-module
 
 	# install only the radius modules
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(RADIUS_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-radius-modules \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-radius-modules \
@@ -232,6 +246,7 @@ install: build
 
 	# install only the presence modules
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(PRESENCE_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-presence-modules \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-presence-modules \
@@ -240,6 +255,7 @@ install: build
 
 	# install only the xmlrpc module
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(XMLRPC_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-xmlrpc-module \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-xmlrpc-module \
@@ -248,6 +264,7 @@ install: build
 
 	# install only the perl modules
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(PERL_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-perl-modules \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-perl-modules \
@@ -256,6 +273,7 @@ install: build
 
 	# install only the snmpstats module
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(SNMPSTATS_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-snmpstats-module \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-snmpstats-module \
@@ -264,6 +282,7 @@ install: build
 
 	# install only the xmpp module
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(XMPP_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-xmpp-module \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-xmpp-module \
@@ -272,6 +291,7 @@ install: build
 
 	# install only the carrierroute module
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(CROUTE_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-carrierroute-module \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-carrierroute-module \
@@ -280,6 +300,7 @@ install: build
 
 	# install only the db_berkeley module
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(BERKELEY_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-berkeley-module \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-berkeley-module \
@@ -288,6 +309,7 @@ install: build
 
 	# install only the ldap modules
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(LDAP_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-ldap-modules \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-ldap-modules \
@@ -296,6 +318,7 @@ install: build
 
 	# install only the utils modules
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(UTILS_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-utils-module \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-utils-module \
@@ -304,6 +327,7 @@ install: build
 
 	# install only the regex modules
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(REGEX_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-regex-modules \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-regex-modules \
@@ -320,15 +344,29 @@ install: build
 
 	# install only the memcached modules
 	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(MEMCACHED_MOD_PATH)"  \
+		modules_s="" modules_k="" \
 		basedir=$(CURDIR)/debian/kamailio-memcached-module \
 		prefix=/usr \
 		cfg-prefix=$(CURDIR)/debian/kamailio-memcached-module \
 		cfg-target=/etc/kamailio/ \
 		doc-dir=share/doc/kamailio-memcached-module
 
+	# eliminate duplicate libs
+	-for p in $(ALL_PACKAGES); do \
+		echo "### Processing duplicate libs for '$$p'"; \
+		for d in $(DUP_LIBS_DIRS); do \
+			test "$$d" != "$(CURDIR)/debian/$$p/usr/lib/kamailio" &&\
+			for r in $$d/lib*; do \
+				echo " removing $$p lib `basename $$r` present also in $$d";\
+				rm -f $(CURDIR)/debian/$$p/usr/lib/kamailio/`basename "$$r"` ; \
+			done ; \
+		done ; \
+	done
+
+
 	# the modules packages all ship an empty /usr/sbin directory, let's clean that up
-	for p in $(ALL_PACKAGES); \
-		do rmdir --ignore-fail-on-non-empty $(CURDIR)/debian/$$p/usr/sbin; done
+	#for p in $(ALL_PACKAGES); \
+	#	do rmdir --ignore-fail-on-non-empty $(CURDIR)/debian/$$p/usr/sbin; done
 
 # This single target is used to build all the packages, all at once, or
 # one at a time. So keep in mind: any options passed to commands here will
@@ -350,7 +388,8 @@ binary-arch: build install
 	dh_compress 
 	dh_fixperms
 	dh_installdeb
-	dh_shlibdeps
+	dh_makeshlibs
+	LD_LIBRARY_PATH="$(CURDIR)/debian/kamailio/usr/lib/kamailio/" dh_shlibdeps
 	dh_gencontrol
 	dh_md5sums
 	dh_builddeb

+ 14 - 0
pkg/kamailio/debian/changelog

@@ -1,3 +1,17 @@
+kamailio (3.0.0-rc3) unstable; urgency=low
+
+  * update to 3.0.0-rc3 from upstream
+  * updated debian/rules to work with the SIP Router style module packaging
+
+ -- Daniel-Constantin Mierla <[email protected]>  Fri, 10 Dec 2009 12:10:02 +0100
+
+kamailio (3.0.0-rc2) unstable; urgency=low
+
+  * update to 3.0.0-rc2 from upstream
+  * updated debian/rules to work with the new style module packaging
+
+ -- Jonas Bergler <[email protected]>  Wed, 18 Nov 2009 12:30:02 +1300
+
 kamailio (1.5.0-svn1) unstable; urgency=low
 
   * increment debian packaging for trunk

+ 32 - 49
pkg/kamailio/debian/control

@@ -3,7 +3,7 @@ Section: net
 Priority: optional
 Maintainer: Debian VoIP Team <[email protected]>
 Uploaders: Kilian Krause <[email protected]>
-Build-Depends: debhelper (>= 5), dpatch, libmysqlclient15-dev, libexpat1-dev, libxml2-dev, libpq-dev, libradiusclient-ng-dev, flex, bison, zlib1g-dev, unixodbc-dev, libxmlrpc-c3-dev, libperl-dev, libsnmp-dev, dpkg-dev (>= 1.13.19), libdb-dev (>= 4.6.19), xsltproc, libconfuse-dev, libldap2-dev, libcurl4-gnutls-dev, python, libpcre3-dev, docbook-xml, libpurple-dev, libmemcache-dev
+Build-Depends: debhelper (>= 5), dpatch, libmysqlclient15-dev, libexpat1-dev, libxml2-dev, libpq-dev, libradiusclient-ng-dev, flex, bison, zlib1g-dev, unixodbc-dev, libxmlrpc-c3-dev, libperl-dev, libsnmp-dev, dpkg-dev (>= 1.13.19), libdb-dev (>= 4.6.19), xsltproc, libconfuse-dev, libldap2-dev, libssl-dev, libcurl4-openssl-dev, python, libpcre3-dev, docbook-xml, libpurple-dev, libmemcache-dev, libreadline5-dev
 Standards-Version: 3.8.0
 Homepage: http://www.kamailio.org/
 Vcs-Svn: svn://svn.debian.org/pkg-voip/kamailio/trunk/
@@ -12,7 +12,7 @@ Vcs-Browser: http://svn.debian.org/wsvn/pkg-voip/kamailio/?op=log
 Package: kamailio
 Architecture: any
 Depends: ${shlibs:Depends}, ${misc:Depends}, adduser
-Suggests: kamailio-mysql-module, kamailio-postgres-module, kamailio-unixodbc-module, kamailio-jabber-module, kamailio-cpl-module, kamailio-radius-modules, kamailio-presence-modules, kamailio-xmlrpc-module, kamailio-perl-modules, kamailio-snmpstats-module, kamailio-xmpp-module, kamailio-carrierroute-module, kamailio-berkeley-module, kamailio-ldap-modules
+Suggests: kamailio-mysql-modules, kamailio-postgres-modules, kamailio-unixodbc-modules, kamailio-tls-modules, kamailio-cpl-modules, kamailio-radius-modules, kamailio-presence-modules, kamailio-xmlrpc-modules, kamailio-perl-modules, kamailio-snmpstats-modules, kamailio-xmpp-modules, kamailio-carrierroute-modules, kamailio-berkeley-modules, kamailio-ldap-modules
 Description: very fast and configurable SIP proxy
  Kamailio is a very fast and flexible SIP (RFC3261)
  proxy server. Written entirely in C, Kamailio can handle thousands calls
@@ -30,20 +30,7 @@ Description: very fast and configurable SIP proxy
  This package contains the main Kamailio binary along with the principal modules
  and support binaries.
 
-Package: kamailio-dbg
-Priority: extra
-Architecture: any
-Depends: kamailio (= ${binary:Version})
-Conflicts: kamailio (<< ${binary:Version})
-Description: very fast and configurable SIP proxy [debug symbols]
- Kamailio is a very fast and flexible SIP (RFC3261)
- proxy server. Written entirely in C, Kamailio can handle thousands calls
- per second even on low-budget hardware.
- .
- This package contains the debugging symbols for the Kamailio binaries and
- modules. You only need to install it if you need to debug Kamailio.
-
-Package: kamailio-mysql-module
+Package: kamailio-mysql-modules
 Architecture: any
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version}), mysql-client
 Description: MySQL database connectivity module for Kamailio
@@ -53,7 +40,7 @@ Description: MySQL database connectivity module for Kamailio
  .
  This package provides the MySQL database driver for Kamailio.
 
-Package: kamailio-postgres-module
+Package: kamailio-postgres-modules
 Architecture: any
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version}), postgresql-client
 Description: PostgreSQL database connectivity module for Kamailio
@@ -63,17 +50,7 @@ Description: PostgreSQL database connectivity module for Kamailio
  .
  This package provides the PostgreSQL database driver for Kamailio.
 
-Package: kamailio-jabber-module
-Architecture: any
-Depends: ${shlibs:Depends}, kamailio (= ${binary:Version})
-Description: Jabber gateway module for Kamailio
- Kamailio is a very fast and flexible SIP (RFC3261)
- proxy server. Written entirely in C, Kamailio can handle thousands calls
- per second even on low-budget hardware.
- .
- This package provides the SIP to Jabber translator module for Kamailio.
-
-Package: kamailio-cpl-module
+Package: kamailio-cpl-modules
 Architecture: any
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version})
 Description: CPL module (CPL interpreter engine) for Kamailio
@@ -96,7 +73,7 @@ Description: radius modules for Kamailio
  authentication, peering, group membership and messages URIs checking
  against a Radius Server.
 
-Package: kamailio-unixodbc-module 
+Package: kamailio-unixodbc-modules
 Architecture: any 
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version})
 Description: unixODBC database connectivity module for Kamailio 
@@ -118,7 +95,7 @@ Description: SIMPLE presence modules for Kamailio
  server and presence user agent for RICH presence, registrar-based presence,
  external triggered presence and XCAP support.
 
-Package: kamailio-xmlrpc-module
+Package: kamailio-xmlrpc-modules
 Architecture: any
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version})
 Description: XMLRPC support for Kamailio's Management Interface
@@ -126,8 +103,8 @@ Description: XMLRPC support for Kamailio's Management Interface
  proxy server. Written entirely in C, Kamailio can handle thousands calls
  per second even on low-budget hardware.
  .
- This package provides the XMLRPC transport implementation for Kamailio's
- Management Interface.
+ This package provides the XMLRPC transport implementations for Kamailio's
+ Management and Control Interface.
 
 Package: kamailio-perl-modules
 Architecture: any
@@ -142,7 +119,7 @@ Description: Perl extensions and database driver for Kamailio
  This package provides an interface for Kamailio to write Perl extensions and
  the perlvdb database driver for Kamailio.
 
-Package: kamailio-snmpstats-module
+Package: kamailio-snmpstats-modules
 Architecture: any
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version}), snmpd
 Description: SNMP AgentX subagent module for Kamailio
@@ -153,7 +130,7 @@ Description: SNMP AgentX subagent module for Kamailio
  This package provides the snmpstats module for Kamailio. This module acts
  as an AgentX subagent which connects to a master agent.
 
-Package: kamailio-xmpp-module
+Package: kamailio-xmpp-modules
 Architecture: any
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version})
 Description: XMPP gateway module for Kamailio
@@ -163,7 +140,7 @@ Description: XMPP gateway module for Kamailio
  .
  This package provides the SIP to XMPP IM translator module for Kamailio.
 
-Package: kamailio-carrierroute-module
+Package: kamailio-carrierroute-modules
 Architecture: any
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version})
 Description: Carrierroute module for Kamailio
@@ -174,7 +151,7 @@ Description: Carrierroute module for Kamailio
  This package provides the carrierroute module for Kamailio, an integrated
  solution for routing, balancing and blacklisting.
 
-Package: kamailio-berkeley-module
+Package: kamailio-berkeley-modules
 Architecture: any
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version}), db4.6-util
 Description: Berkeley Database module for Kamailio
@@ -198,7 +175,7 @@ Description: LDAP modules for Kamailio
  queries from the Kamailio config and storage of SIP account data in an LDAP
  directory.
 
-Package: kamailio-utils-module
+Package: kamailio-utils-modules
 Architecture: any
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version})
 Description: Provides a set utility functions for Kamailio
@@ -209,17 +186,7 @@ Description: Provides a set utility functions for Kamailio
  Provides a set of utility functions for Kamailio, which are not related
  to the server configuration.
 
-Package: kamailio-regex-modules
-Architecture: any
-Depends: ${shlibs:Depends}, kamailio (= ${binary:Version})
-Description: Provides the lcr, diaplan and regex modules
- Kamailio is a very fast and flexible SIP (RFC3261)
- proxy server. Written entirely in C, Kamailio can handle thousands calls
- per second even on low-budget hardware.
- .
- Contains the lcr, diaplan and regex modules that depends on the pcre library.
-
-Package: kamailio-purple-module
+Package: kamailio-purple-modules
 Architecture: any
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version})
 Description: Provides the purple module, a multi-protocol IM gateway
@@ -230,7 +197,7 @@ Description: Provides the purple module, a multi-protocol IM gateway
  This package provides the purple module, a multi-protocol instant
  messaging gateway module.
 
-Package: kamailio-memcached-module
+Package: kamailio-memcached-modules
 Architecture: any
 Depends: ${shlibs:Depends}, kamailio (= ${binary:Version})
 Description: Provides the memcached module, an interface to the memcached server
@@ -240,3 +207,19 @@ Description: Provides the memcached module, an interface to the memcached server
  .
  This package provides the memcached module, an interface to the memcached
  server, a high-performance, distributed memory object caching system.
+
+Package: kamailio-tls-modules
+Architecture: any
+Depends: ${shlibs:Depends}, kamailio (= ${Source-Version})
+Description: contains the TLS kamailio transport module
+ This has been split out of the main kamailio package, so that kamailio will not
+ depend on openssl. This module will enable you to use the TLS transport.
+
+Package: kamailio-nth
+Architecture: any
+Depends: screen, gdb, binutils, gcc, bison, flex, ngrep, tcpdump, iftop, lsof, psmisc, vim, bvi, most, mc, sipsak
+Description: Kamailio - package for "nice to have" installation
+ This is a meta-package for easy installation various useful tools that may be
+ handy on server with Kamailio installed.
+
+

+ 0 - 3
pkg/kamailio/debian/patches/00list

@@ -1,3 +0,0 @@
-10_no_lib64_on_64_bits
-11_always_smp
-

+ 0 - 27
pkg/kamailio/debian/patches/10_no_lib64_on_64_bits.dpatch

@@ -1,27 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 10_no_lib64_on_64_bits.dpatch by  <[email protected]>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Debian uses /usr/lib even for 64bit architectures.
-
-@DPATCH@
-diff -urNad kamailio-1.2.0~/Makefile.defs kamailio-1.2.0/Makefile.defs
---- kamailio-1.2.0~/Makefile.defs	2007-02-24 12:35:45.000000000 +0100
-+++ kamailio-1.2.0/Makefile.defs	2007-02-24 16:26:45.886854110 +0100
-@@ -123,14 +123,12 @@
- bin-dir = sbin/
- 
- ARCH_B= $(shell echo $(ARCH) | sed -e 's/.*64.*/64b/')
--ifeq ($(ARCH_B),64b)
--	LIBDIR ?= lib64
--else
--	LIBDIR ?= lib
-+ifneq ($(ARCH_B),64b)
- 	# assume 32b - it is not really used further
- 	ARCH_B=32b
- endif
- 
-+LIBDIR ?= lib
- lib-dir = $(LIBDIR)/$(MAIN_NAME)
- modules-dir = $(LIBDIR)/$(MAIN_NAME)/modules/
- 

+ 0 - 24
pkg/kamailio/debian/patches/11_always_smp.dpatch

@@ -1,24 +0,0 @@
-#! /bin/sh /usr/share/dpatch/dpatch-run
-## 11_always_smp.dpatch by  <[email protected]>
-##
-## All lines beginning with `## DP:' are a description of the patch.
-## DP: Always build for SMP.
-
-@DPATCH@
-diff -urNad kamailio-1.2.0~/Makefile.defs kamailio-1.2.0/Makefile.defs
---- kamailio-1.2.0~/Makefile.defs	2007-02-24 16:28:43.152825070 +0100
-+++ kamailio-1.2.0/Makefile.defs	2007-02-24 16:28:46.123102964 +0100
-@@ -82,12 +82,7 @@
- 	endif
- endif
- 
--SMP_STR = $(shell uname -v | grep -i "SMP")
--ifeq (,$(SMP_STR))
--	ISSMP=no
--else
--	ISSMP=yes
--endif
-+ISSMP=yes
- 
- OSREL = $(shell uname -r)
- # numerical version (good for comparisons: A.B.C => A*1000000+B*1000+C)

+ 156 - 311
pkg/kamailio/debian/rules

@@ -1,110 +1,115 @@
 #!/usr/bin/make -f
 # Sample debian/rules that uses debhelper.
 # GNU copyright 1997 to 1999 by Joey Hess.
+#
+# $Id$
+#
+# History:
+# --------
+#  2009-07-08  updated for sip-router (andrei)
+#  2009-12-10  updated for kamailio 3.0 (daniel)
 
-DEB_HOST_ARCH ?= $(shell dpkg-architecture -qDEB_HOST_ARCH)
-
-ALL_PACKAGES = kamailio kamailio-mysql-module kamailio-postgres-module \
-	kamailio-jabber-module kamailio-cpl-module kamailio-radius-modules \
-	kamailio-unixodbc-module kamailio-presence-modules kamailio-xmlrpc-module \
-	kamailio-perl-modules kamailio-snmpstats-module kamailio-xmpp-module \
-	kamailio-carrierroute-module kamailio-berkeley-module kamailio-ldap-modules \
-	kamailio-utils-module kamailio-regex-modules kamailio-purple-module \
-	kamailio-memcached-module
-
-DEBVERSION:=$(shell head -n 1 debian/changelog \
-                    | sed -e 's/^[^(]*(\([^)]*\)).*/\1/')
-UPVERSION:=$(shell echo $(DEBVERSION) | sed -e 's/^.*://' -e 's/-[0-9.]*$$//' -e 's/.dfsg$$//')
-
-FILENAME := kamailio_$(UPVERSION).orig.tar.gz
-UPFILENAME := kamailio-$(UPVERSION)-tls_src.tar.gz
-URL := http://kamailio.org/pub/kamailio/$(UPVERSION)/src/kamailio-$(UPVERSION)-tls_src.tar.gz
 
 # Uncomment this to turn on verbose mode.
-# export DH_VERBOSE=1
-
-# Include dpatch rules
-include /usr/share/dpatch/dpatch.make
-
-
-# Do we want the TLS version ?
-# Disabled by default due to license issues, set to non-void to enable
-TLS=
-
-# modules depending on mysql
-MYSQL_MODULES = db_mysql
-# modules depending on postgres
-POSTGRES_MODULES = db_postgres
-# modules depending on unixODBC
-UNIXODBC_MODULES=db_unixodbc
-# jabber module
-JABBER_MODULES = jabber
-# cpl related modules
-CPL_MODULES = cpl-c
-# module depending on radiusclient
-RADIUS_MODULES = auth_radius misc_radius peering
-# presence related modules
-PRESENCE_MODULES = presence presence_xml presence_mwi presence_dialoginfo pua pua_bla pua_mi pua_usrloc pua_xmpp pua_dialoginfo xcap_client rls
-# XMLRPC module
-XMLRPC_MODULES = mi_xmlrpc
-# Perl module
-PERL_MODULES = perl perlvdb
-# SNMPstats module
-SNMPSTATS_MODULES = snmpstats
-# XMPP module
-XMPP_MODULES = xmpp
-# Carrierroute module
-CROUTE_MODULES = carrierroute
-# Berkeley DB module
-BERKELEY_MODULES = db_berkeley
-# LDAP modules
-LDAP_MODULES = ldap h350
-# utils module
-UTILS_MODULES = utils
-# modules depending on libpcre
-REGEX_MODULES = dialplan regex lcr
-# purple module
-PURPLE_MODULES = purple
-# memcached module
-MEMCACHED_MODULES = memcached
-
-ALL_MODULES = $(MYSQL_MODULES) $(POSTGRES_MODULES) $(UNIXODBC_MODULES) $(JABBER_MODULES) $(CPL_MODULES) $(RADIUS_MODULES) $(PRESENCE_MODULES) $(XMLRPC_MODULES) $(PERL_MODULES) $(SNMPSTATS_MODULES) $(XMPP_MODULES) $(CROUTE_MODULES) $(BERKELEY_MODULES) $(LDAP_MODULES) $(UTILS_MODULES) $(REGEX_MODULES) $(PURPLE_MODULES) $(MEMCACHED_MODULES)
-
-# modules not in the "main" package or unstable modules
-EXCLUDED_MODULES = $(ALL_MODULES) pa osp
-
-# the same but with path prepended (needed for modules="...")
-MYSQL_MOD_PATH=$(addprefix modules/, $(MYSQL_MODULES))
-POSTGRES_MOD_PATH=$(addprefix modules/, $(POSTGRES_MODULES))
-UNIXODBC_MOD_PATH=$(addprefix modules/, $(UNIXODBC_MODULES))
-JABBER_MOD_PATH=$(addprefix modules/, $(JABBER_MODULES))
-CPL_MOD_PATH=$(addprefix modules/, $(CPL_MODULES))
-RADIUS_MOD_PATH=$(addprefix modules/, $(RADIUS_MODULES))
-PRESENCE_MOD_PATH=$(addprefix modules/, $(PRESENCE_MODULES))
-XMLRPC_MOD_PATH=$(addprefix modules/, $(XMLRPC_MODULES))
-PERL_MOD_PATH=$(addprefix modules/, $(PERL_MODULES))
-SNMPSTATS_MOD_PATH=$(addprefix modules/, $(SNMPSTATS_MODULES))
-XMPP_MOD_PATH=$(addprefix modules/, $(XMPP_MODULES))
-CROUTE_MOD_PATH=$(addprefix modules/, $(CROUTE_MODULES))
-BERKELEY_MOD_PATH=$(addprefix modules/, $(BERKELEY_MODULES))
-LDAP_MOD_PATH=$(addprefix modules/, $(LDAP_MODULES))
-UTILS_MOD_PATH=$(addprefix modules/, $(UTILS_MODULES))
-REGEX_MOD_PATH=$(addprefix modules/, $(REGEX_MODULES))
-PURPLE_MOD_PATH=$(addprefix modules/, $(PURPLE_MODULES))
-MEMCACHED_MOD_PATH=$(addprefix modules/, $(MEMCACHED_MODULES))
-
-ifeq (cc, $(CC))
-	CC = gcc
-endif
-
-CFLAGS = -Wall -g
-
-ifneq (,$(findstring noopt,$(DEB_BUILD_OPTIONS)))
-        CFLAGS += -O0
-else
-	CFLAGS += -O2
+#export DH_VERBOSE=1
+
+# This is the debhelper compatibility version to use.
+# export DH_COMPAT=4
+#  -- already set in compat
+#  force no striping (always include debug symbols for now)
+export DEB_BUILD_OPTIONS:="$(DEB_BUILD_OPTIONS) nostrip"
+
+# modules not in the "main" kamailio package
+EXCLUDED_MODULES=
+
+# extra modules to skip, because they are not compilable now
+# - regardless if they go to the main kamailio package or to some module package,
+# they will be excluded from compile and install of all
+EXTRA_EXCLUDED_MODULES=seas bdb dbtext oracle pa rls iptrtpproxy
+#EXTRA_EXCLUDED_MODULES=
+
+# possible module directories that can appear in MODULES_SP
+# (only used for deducing a module name)
+MDIRS=modules modules_s modules_k
+
+# modules packaged in separate packages (complete with full modules_* path)
+# with the package name: kamailio-$(module_name)-module
+MODULES_SP=
+
+# module groups that are packaged in seperate packages
+# (with the name kamailio-$(group_name)-modules)
+# Note: the order is important (should be in dependency order, the one
+# on which other depend first)
+PACKAGE_GROUPS=mysql postgres berkeley unixodbc radius presence \
+			   ldap xmlrpc perl utils purple memcached tls \
+			   snmpstats carrierroute xmpp cpl
+
+# directories with possible duplicate libraries (that should be deleted
+# from current module* packages)
+DUP_LIBS_DIRS=$(CURDIR)/debian/kamailio/usr/lib/kamailio \
+			$(CURDIR)/debian/kamailio-db-modules/usr/lib/kamailio
+
+# modules names out of modules sp
+MODULES_SP_NAMES=$(filter-out $(MDIRS),$(subst /, ,$(MODULES_SP)))
+
+# "function" to get package short name out of a dir/module_name
+# it also transforms db_foo into foo
+mod_name=$(subst db_,,$(lastword $(subst /, ,$(1))))
+
+define PACKAGE_GRP_BUILD_template
+	# package all the modules in PACKAGE_GROUPS in separate packages
+	$(foreach grp,$(PACKAGE_GROUPS),\
+		$(MAKE) every-module group_include="k$(grp)"
+	)
+endef
+
+
+define PACKAGE_MODULE_BUILD_template
+	# package all the modules MODULES_SP in separate packages
+	$(foreach mod,$(MODULES_SP),\
+		$(MAKE) modules modules="$(mod)"
+	)
+endef
+
+
+define PACKAGE_GRP_INSTALL_template
+	$(foreach grp,$(PACKAGE_GROUPS),\
+		$(MAKE) install-modules-all group_include="k$(grp)" \
+		basedir=$(CURDIR)/debian/kamailio-$(grp)-modules \
+		cfg_prefix=$(CURDIR)/debian/kamailio-$(grp)-modules \
+		doc-dir=share/doc/kamailio-$(grp)-modules
+		# eliminate duplicate libs
+		-for d in $(DUP_LIBS_DIRS); do \
+			test "$$d" != "$(CURDIR)/debian/kamailio-$(grp)-modules/usr/lib/kamailio" &&\
+			for r in $$d/lib*; do \
+				echo "removing $(grp) lib `basename $$r` present also in $$d";\
+				rm -f $(CURDIR)/debian/kamailio-$(grp)-modules/usr/lib/kamailio/`basename "$$r"` ; \
+			done ; \
+		done
+	)
+endef
+
+
+define PACKAGE_MODULE_INSTALL_template
+	$(foreach mod,$(MODULES_SP),
+		$(MAKE) install-modules-all modules="$(mod)" \
+				modules_s="" modules_k="" \
+				basedir=$(CURDIR)/debian/kamailio-$(call mod_name,$(mod))-module \
+				doc-dir=share/doc/kamailio-$(call mod_name,$(mod))-module
+		# eliminate duplicate libs
+		-for d in $(DUP_LIBS_DIRS); do \
+			test "$$d" != "$(CURDIR)/debian/kamailio-$(call mod_name,$(mod))-module/usr/lib/kamailio" &&\
+			for r in $$d/lib*; do \
+				echo "removing $(call mod_name, $(mod)) lib `basename $$r` present also in $$d";\
+				rm -f $(CURDIR)/debian/kamailio-$(call mod_name,$(mod))-module/usr/lib/kamailio/`basename "$$r"` ; \
+			done ; \
+		done
+	)
+endef
+
+ifneq (,$(findstring debug,$(DEB_BUILD_OPTIONS)))
+	CFLAGS += -g
 endif
-
 ifeq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS)))
 	INSTALL_PROGRAM += -s
 endif
@@ -113,55 +118,33 @@ configure: configure-stamp
 configure-stamp:
 	dh_testdir
 	# Add here commands to configure the package.
+	$(MAKE) cfg prefix=/usr cfg_prefix=$(CURDIR)/debian/kamailio \
+			cfg_target=/etc/kamailio/ \
+			basedir=$(CURDIR)/debian/kamailio \
+			skip_modules="$(EXCLUDED_MODULES) $(EXTRA_EXCLUDED_MODULES)" \
+			group_include="kstandard"
 
 	touch configure-stamp
 
 
 build: build-stamp
-build-stamp: patch-stamp configure-stamp 
-	dh_testdir
 
+build-stamp: configure-stamp 
+	dh_testdir
 	# Add here commands to compile the package.
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) all skip_modules="$(EXCLUDED_MODULES)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(MYSQL_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(POSTGRES_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(UNIXODBC_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(JABBER_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(CPL_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(RADIUS_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(PRESENCE_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(XMLRPC_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(PERL_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(SNMPSTATS_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(XMPP_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(CROUTE_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(BERKELEY_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(LDAP_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(UTILS_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(REGEX_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(PURPLE_MOD_PATH)" cfg-target=/etc/kamailio/
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) modules modules="$(MEMCACHED_MOD_PATH)" cfg-target=/etc/kamailio/
-
-	# generate the utils db_berkeley
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) utils include_modules="db_berkeley"
-
-	# generate the man pages for modules
-	$(MAKE) modules-docbook-man include_modules="$(ALL_MODULES)"
-
+	$(MAKE) all
+	# make groups
+	$(call PACKAGE_GRP_BUILD_template)
+	# make single-module packages
+	$(call PACKAGE_MODULE_BUILD_template)
 	touch build-stamp
 
-clean: real-clean unpatch
-real-clean:
+clean:
 	dh_testdir
 	dh_testroot
 	rm -f build-stamp configure-stamp
-
 	# Add here commands to clean up after the build process.
-	$(MAKE) TLS=$(TLS) include_modules="$(ALL_MODULES)" proper
-	rm -f cfg.tab.h
-	rm -f utils/kamunix/kamunix.o utils/kamunix/kamunix
-	rm -f utils/db_berkeley/kambdb_recover.o utils/db_berkeley/kambdb_recover
-
+	-$(MAKE) maintainer-clean
 	dh_clean
 
 install: build
@@ -169,188 +152,49 @@ install: build
 	dh_testroot
 	dh_clean -k
 	dh_installdirs
-
 	# Add here commands to install the package into debian/kamailio
-	# kamailio base package
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install skip_modules="$(EXCLUDED_MODULES)" \
-		basedir=$(CURDIR)/debian/kamailio \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio
-
-	find $(CURDIR)/debian/kamailio/etc/kamailio -type f -exec chmod -x {} \;
-	sed -i -e "s/^PATH.*//" $(CURDIR)/debian/kamailio/usr/sbin/kamctl
-
-	# install only the mysql module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(MYSQL_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-mysql-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-mysql-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-mysql-module
-
-	# install only the postgres module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(POSTGRES_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-postgres-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-postgres-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-postgres-module
-
-	# install only the unixodbc module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(UNIXODBC_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-unixodbc-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-unixodbc-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-unixodbc-module
-
-	# install only the jabber module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(JABBER_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-jabber-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-jabber-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-jabber-module
-
-	# install only the cpl module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(CPL_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-cpl-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-cpl-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-cpl-module
-
-	# install only the radius modules
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(RADIUS_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-radius-modules \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-radius-modules \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-radius-modules
-
-	# install only the presence modules
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(PRESENCE_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-presence-modules \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-presence-modules \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-presence-modules
-
-	# install only the xmlrpc module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(XMLRPC_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-xmlrpc-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-xmlrpc-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-xmlrpc-module
-
-	# install only the perl modules
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(PERL_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-perl-modules \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-perl-modules \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-perl-modules
-
-	# install only the snmpstats module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(SNMPSTATS_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-snmpstats-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-snmpstats-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-snmpstats-module
-
-	# install only the xmpp module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(XMPP_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-xmpp-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-xmpp-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-xmpp-module
-
-	# install only the carrierroute module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(CROUTE_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-carrierroute-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-carrierroute-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-carrierroute-module
-
-	# install only the db_berkeley module
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(BERKELEY_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-berkeley-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-berkeley-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-berkeley-module
-
-	# install only the ldap modules
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(LDAP_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-ldap-modules \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-ldap-modules \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-ldap-modules
-
-	# install only the utils modules
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(UTILS_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-utils-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-utils-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-utils-module
-
-	# install only the regex modules
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(REGEX_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-regex-modules \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-regex-modules \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-regex-modules
-
-	# install only the purple modules
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(PURPLE_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-purple-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-purple-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-purple-module
-
-	# install only the memcached modules
-	CC="$(CC)" CFLAGS="$(CFLAGS)" TLS=$(TLS) $(MAKE) install-modules-all modules="$(MEMCACHED_MOD_PATH)"  \
-		basedir=$(CURDIR)/debian/kamailio-memcached-module \
-		prefix=/usr \
-		cfg-prefix=$(CURDIR)/debian/kamailio-memcached-module \
-		cfg-target=/etc/kamailio/ \
-		doc-dir=share/doc/kamailio-memcached-module
-
-
-	# the modules packages all ship an empty /usr/sbin directory, let's clean that up
-	for p in $(ALL_PACKAGES); \
-		do rmdir --ignore-fail-on-non-empty $(CURDIR)/debian/$$p/usr/sbin; done
+	$(MAKE) install group_include="kstandard"
+	# fix etc/kamailio dir location -- not needed -- andrei
+	# mv -f $(CURDIR)/debian/kamailio/usr/etc $(CURDIR)/debian/kamailio
+	# make group packages
+	$(call PACKAGE_GRP_INSTALL_template)
+	# make single module packages
+	$(call PACKAGE_MODULE_INSTALL_template)
+	# install /etc/default/kamailio file
+	mkdir -p $(CURDIR)/debian/kamailio/etc/default
+	cp -f debian/kamailio.default $(CURDIR)/debian/kamailio/etc/default/kamailio
+	#dh_movefiles
+
+
 
 # This single target is used to build all the packages, all at once, or
 # one at a time. So keep in mind: any options passed to commands here will
 # affect _all_ packages. Anything you want to only affect one package
 # should be put in another target, such as the install target.
-binary-arch: build install
+binary-common: 
 	dh_testdir
 	dh_testroot
+	dh_installdebconf	
 	dh_installdocs
-	dh_installexamples --exclude=".svn"
+	dh_installexamples
+	dh_installmenu
 #	dh_installlogrotate
-	dh_installinit -pkamailio -- defaults 23
+#	dh_installemacsen
+#	dh_installpam
+#	dh_installmime
+	dh_installinit  -- defaults 23
 	dh_installcron
 	dh_installman
 	dh_installinfo
-	dh_installchangelogs
+#	dh_undocumented
+	dh_installchangelogs 
 	dh_link
-	dh_strip --dbg-package=kamailio-dbg
+	dh_strip
 	dh_compress 
 	dh_fixperms
+	dh_makeshlibs
 	dh_installdeb
+#	dh_perl
 	dh_shlibdeps
 	dh_gencontrol
 	dh_md5sums
@@ -358,18 +202,19 @@ binary-arch: build install
 
 # Build architecture-independent packages using the common target
 binary-indep: build install
+# (Uncomment this next line if you have such packages.)
+#        $(MAKE) -f debian/rules DH_OPTIONS=-i binary-common
 # We have nothing to do by default.
 
-binary: binary-indep binary-arch
 
-print-version:
-	@@echo "Debian version:          $(DEBVERSION)"
-	@@echo "Upstream version:        $(UPVERSION)"
+# Build architecture-dependent packages using the common target
+binary-arch: build install
+	$(MAKE) -f debian/rules DH_OPTIONS=-a binary-common
 
-get-orig-source:
-	@@dh_testdir
-	@@[ -d ../tarballs/. ]||mkdir -p ../tarballs
-	@@echo Downloading $(FILENAME) from $(URL) ...
-	@@wget -N -nv -T10 -t3 -O ../tarballs/$(FILENAME) $(URL)
+# Any other binary targets build just one binary package at a time.
+binary-%: build install
+	$(MAKE) -f debian/rules binary-common DH_OPTIONS=-p$*
+
+binary: binary-indep binary-arch
+.PHONY: build clean binary-indep binary-arch binary install configure
 
-.PHONY: build clean binary-indep binary-arch binary install configure patch unpatch real-clean

+ 1 - 0
socket_info.c

@@ -363,6 +363,7 @@ static int fix_sock_str(struct socket_info* si)
 		return -1;
 	}
 	si->sock_str.s[len] = '\0';
+	si->sock_str.len = len;
 	return 0;
 }
 

+ 5 - 1
sr_module.c

@@ -899,6 +899,10 @@ int init_modules(void)
 	struct sr_module* t;
 	int i;
 	
+	i = init_mod(modules);
+	if(i!=0)
+		return i;
+
 	for(t = modules; t; t = t->next)
 		if (t->exports){
 			switch(t->mod_interface_ver){
@@ -938,7 +942,7 @@ int init_modules(void)
 		}
 	}
 	
-	return init_mod(modules);
+	return 0;
 }
 
 #endif

+ 4 - 14
sr_module.h

@@ -389,6 +389,10 @@ int init_child(int rank);
 int init_modules(void);
 struct sr_module* find_module_by_name(char* mod);
 
+/* true if the module with name 'mod_name' is loaded */
+#define module_loaded(mod_name) (find_module_by_name(mod_name)!=0)
+
+
 /*! \brief
  * Find a parameter with given type and return it's
  * address in memory
@@ -520,18 +524,4 @@ int get_int_fparam(int* dst, struct sip_msg* msg, fparam_t* param);
 int get_regex_fparam(regex_t *dst, struct sip_msg* msg, fparam_t* param);
 
 
-/* functions needed for kamailio/openser compatibility */
-
-/*! \brief Check if module is loaded
- * \return Returns 1 if the module with name 'name' is loaded, and zero otherwise. */
-int module_loaded(char *name);
-
-/*! \brief Counts the additional the number of processes
- requested by modules */
-int count_module_procs(void);
-
-
-/*! \brief Forks and starts the additional processes required by modules */
-int start_module_procs(void);
-
 #endif /* sr_module_h */

+ 11 - 3
utils/kamctl/Makefile

@@ -1,6 +1,12 @@
 # $Id$
 COREPATH=../..
 include $(COREPATH)/Makefile.defs
+include $(COREPATH)/config.mak
+
+all:
+		@echo "No compilation needed for kamctl"
+
+install-if-newer: install
 
 install: install-cfg install-bin install-man install-modules
 
@@ -81,7 +87,7 @@ install-man: $(man_prefix)/$(man_dir)/man8 $(man_prefix)/$(man_dir)/man5
 		chmod 644  $(man_prefix)/$(man_dir)/man8/kamdbctl.8
 
 
-MYSQLON?=yes
+# MYSQLON?=yes
 
 install-modules: $(bin_prefix)/$(bin_dir)
 		# install MySQL stuff
@@ -175,7 +181,8 @@ install-modules: $(bin_prefix)/$(bin_dir)
 					$(data_prefix)/$(data_dir)/oracle/admin/`basename "$$FILE"` ; \
 				fi ;\
 			done ; \
-			$(INSTALL_BIN) utils/db_oracle/kamailio_orasel $(bin-prefix)/$(bin-dir) ; \
+			make -C ../db_oracle/ ; \
+			$(INSTALL_BIN) ../db_oracle/kamailio_orasel $(bin_prefix)/$(bin_dir) ; \
 		fi
 		# install Berkeley database stuff
 		if [ "$(BERKELEYDBON)" = "yes" ]; then \
@@ -199,7 +206,8 @@ install-modules: $(bin_prefix)/$(bin_dir)
 					$(data_prefix)/$(data_dir)/db_berkeley/kamailio/`basename "$$FILE"` ; \
 				fi ;\
 			done ; \
-			$(INSTALL_BIN) utils/db_berkeley/kambdb_recover $(bin-prefix)/$(bin-dir) ; \
+			make -C ../db_berkeley/ ; \
+			$(INSTALL_BIN) ../db_berkeley/kambdb_recover $(bin_prefix)/$(bin_dir) ; \
 		fi
 		# install dbtext stuff
 		if [ "$(DBTEXTON)" = "yes" ]; then \

+ 2 - 2
utils/kamctl/db_berkeley/kamailio/dialog

@@ -1,5 +1,5 @@
 METADATA_COLUMNS
-id(int) hash_entry(int) hash_id(int) callid(str) from_uri(str) from_tag(str) to_uri(str) to_tag(str) caller_cseq(str) callee_cseq(str) caller_route_set(str) callee_route_set(str) caller_contact(str) callee_contact(str) caller_sock(str) callee_sock(str) state(int) start_time(int) timeout(int) sflags(int) toroute(int)
+id(int) hash_entry(int) hash_id(int) callid(str) from_uri(str) from_tag(str) to_uri(str) to_tag(str) caller_cseq(str) callee_cseq(str) caller_route_set(str) callee_route_set(str) caller_contact(str) callee_contact(str) caller_sock(str) callee_sock(str) state(int) start_time(int) timeout(int) sflags(int) toroute(int) req_uri(str)
 METADATA_KEY
 1 2 
 METADATA_READONLY
@@ -7,4 +7,4 @@ METADATA_READONLY
 METADATA_LOGFLAGS
 0
 METADATA_DEFAULTS
-NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|0|0|0
+NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|NIL|0|0|0|NIL

+ 12 - 4
utils/kamctl/db_berkeley/kamailio/version

@@ -16,10 +16,10 @@ address|
 address|3
 aliases|
 aliases|1004
-carrierfailureroute|
-carrierfailureroute|2
 carrier_name|
 carrier_name|1
+carrierfailureroute|
+carrierfailureroute|2
 carrierroute|
 carrierroute|3
 cpl|
@@ -27,7 +27,7 @@ cpl|1
 dbaliases|
 dbaliases|1
 dialog|
-dialog|3
+dialog|4
 dialplan|
 dialplan|1
 dispatcher|
@@ -38,6 +38,14 @@ domain_name|
 domain_name|1
 domainpolicy|
 domainpolicy|2
+dr_gateways|
+dr_gateways|3
+dr_groups|
+dr_groups|2
+dr_gw_lists|
+dr_gw_lists|1
+dr_rules|
+dr_rules|3
 globalblacklist|
 globalblacklist|1
 grp|
@@ -79,7 +87,7 @@ speed_dial|2
 subscriber|
 subscriber|6
 trusted|
-trusted|4
+trusted|5
 uri|
 uri|1
 userblacklist|

+ 1 - 1
utils/kamctl/dbtext/kamailio/dialog

@@ -1 +1 @@
-id(int,auto) hash_entry(int) hash_id(int) callid(string) from_uri(string) from_tag(string) to_uri(string) to_tag(string) caller_cseq(string) callee_cseq(string) caller_route_set(string,null) callee_route_set(string,null) caller_contact(string) callee_contact(string) caller_sock(string) callee_sock(string) state(int) start_time(int) timeout(int) sflags(int) toroute(int) 
+id(int,auto) hash_entry(int) hash_id(int) callid(string) from_uri(string) from_tag(string) to_uri(string) to_tag(string) caller_cseq(string) callee_cseq(string) caller_route_set(string,null) callee_route_set(string,null) caller_contact(string) callee_contact(string) caller_sock(string) callee_sock(string) state(int) start_time(int) timeout(int) sflags(int) toroute(int) req_uri(string) 

+ 7 - 3
utils/kamctl/dbtext/kamailio/version

@@ -3,17 +3,21 @@ acc:4
 active_watchers:9
 address:3
 aliases:1004
-carrierfailureroute:2
 carrier_name:1
+carrierfailureroute:2
 carrierroute:3
 cpl:1
 dbaliases:1
-dialog:3
+dialog:4
 dialplan:1
 dispatcher:3
 domain:1
 domain_name:1
 domainpolicy:2
+dr_gateways:3
+dr_groups:2
+dr_gw_lists:1
+dr_rules:3
 globalblacklist:1
 grp:2
 gw:10
@@ -34,7 +38,7 @@ silo:5
 sip_trace:2
 speed_dial:2
 subscriber:6
-trusted:4
+trusted:5
 uri:1
 userblacklist:1
 usr_preferences:2

+ 2 - 5
utils/kamctl/kamctl

@@ -866,11 +866,8 @@ $AVP_USER_COLUMN='$OSERUSER' AND $AVP_DOMAIN_COLUMN='$OSERDOMAIN'"
 cisco_restart() {
 	require_ctlengine
 	myhost=`get_my_host`
-	RET=`$CTLCMD t_uac_dlg NOTIFY "$1" "." \
-		"From: sip:daemon@$myhost" \
-		"To: <$1>" "Event: check-sync" \
-		"Contact: <sip:daemon@!!>" "." "." |
-		head -1 `
+	CMD="t_uac_dlg NOTIFY $1 . . \"From:sip:daemon@$myhost\r\nTo:<$1>\r\nEvent:check-sync\r\nContact:sip:daemon@$myhost\r\n\""
+	RET=`$CTLCMD $CMD | head -1`
 	print_status $RET
 }
 

+ 3 - 2
utils/kamctl/mysql/dialog-create.sql

@@ -1,4 +1,4 @@
-INSERT INTO version (table_name, table_version) values ('dialog','3');
+INSERT INTO version (table_name, table_version) values ('dialog','4');
 CREATE TABLE dialog (
     id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
     hash_entry INT(10) UNSIGNED NOT NULL,
@@ -20,7 +20,8 @@ CREATE TABLE dialog (
     start_time INT(10) UNSIGNED NOT NULL,
     timeout INT(10) UNSIGNED DEFAULT 0 NOT NULL,
     sflags INT(10) UNSIGNED DEFAULT 0 NOT NULL,
-    toroute INT(10) UNSIGNED DEFAULT 0 NOT NULL
+    toroute INT(10) UNSIGNED DEFAULT 0 NOT NULL,
+    req_uri VARCHAR(128) NOT NULL
 ) ENGINE=MyISAM;
 
 CREATE INDEX hash_idx ON dialog (hash_entry, hash_id);

+ 39 - 0
utils/kamctl/mysql/drouting-create.sql

@@ -0,0 +1,39 @@
+INSERT INTO version (table_name, table_version) values ('dr_gateways','3');
+CREATE TABLE dr_gateways (
+    gwid INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
+    type INT(11) UNSIGNED DEFAULT 0 NOT NULL,
+    address VARCHAR(128) NOT NULL,
+    strip INT(11) UNSIGNED DEFAULT 0 NOT NULL,
+    pri_prefix VARCHAR(64) DEFAULT NULL,
+    attrs VARCHAR(255) DEFAULT NULL,
+    description VARCHAR(128) DEFAULT '' NOT NULL
+) ENGINE=MyISAM;
+
+INSERT INTO version (table_name, table_version) values ('dr_rules','3');
+CREATE TABLE dr_rules (
+    ruleid INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
+    groupid VARCHAR(255) NOT NULL,
+    prefix VARCHAR(64) NOT NULL,
+    timerec VARCHAR(255) NOT NULL,
+    priority INT(11) DEFAULT 0 NOT NULL,
+    routeid VARCHAR(64) NOT NULL,
+    gwlist VARCHAR(255) NOT NULL,
+    description VARCHAR(128) DEFAULT '' NOT NULL
+) ENGINE=MyISAM;
+
+INSERT INTO version (table_name, table_version) values ('dr_gw_lists','1');
+CREATE TABLE dr_gw_lists (
+    id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
+    gwlist VARCHAR(255) NOT NULL,
+    description VARCHAR(128) DEFAULT '' NOT NULL
+) ENGINE=MyISAM;
+
+INSERT INTO version (table_name, table_version) values ('dr_groups','2');
+CREATE TABLE dr_groups (
+    id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
+    username VARCHAR(64) NOT NULL,
+    domain VARCHAR(128) DEFAULT '' NOT NULL,
+    groupid INT(11) UNSIGNED DEFAULT 0 NOT NULL,
+    description VARCHAR(128) DEFAULT '' NOT NULL
+) ENGINE=MyISAM;
+

+ 2 - 1
utils/kamctl/mysql/lcr-create.sql

@@ -14,7 +14,8 @@ CREATE TABLE gw (
     weight INT UNSIGNED,
     flags INT UNSIGNED DEFAULT 0 NOT NULL,
     defunct INT UNSIGNED DEFAULT NULL,
-    CONSTRAINT lcr_id_gw_name_idx UNIQUE (lcr_id, gw_name)
+    CONSTRAINT lcr_id_grp_id_gw_name_idx UNIQUE (lcr_id, grp_id, gw_name),
+    CONSTRAINT lcr_id_grp_id_ip_addr_idx UNIQUE (lcr_id, grp_id, ip_addr)
 ) ENGINE=MyISAM;
 
 INSERT INTO version (table_name, table_version) values ('lcr','3');

+ 2 - 2
utils/kamctl/mysql/permissions-create.sql

@@ -1,10 +1,10 @@
-INSERT INTO version (table_name, table_version) values ('trusted','4');
+INSERT INTO version (table_name, table_version) values ('trusted','5');
 CREATE TABLE trusted (
     id INT(10) UNSIGNED AUTO_INCREMENT PRIMARY KEY NOT NULL,
     src_ip VARCHAR(50) NOT NULL,
     proto VARCHAR(4) NOT NULL,
     from_pattern VARCHAR(64) DEFAULT NULL,
-    tag VARCHAR(32)
+    tag VARCHAR(64)
 ) ENGINE=MyISAM;
 
 CREATE INDEX peer_idx ON trusted (src_ip);

Some files were not shown because too many files changed in this diff