Browse Source

Merge remote branch 'origin/sr_3.0'

latest sr_3.0 fixes, after kamailio 3.0 release.

* origin/sr_3.0: (58 commits)
  Backport of the changes (see previous commits).
  kex: documented missing functions
  kex: aliased avp_printf to pv_printf
  auth_diameter(k): remove redundant declaration of find_credentials, now in core
  - fix bug in encode_contact()
  - fix bug when RURI was changed before and newuri will be used
  - remove unused code
  modules_k/nathelper: removed garbage from documentation (credits to Klaus)
  modules_k/nathelper:  improved handle_ruri_alias() documentation
  modules/lcr and modules_k/nathelper: fixed compiler warnings
  modules_k/nathelper: handle_uri_alias() alias handling fix
  modules_k/usrloc: changed 'Kamailio' to 'SIP Router' in user agent string.
  tm: safer handling for local transactions and drop_replies!=0
  sctp: stats: don't increment ASSOC_SHUTDOWN on COMM_LOST
  sctp: SCTP_STATS_ASSOC_SHUTDOWN
  tm doc: local_ack_mode documentation
  tm: new param: local_ack_mode
  makefile: fix make bin &  basedir
  core: fix parsing for avps with the same name as a pv class
  tls: name the certificates based on $MAIN_NAME
  ...

Conflicts:
	modules/tm/README
	modules_k/nathelper/rtpproxy_stream.c
	pkg/debian/rules
Andrei Pelinescu-Onciul 15 years ago
parent
commit
fd47b28cea
100 changed files with 1976 additions and 827 deletions
  1. 48 7
      Makefile
  2. 2 1
      Makefile.defs
  3. 31 0
      Makefile.modules
  4. 0 25
      Makefile.rules
  5. 34 30
      cfg.y
  6. 4 4
      config.h
  7. 94 10
      core_cmd.c
  8. 3 1
      lvalue.c
  9. 6 6
      main.c
  10. 3 2
      mod_fix.c
  11. 1 0
      modules/ctl/init_socks.h
  12. 3 10
      modules/lcr/lcr_mod.c
  13. 1 1
      modules/tls/Makefile
  14. 12 10
      modules/tls/sip-router_cert.sh
  15. 403 164
      modules/tm/README
  16. 9 1
      modules/tm/config.c
  17. 1 0
      modules/tm/config.h
  18. 47 0
      modules/tm/doc/params.xml
  19. 36 20
      modules/tm/t_msgbuilder.c
  20. 30 13
      modules/tm/t_reply.c
  21. 1 0
      modules/tm/tm.c
  22. 2 1
      modules_k/dialog/dlg_handlers.c
  23. 1 1
      modules_k/dialog/dlg_req_within.c
  24. 2 1
      modules_k/dialog/dlg_transfer.c
  25. 2 1
      modules_k/dispatcher/dispatch.c
  26. 1 1
      modules_k/imc/imc_cmd.c
  27. 2 1
      modules_k/jabber/xjab_worker.c
  28. 77 0
      modules_k/kex/README
  29. 100 0
      modules_k/kex/doc/kex_admin.xml
  30. 2 0
      modules_k/kex/kex_mod.c
  31. 2 0
      modules_k/msilo/msilo.c
  32. 414 325
      modules_k/nathelper/README
  33. 19 0
      modules_k/nathelper/doc/nathelper.xml
  34. 129 4
      modules_k/nathelper/doc/nathelper_admin.xml
  35. 305 1
      modules_k/nathelper/nathelper.c
  36. 2 2
      modules_k/nathelper/rtpproxy_stream.c
  37. 3 4
      modules_k/presence/notify.c
  38. 4 4
      modules_k/pua/pua.c
  39. 2 2
      modules_k/pua/send_publish.c
  40. 4 4
      modules_k/pua/send_subscribe.c
  41. 3 3
      modules_k/pv/pv_trans.c
  42. 105 125
      modules_k/registrar/README
  43. 0 25
      modules_k/registrar/doc/registrar_admin.xml
  44. 3 1
      modules_k/registrar/reg_mod.c
  45. 2 2
      modules_k/rls/notify.c
  46. 1 1
      modules_k/usrloc/ul_mi.c
  47. 7 6
      modules_k/xlog/README
  48. 11 6
      modules_k/xlog/doc/xlog_admin.xml
  49. 2 1
      modules_k/xlog/xlog.c
  50. 0 0
      obsolete/pa/ChangeLog
  51. 0 0
      obsolete/pa/Makefile
  52. 0 0
      obsolete/pa/README
  53. 0 0
      obsolete/pa/async_auth.c
  54. 0 0
      obsolete/pa/async_auth.h
  55. 0 0
      obsolete/pa/auth.c
  56. 0 0
      obsolete/pa/auth.h
  57. 0 0
      obsolete/pa/dlist.c
  58. 0 0
      obsolete/pa/dlist.h
  59. 0 0
      obsolete/pa/doc/Makefile
  60. 0 0
      obsolete/pa/doc/auth.xml
  61. 0 0
      obsolete/pa/doc/functions.xml
  62. 0 0
      obsolete/pa/doc/pa.xml
  63. 0 0
      obsolete/pa/doc/pa_base.xml
  64. 0 0
      obsolete/pa/doc/pa_db_src.xml
  65. 0 0
      obsolete/pa/doc/pa_incl.xml
  66. 0 0
      obsolete/pa/doc/params.xml
  67. 0 0
      obsolete/pa/doc/xcap.xml
  68. 0 0
      obsolete/pa/extension_elements.c
  69. 0 0
      obsolete/pa/extension_elements.h
  70. 0 0
      obsolete/pa/hslot.c
  71. 0 0
      obsolete/pa/hslot.h
  72. 0 0
      obsolete/pa/message.c
  73. 0 0
      obsolete/pa/message.h
  74. 0 0
      obsolete/pa/mimetypes.c
  75. 0 0
      obsolete/pa/mimetypes.h
  76. 0 0
      obsolete/pa/notify.c
  77. 0 0
      obsolete/pa/notify.h
  78. 0 0
      obsolete/pa/offline_winfo.c
  79. 0 0
      obsolete/pa/offline_winfo.h
  80. 0 0
      obsolete/pa/pa_mod.c
  81. 0 0
      obsolete/pa/pa_mod.h
  82. 0 0
      obsolete/pa/paerrno.c
  83. 0 0
      obsolete/pa/paerrno.h
  84. 0 0
      obsolete/pa/pdomain.c
  85. 0 0
      obsolete/pa/pdomain.h
  86. 0 0
      obsolete/pa/pres_notes.c
  87. 0 0
      obsolete/pa/pres_notes.h
  88. 0 0
      obsolete/pa/pres_timer.c
  89. 0 0
      obsolete/pa/presentity.c
  90. 0 0
      obsolete/pa/presentity.h
  91. 0 0
      obsolete/pa/ptime.c
  92. 0 0
      obsolete/pa/ptime.h
  93. 0 0
      obsolete/pa/publish.c
  94. 0 0
      obsolete/pa/publish.h
  95. 0 0
      obsolete/pa/qsa_interface.c
  96. 0 0
      obsolete/pa/qsa_interface.h
  97. 0 0
      obsolete/pa/reply.c
  98. 0 0
      obsolete/pa/reply.h
  99. 0 0
      obsolete/pa/rpc.c
  100. 0 0
      obsolete/pa/rpc.h

+ 48 - 7
Makefile

@@ -156,7 +156,7 @@ module_group_standard_dep=acc_db acc_radius auth_db auth_radius avp_db \
 				presence_b2b rls speeddial uri_db xcap xmlrpc
 
 # For db use (db modules, excluding drivers)
-module_group_db=acc_db auth_db avp_db db_ops db_flatstore db_text \
+module_group_db=acc_db auth_db avp_db db_ops db_text \
 				uri_db domain lcr msilo speeddial
 				#dbtext (s) not migrated yet to the new db interface
 
@@ -172,7 +172,14 @@ module_group_postgres=$(module_group_postgres_driver) $(module_group_db)
 module_group_radius=acc_radius auth_radius misc_radius peering
 
 # For presence
-module_group_presence=dialog pa presence_b2b rls xcap
+# kamailio modules
+module_group_presence=presence presence_dialoginfo presence_mwi presence_xml \
+						pua pua_bla pua_dialoginfo pua_mi pua_usrloc pua_xmpp \
+						rls xcap_client
+#ser modules
+module_group_presence+=dialog presence_b2b xcap
+# obsolete/unmaintained ser modules
+#module_group_presence=pa rls
 
 # Modules in this group satisfy specific or niche applications, but are 
 # considered stable for production use. They may or may not have dependencies
@@ -198,13 +205,13 @@ else
 	# excluded because they depend on external libraries
 	exclude_modules?= 		cpl mangler postgres jabber mysql cpl-c \
 							auth_radius misc_radius \
-							acc_radius dialog pa rls presence_b2b xcap xmlrpc\
+							acc_radius pa rls presence_b2b xcap xmlrpc\
 							osp tls oracle \
 							unixsock dbg print_lib auth_identity ldap \
 							db_berkeley db_mysql db_postgres db_oracle \
 							db_unixodbc memcached mi_xmlrpc \
-							nat_traversal perl perlvdb purple seas siptrace \
-							snmpstats uac_redirect xmpp \
+							perl perlvdb purple seas \
+							snmpstats xmpp \
 							carrierroute misc_radius peering \
 							dialplan lcr utils presence \
 							presence_dialoginfo presence_xml pua pua_bla \
@@ -250,6 +257,7 @@ ifeq ($(makefile_defs),1)
 ifeq ($(quiet),verbose)
 $(info config.mak loaded)
 endif # verbose
+export makefile_defs
 # config_make valid & used
 config_mak=1
 ifeq ($(MAIN_NAME),)
@@ -271,6 +279,7 @@ else
 # config.mak not strictly needed, but try to load it if exists for $(Q)
 config_mak=skip
 -include config.mak
+export makefile_defs
 endif
 endif
 
@@ -419,6 +428,15 @@ ifeq ($(config_mak),1)
 
 include Makefile.cfg
 
+# fix basedir path (relative -> absolute)
+ifneq (,$(basedir))
+ifeq (,$(filter /%, $(basedir)))
+override basedir:=$(CURDIR)/$(basedir)
+# remove basedir from command line overrides
+MAKEOVERRIDES:=$(filter-out basedir=%,$ $(MAKEOVERRIDES))
+endif # (,$(filter /%, $(basedir)))
+endif # (,$(basedir))
+
 else ifneq ($(config_mak),skip)
 
 config.mak: Makefile.defs
@@ -711,7 +729,7 @@ tar: $(auto_gen_keep)
 .PHONY: bin
 bin:
 	mkdir -p tmp/$(MAIN_NAME)/usr/local
-	$(MAKE) install basedir=tmp/$(MAIN_NAME) $(mk_params)
+	$(MAKE) install basedir=$(CURDIR)/tmp/$(MAIN_NAME) $(mk_params)
 	$(TAR) -C tmp/$(MAIN_NAME)/ -zcf ../$(NAME)-$(RELEASE)_$(OS)_$(ARCH).tar.gz .
 	rm -rf tmp/$(MAIN_NAME)
 
@@ -729,7 +747,8 @@ deb:
 sunpkg:
 	mkdir -p tmp/$(MAIN_NAME)
 	mkdir -p tmp/$(MAIN_NAME)_sun_pkg
-	$(MAKE) install basedir=tmp/$(MAIN_NAME) prefix=/usr/local $(mk_params)
+	$(MAKE) install basedir=$(CURDIR)/tmp/$(MAIN_NAME) \
+			prefix=/usr/local $(mk_params)
 	(cd pkg/solaris; \
 	pkgmk -r ../../tmp/$(MAIN_NAME)/usr/local -o -d ../../tmp/$(MAIN_NAME)_sun_pkg/ -v "$(RELEASE)" ;\
 	cd ../..)
@@ -953,6 +972,28 @@ clean-libs:
 proper-libs realclean-libs distclean-libs maintainer-clean-libs:
 			$(MAKE) -C lib $(patsubst %-libs,%,$@)
 
+# utils cleaning targets
+
+.PHONY: clean-utils
+clean-utils:
+	@for r in $(C_COMPILE_UTILS) $(C_INSTALL_UTILS) "" ; do \
+		if [ -d "$$r" ]; then \
+			 $(MAKE) -C "$$r" clean ; \
+		fi ; \
+	done
+
+.PHONY: proper-utils
+.PHONY: distclean-utils
+.PHONY: realclean-utils
+.PHONY: maintainer-clean-utils
+proper-utils realclean-utils distclean-utils maintainer-clean-utils: \
+ clean_target=$(patsubst %-utils,%,$@)
+proper-utils realclean-utils distclean-utils maintainer-clean-utils:
+	@for r in $(C_COMPILE_UTILS) $(C_INSTALL_UTILS) "" ; do \
+		if [ -d "$$r" ]; then \
+			 $(MAKE) -C "$$r" $(clean_target); \
+		fi ; \
+	done
 
 # clean extra binary names (common "flavour" names)
 clean: clean-extra-names

+ 2 - 1
Makefile.defs

@@ -671,7 +671,8 @@ ifeq ($(CC_NAME), gcc)
 						fi)
 		ASPATH:=$(shell  if [ -z "$(ASGCC)" ] ; then echo "as" ;\
 						else \
-						if $(ASGCC) -V 2>/dev/null 1>/dev/null; then \
+						if $(ASGCC) -V 2>/dev/null 1>/dev/null </dev/null; \
+						then \
 							echo $(ASGCC); \
 						else echo "as" ; \
 						fi\

+ 31 - 0
Makefile.modules

@@ -139,14 +139,45 @@ install-libs:
 
 endif # $(SER_LIBS)
 
+.PHONY: utils
+.PHONY: clean-utils
+.PHONY: proper-utils
+.PHONY: distclean-utils
+.PHONY: realclean-utils
+.PHONY: maintainer-clean-utils
 ifneq (,$(MOD_INSTALL_UTILS))
 install-utils:
 	@for ut in $(MOD_INSTALL_UTILS) ; do \
 		$(call try_err, $(MAKE) -C "$${ut}" install-if-newer ) ;\
 	done; true
 
+utils:
+	@for r in $(MOD_INSTALL_UTILS) ; do \
+		$(call try_err, $(MAKE) -C "$$r" ) ;\
+	done; true
+
+clean-utils:
+	@for r in $(MOD_INSTALL_UTILS) ; do \
+		if [ -d "$$r" ]; then \
+			 $(MAKE) -C "$$r" clean ; \
+		fi ; \
+	done
+
+proper-utils realclean-utils distclean-utils maintainer-clean-utils: \
+ clean_target=$(patsubst %-utils,%,$@)
+proper-utils realclean-utils distclean-utils maintainer-clean-utils:
+	@for r in $(MOD_INSTALL_UTILS) ; do \
+		if [ -d "$$r" ]; then \
+			 $(MAKE) -C "$$r" $(clean_target); \
+		fi ; \
+	done
+
 else
+# ! MOD_INSTALL_UTILS
 install-utils:
+utils:
+clean-utils:
+proper-utils realclean-utils distclean-utils maintainer-clean-utils:
 
 endif # $(MOD_INSTALL_UTILS)
 

+ 0 - 25
Makefile.rules

@@ -218,16 +218,6 @@ clean-modules:
 		fi ; \
 	done
 
-.PHONY: clean-utils
-clean-utils:
-	@if [ -n "$(cmodules)" ]; then \
-		for r in $(utils_compile) "" ; do \
-			if [ -d "$$r" ]; then \
-				 $(MAKE) -C "$$r" clean ; \
-			fi ; \
-		done \
-	fi
-
 # make proper for the local directory
 .PHONY: proper
 .PHONY: distclean
@@ -253,21 +243,6 @@ proper-modules realclean-modules distclean-modules maintainer-clean-modules:
 		fi ; \
 	done
 
-.PHONY: proper-utils
-.PHONY: distclean-utils
-.PHONY: realclean-utils
-.PHONY: maintainer-clean-utils
-proper-utils realclean-utils distclean-utils maintainer-clean-utils: \
- clean_target=$(patsubst %-utils,%,$@)
-proper-utils realclean-utils distclean-utils maintainer-clean-utils:
-	@if [ -n "$(cmodules)" ]; then \
-		for r in $(utils_compile) "" ; do \
-			if [ -d "$$r" ]; then \
-				 $(MAKE) -C "$$r" $(clean_target); \
-			fi ; \
-		done \
-	fi
-
 .PHONY: clean-tmp
 clean-tmp:
 	-@rm -f TAGS tags *.dbg .*.swp

+ 34 - 30
cfg.y

@@ -540,7 +540,7 @@ extern char *finame;
 %left GT LT GTE LTE
 %left PLUS MINUS
 %left STAR SLASH MODULO
-%right NOT
+%right NOT UNARY
 %right DEFINED
 %right INTCAST STRCAST
 %left DOT
@@ -730,7 +730,7 @@ id_lst:
 	;
 
 intno: NUMBER
-	|  MINUS %prec NOT NUMBER { $$=-$2; }
+	|  MINUS NUMBER %prec UNARY { $$=-$2; }
 	;
 
 flags_decl:		FLAGS_DECL	flag_list
@@ -1840,41 +1840,41 @@ eip_op:		SRCIP		{ $$=SRCIP_O; }
 
 
 exp_elem:
-	METHOD strop %prec EQUAL_T rval_expr
+	METHOD strop rval_expr %prec EQUAL_T
 		{$$= mk_elem($2, METHOD_O, 0, RVE_ST, $3);}
-	| METHOD strop %prec EQUAL_T ID
+	| METHOD strop ID %prec EQUAL_T
 		{$$ = mk_elem($2, METHOD_O, 0, STRING_ST,$3); }
 	| METHOD strop error { $$=0; yyerror("string expected"); }
 	| METHOD error	
 		{ $$=0; yyerror("invalid operator,== , !=, or =~ expected"); }
-	| uri_type strop %prec EQUAL_T rval_expr
+	| uri_type strop rval_expr %prec EQUAL_T
 		{$$ = mk_elem($2, $1, 0, RVE_ST, $3); }
-	| uri_type strop %prec EQUAL_T MYSELF
+	| uri_type strop MYSELF %prec EQUAL_T
 		{$$=mk_elem($2, $1, 0, MYSELF_ST, 0); }
-	| uri_type strop %prec EQUAL_T error
+	| uri_type strop error %prec EQUAL_T
 		{ $$=0; yyerror("string or MYSELF expected"); }
 	| uri_type error
 		{ $$=0; yyerror("invalid operator, == , != or =~ expected"); }
-	| eint_op cmpop %prec GT rval_expr { $$=mk_elem($2, $1, 0, RVE_ST, $3 ); }
-	| eint_op equalop %prec EQUAL_T rval_expr 
+	| eint_op cmpop rval_expr %prec GT { $$=mk_elem($2, $1, 0, RVE_ST, $3 ); }
+	| eint_op equalop rval_expr %prec EQUAL_T
 		{ $$=mk_elem($2, $1, 0, RVE_ST, $3 ); }
 	| eint_op cmpop error   { $$=0; yyerror("number expected"); }
 	| eint_op equalop error { $$=0; yyerror("number expected"); }
 	| eint_op error { $$=0; yyerror("==, !=, <,>, >= or <=  expected"); }
-	| PROTO equalop %prec EQUAL_T proto
+	| PROTO equalop proto %prec EQUAL_T
 		{ $$=mk_elem($2, PROTO_O, 0, NUMBER_ST, (void*)$3 ); }
-	| PROTO equalop %prec EQUAL_T rval_expr
+	| PROTO equalop rval_expr %prec EQUAL_T
 		{ $$=mk_elem($2, PROTO_O, 0, RVE_ST, $3 ); }
 	| PROTO equalop error
 		{ $$=0; yyerror("protocol expected (udp, tcp, tls or sctp)"); }
-	| SNDPROTO equalop %prec EQUAL_T proto
+	| SNDPROTO equalop proto %prec EQUAL_T
 		{ $$=mk_elem($2, SNDPROTO_O, 0, NUMBER_ST, (void*)$3 ); }
-	| SNDPROTO equalop %prec EQUAL_T rval_expr
+	| SNDPROTO equalop rval_expr %prec EQUAL_T
 		{ $$=mk_elem($2, SNDPROTO_O, 0, RVE_ST, $3 ); }
 	| SNDPROTO equalop error
 		{ $$=0; yyerror("protocol expected (udp, tcp, tls or sctp)"); }
-	| eip_op strop %prec EQUAL_T ipnet { $$=mk_elem($2, $1, 0, NET_ST, $3); }
-	| eip_op strop %prec EQUAL_T rval_expr {
+	| eip_op strop ipnet %prec EQUAL_T { $$=mk_elem($2, $1, 0, NET_ST, $3); }
+	| eip_op strop rval_expr %prec EQUAL_T {
 			s_tmp.s=0;
 			$$=0;
 			if (rve_is_constant($3)){
@@ -1912,29 +1912,29 @@ exp_elem:
 				$$=mk_elem($2, $1, 0, RVE_ST, $3);
 			}
 		}
-	| eip_op strop %prec EQUAL_T host
+	| eip_op strop host %prec EQUAL_T
 		{ $$=mk_elem($2, $1, 0, STRING_ST, $3); }
-	| eip_op strop %prec EQUAL_T MYSELF
+	| eip_op strop MYSELF %prec EQUAL_T
 		{ $$=mk_elem($2, $1, 0, MYSELF_ST, 0); }
-	| eip_op strop %prec EQUAL_T error
+	| eip_op strop error %prec EQUAL_T
 		{ $$=0; yyerror( "ip address or hostname expected" ); }
 	| eip_op error
 		{ $$=0; yyerror("invalid operator, ==, != or =~ expected");}
 	
-	| MYSELF equalop %prec EQUAL_T uri_type
+	| MYSELF equalop uri_type %prec EQUAL_T
 		{ $$=mk_elem($2, $3, 0, MYSELF_ST, 0); }
-	| MYSELF equalop %prec EQUAL_T eip_op
+	| MYSELF equalop eip_op %prec EQUAL_T
 		{ $$=mk_elem($2, $3, 0, MYSELF_ST, 0); }
-	| MYSELF equalop %prec EQUAL_T error
+	| MYSELF equalop error %prec EQUAL_T
 		{ $$=0; yyerror(" URI, SRCIP or DSTIP expected"); }
 	| MYSELF error	{ $$=0; yyerror ("invalid operator, == or != expected"); }
 	;
 /*
 exp_elem2:
-	rval_expr cmpop %prec GT rval_expr
+	rval_expr cmpop rval_expr %prec GT
 		{ $$=mk_elem( $2, RVE_ST, $1, RVE_ST, $3);}
 	|
-	rval_expr equalop %prec EQUAL_T rval_expr
+	rval_expr equalop rval_expr %prec EQUAL_T
 		{ $$=mk_elem( $2, RVE_ST, $1, RVE_ST, $3);}
 	| rval_expr LOG_AND rval_expr
 		{ $$=mk_exp_rve(LOGAND_OP, $1, $3);}
@@ -2435,6 +2435,10 @@ avp_pvar:	AVP_OR_PVAR {
 				s_tmp.s=$1; s_tmp.len=strlen(s_tmp.s);
 				if (pv_parse_spec2(&s_tmp, &lval_tmp->lv.pvs, 1)==0){
 					/* not a pvar, try avps */
+					/* lval_tmp might be partially filled by the failed
+					   pv_parse_spec2() (especially if the avp name is the
+					   same as a pv class) => clean it again */
+					memset(lval_tmp, 0, sizeof(*lval_tmp));
 					lval_tmp->lv.avps.type|= AVP_NAME_STR;
 					lval_tmp->lv.avps.name.s.s = s_tmp.s+1;
 					lval_tmp->lv.avps.name.s.len = s_tmp.len-1;
@@ -2527,7 +2531,7 @@ rval: intno			{$$=mk_rve_rval(RV_INT, (void*)$1); }
 
 
 rve_un_op: NOT	{ $$=RVE_LNOT_OP; }
-		|  MINUS %prec NOT	{ $$=RVE_UMINUS_OP; } 
+		|  MINUS %prec UNARY	{ $$=RVE_UMINUS_OP; } 
 		/* TODO: RVE_BOOL_OP, RVE_NOT_OP? */
 	;
 
@@ -2546,7 +2550,7 @@ rval_expr: rval						{ $$=$1;
 											YYERROR;
 										}
 									}
-		| rve_un_op %prec NOT rval_expr	{$$=mk_rve1($1, $2); }
+		| rve_un_op rval_expr %prec UNARY	{$$=mk_rve1($1, $2); }
 		| INTCAST rval_expr				{$$=mk_rve1(RVE_INT_OP, $2); }
 		| STRCAST rval_expr				{$$=mk_rve1(RVE_STR_OP, $2); }
 		| rval_expr PLUS rval_expr		{$$=mk_rve2(RVE_PLUS_OP, $1, $3); }
@@ -2556,8 +2560,8 @@ rval_expr: rval						{ $$=$1;
 		| rval_expr MODULO rval_expr	{$$=mk_rve2(RVE_MOD_OP, $1, $3); }
 		| rval_expr BIN_OR rval_expr	{$$=mk_rve2(RVE_BOR_OP, $1,  $3); }
 		| rval_expr BIN_AND rval_expr	{$$=mk_rve2(RVE_BAND_OP, $1,  $3);}
-		| rval_expr rve_cmpop %prec GT rval_expr { $$=mk_rve2( $2, $1, $3);}
-		| rval_expr rve_equalop %prec EQUAL_T rval_expr
+		| rval_expr rve_cmpop rval_expr %prec GT { $$=mk_rve2( $2, $1, $3);}
+		| rval_expr rve_equalop rval_expr %prec EQUAL_T
 			{ $$=mk_rve2( $2, $1, $3);}
 		| rval_expr LOG_AND rval_expr	{ $$=mk_rve2(RVE_LAND_OP, $1, $3);}
 		| rval_expr LOG_OR rval_expr	{ $$=mk_rve2(RVE_LOR_OP, $1, $3);}
@@ -2565,7 +2569,7 @@ rval_expr: rval						{ $$=$1;
 		| STRLEN LPAREN rval_expr RPAREN { $$=mk_rve1(RVE_STRLEN_OP, $3);}
 		| STREMPTY LPAREN rval_expr RPAREN {$$=mk_rve1(RVE_STREMPTY_OP, $3);}
 		| DEFINED rval_expr				{ $$=mk_rve1(RVE_DEFINED_OP, $2);}
-		| rve_un_op %prec NOT error		{ $$=0; yyerror("bad expression"); }
+		| rve_un_op error %prec UNARY 		{ $$=0; yyerror("bad expression"); }
 		| INTCAST error					{ $$=0; yyerror("bad expression"); }
 		| STRCAST error					{ $$=0; yyerror("bad expression"); }
 		| rval_expr PLUS error			{ $$=0; yyerror("bad expression"); }
@@ -2575,9 +2579,9 @@ rval_expr: rval						{ $$=$1;
 		| rval_expr MODULO error			{ $$=0; yyerror("bad expression"); }
 		| rval_expr BIN_OR error		{ $$=0; yyerror("bad expression"); }
 		| rval_expr BIN_AND error		{ $$=0; yyerror("bad expression"); }
-		| rval_expr rve_cmpop %prec GT error
+		| rval_expr rve_cmpop error %prec GT
 			{ $$=0; yyerror("bad expression"); }
-		| rval_expr rve_equalop %prec EQUAL_T error
+		| rval_expr rve_equalop error %prec EQUAL_T
 			{ $$=0; yyerror("bad expression"); }
 		| rval_expr LOG_AND error		{ $$=0; yyerror("bad expression"); }
 		| rval_expr LOG_OR error		{ $$=0; yyerror("bad expression"); }

+ 4 - 4
config.h

@@ -85,12 +85,12 @@
 #define CONTENT_LENGTH "Content-Length: "
 #define CONTENT_LENGTH_LEN (sizeof(CONTENT_LENGTH)-1)
 
-#define USER_AGENT "User-Agent: SIP Router "\
-		"(" VERSION " (" ARCH "/" OS_QUOTED "))"
+#define USER_AGENT "User-Agent: " NAME \
+		" (" VERSION " (" ARCH "/" OS_QUOTED "))"
 #define USER_AGENT_LEN (sizeof(USER_AGENT)-1)
 
-#define SERVER_HDR "Server: SIP Router "\
-		"(" VERSION " (" ARCH "/" OS_QUOTED "))"
+#define SERVER_HDR "Server: " NAME \
+		" (" VERSION " (" ARCH "/" OS_QUOTED "))"
 #define SERVER_HDR_LEN (sizeof(SERVER_HDR)-1)
 
 #define MAX_WARNING_LEN  256

+ 94 - 10
core_cmd.c

@@ -438,21 +438,54 @@ static void core_shmmem(rpc_t* rpc, void* c)
 {
 	struct mem_info mi;
 	void *handle;
-
+	char* param;
+	long rs;
+
+	rs=0;
+	/* look for optional size/divisor parameter */
+	if (rpc->scan(c, "*s", &param)>0){
+		switch(*param){
+			case 'b':
+			case 'B':
+				rs=0;
+				break;
+			case 'k':
+			case 'K':
+				rs=10; /* K -> 1024 */
+				break;
+			case 'm':
+			case 'M':
+				rs=20; /* M -> 1048576 */
+				break;
+			case 'g':
+			case 'G':
+				rs=30; /* G -> 1024M */
+				break;
+			default:
+				rpc->fault(c, 500, "bad param, (use b|k|m|g)");
+				return;
+		}
+		if (param[1] && ((param[1]!='b' && param[1]!='B') || param[2])){
+				rpc->fault(c, 500, "bad param, (use b|k|m|g)");
+				return;
+		}
+	}
 	shm_info(&mi);
 	rpc->add(c, "{", &handle);
 	rpc->struct_add(handle, "dddddd",
-		"total", (unsigned int)mi.total_size,
-		"free", (unsigned int)mi.free,
-		"used", (unsigned int)mi.used,
-		"real_used",(unsigned int)mi.real_used,
-		"max_used", (unsigned int)mi.max_used,
+		"total", (unsigned int)(mi.total_size>>rs),
+		"free", (unsigned int)(mi.free>>rs),
+		"used", (unsigned int)(mi.used>>rs),
+		"real_used",(unsigned int)(mi.real_used>>rs),
+		"max_used", (unsigned int)(mi.max_used>>rs),
 		"fragments", (unsigned int)mi.total_frags
 	);
 }
 
 static const char* core_shmmem_doc[] = {
-	"Returns shared memory info.",  /* Documentation string */
+	"Returns shared memory info. It has an optional parameter that specifies"
+	" the measuring unit: b - bytes (default), k or kb, m or mb, g or gb. "
+	"Note: when using something different from bytes, the value is truncated.",
 	0                               /* Method signature(s) */
 };
 
@@ -650,7 +683,13 @@ static void core_tcp_options(rpc_t* rpc, void* c)
 
 
 static const char* core_sctp_options_doc[] = {
-	"Returns active sctp options.",    /* Documentation string */
+	"Returns active sctp options. With one parameter"
+	" it returns the sctp options set in the kernel for a specific socket"
+	"(debugging), with 0 filled in for non-kernel related options."
+	" The parameter can be: \"default\" | \"first\" | address[:port] ."
+	" With no parameters it returns ser's idea of the current sctp options"
+	 " (intended non-debugging use).",
+	/* Documentation string */
 	0                                 /* Method signature(s) */
 };
 
@@ -659,9 +698,54 @@ static void core_sctp_options(rpc_t* rpc, void* c)
 #ifdef USE_SCTP
 	void *handle;
 	struct cfg_group_sctp t;
-
+	char* param;
+	struct socket_info* si;
+	char* host;
+	str hs;
+	int hlen;
+	int port;
+	int proto;
+
+	param=0;
 	if (!sctp_disable){
-		sctp_options_get(&t);
+		/* look for optional socket parameter */
+		if (rpc->scan(c, "*s", &param)>0){
+			si=0;
+			if (strcasecmp(param, "default")==0){
+				si=sendipv4_sctp?sendipv4_sctp:sendipv6_sctp;
+			}else if (strcasecmp(param, "first")==0){
+				si=sctp_listen;
+			}else{
+				if (parse_phostport(param, &host, &hlen, &port, &proto)!=0){
+					rpc->fault(c, 500, "bad param (use address, address:port,"
+										" default or first)");
+					return;
+				}
+				if (proto && proto!=PROTO_SCTP){
+					rpc->fault(c, 500, "bad protocol in param (only SCTP"
+										" allowed)");
+					return;
+				}
+				hs.s=host;
+				hs.len=hlen;
+				si=grep_sock_info(&hs, port, PROTO_SCTP);
+				if (si==0){
+					rpc->fault(c, 500, "not listening on sctp %s", param);
+					return;
+				}
+			}
+			if (si==0 || si->socket==-1){
+				rpc->fault(c, 500, "could not find a sctp socket");
+				return;
+			}
+			memset(&t, 0, sizeof(t));
+			if (sctp_get_cfg_from_sock(si->socket, &t)!=0){
+				rpc->fault(c, 500, "failed to get socket options");
+				return;
+			}
+		}else{
+			sctp_options_get(&t);
+		}
 		rpc->add(c, "{", &handle);
 		rpc->struct_add(handle, "ddddddddddddddddddd",
 			"sctp_socket_rcvbuf",	t.so_rcvbuf,

+ 3 - 1
lvalue.c

@@ -384,7 +384,9 @@ int lval_assign(struct run_act_ctx* h, struct sip_msg* msg,
 	ret=0;
 	rv=rval_expr_eval(h, msg, rve);
 	if (unlikely(rv==0)){
-		ERR("rval expression evaluation failed\n");
+		ERR("rval expression evaluation failed (%d,%d-%d,%d)\n",
+				rve->fpos.s_line, rve->fpos.s_col,
+				rve->fpos.e_line, rve->fpos.e_col);
 		goto error;
 	}
 	switch(lv->type){

+ 6 - 6
main.c

@@ -721,19 +721,19 @@ void handle_sigs()
 		case SIGCHLD:
 			while ((chld=waitpid( -1, &chld_status, WNOHANG ))>0) {
 				if (WIFEXITED(chld_status))
-					LOG(L_ALERT, "child process %d exited normally,"
-							" status=%d\n", chld,
+					LOG(L_ALERT, "child process %ld exited normally,"
+							" status=%d\n", (long)chld,
 							WEXITSTATUS(chld_status));
 				else if (WIFSIGNALED(chld_status)) {
-					LOG(L_ALERT, "child process %d exited by a signal"
-							" %d\n", chld, WTERMSIG(chld_status));
+					LOG(L_ALERT, "child process %ld exited by a signal"
+							" %d\n", (long)chld, WTERMSIG(chld_status));
 #ifdef WCOREDUMP
 					LOG(L_ALERT, "core was %sgenerated\n",
 							 WCOREDUMP(chld_status) ?  "" : "not " );
 #endif
 				}else if (WIFSTOPPED(chld_status))
-					LOG(L_ALERT, "child process %d stopped by a"
-								" signal %d\n", chld,
+					LOG(L_ALERT, "child process %ld stopped by a"
+								" signal %d\n", (long)chld,
 								 WSTOPSIG(chld_status));
 			}
 #ifndef STOP_JIRIS_CHANGES

+ 3 - 2
mod_fix.c

@@ -239,7 +239,8 @@ FIXUP_F2FP_T(igp_pvar_pvar, 1, 3, 1, FPARAM_INT|FPARAM_PVS, FPARAM_PVS)
 	}
 
 
+/* format: name, minp, maxp, no_of_spve_params, type_for_rest_params */
 FIXUP_F_SPVE_T(spve_spve, 1, 2, 2, 0)
-FIXUP_F_SPVE_T(spve_uint, 1, 2, 2, FPARAM_INT)
-FIXUP_F_SPVE_T(spve_str, 1, 2, 2, FPARAM_STR)
+FIXUP_F_SPVE_T(spve_uint, 1, 2, 1, FPARAM_INT)
+FIXUP_F_SPVE_T(spve_str, 1, 2, 1, FPARAM_STR)
 FIXUP_F_SPVE_T(spve_null, 1, 1, 1, 0)

+ 1 - 0
modules/ctl/init_socks.h

@@ -31,6 +31,7 @@
 
 #ifndef _init_socks_h
 #define _init_socks_h
+#include <sys/types.h>
 #include <sys/un.h>
 #include "../../ip_addr.h"
 

+ 3 - 10
modules/lcr/lcr_mod.c

@@ -2068,16 +2068,9 @@ static int next_gw(struct sip_msg* _m, char* _s1, char* _s2)
          * failure route block => append new branch. */
 	uri_str.s = r_uri;
 	uri_str.len = r_uri_len;
-	memset(&act, '\0', sizeof(act));
-	act.type = APPEND_BRANCH_T;
-	act.val[0].type = STRING_ST;
-	act.val[0].u.str = uri_str;
-	act.val[1].type = NUMBER_ST;
-	act.val[1].u.number = 0;
-	init_run_actions_ctx(&ra_ctx);
-	rval = do_action(&ra_ctx, &act, _m);
-	if (rval != 1) {
-	    LM_ERR("do_action failed with return value <%d>\n", rval);
+	LM_DBG("appending branch <%.*s>\n", uri_str.len, uri_str.s);
+	if (append_branch(_m, &uri_str, 0, 0, Q_UNSPECIFIED, 0, 0) == -1) {
+	    LM_ERR("when appending branch <%.*s>\n", uri_str.len, uri_str.s);
 	    return -1;
 	}
     }

+ 1 - 1
modules/tls/Makefile

@@ -23,6 +23,6 @@ include ../../Makefile.modules
 
 
 install-tls-cert: $(cfg_prefix)/$(cfg_dir)
-	./$(SCR_NAME)_cert.sh -d $(cfg_prefix)/$(cfg_dir)
+	MAIN_NAME=$(MAIN_NAME) ./$(SCR_NAME)_cert.sh -d $(cfg_prefix)/$(cfg_dir)
 
 install-cfg:  install-tls-cert

+ 12 - 10
modules/tls/sip-router_cert.sh

@@ -3,18 +3,20 @@
 # $Id$
 #
 # This script generates a self-signed TLS/SSL certificate that can be
-# immediately used with the TLS module of SER. The file was inspired
+# immediately used with the TLS module of SIP Router. The file was inspired
 # by a script from Debian's uw-imapd package.
 #
 
 #############################################################################
 # Configuration variables
 #############################################################################
-DEFAULT_DIR="/usr/local/etc/ser"
+NAME=$MAIN_NAME
+if [ -z "$NAME" ] ; then NAME="sip-router"; fi;
+DEFAULT_DIR="/usr/local/etc/$NAME"
 DEFAULT_DAYS=365
-DEFAULT_INFO="Self-signed certificate for SER"
-DEFAULT_CERT_FILENAME="ser-selfsigned.pem"
-DEFAULT_KEY_FILENAME="ser-selfsigned.key"
+DEFAULT_INFO="Self-signed certificate for $NAME"
+DEFAULT_CERT_FILENAME="$NAME-selfsigned.pem"
+DEFAULT_KEY_FILENAME="$NAME-selfsigned.key"
 
 DEFAULT_OPENSSL='openssl'
 
@@ -50,19 +52,19 @@ longopts() {
 usage() {
 cat <<EOF
 NAME
-  $COMMAND - Generate a self-signed TLS/SSL certificate for use with SER.
+  $COMMAND - Generate a self-signed TLS/SSL certificate for use with $NAME.
 
 SYNOPSIS
   $COMMAND [options]
 
 DESCRIPTION
   This is a simple shell script that generates a self signed TLS/SSL
-  certificate (and private key) for use with the tls module of SER. The
+  certificate (and private key) for use with the tls module of $NAME. The
   self-signed certificate is suitable for testing and/or private setups.
   You are encouraged to create a proper authorized one if needed.
 
   Both certificate and key files are by default stored in the directory
-  containing the configuration file of SER (unless you change it using
+  containing the configuration file of $NAME (unless you change it using
   the options below).
 
 OPTIONS
@@ -100,7 +102,7 @@ AUTHOR
   Written by Jan Janak <[email protected]>
 
 REPORTING BUGS
-  Report bugs to <ser-bugs@iptel.org>
+  Report bugs to <sr-dev@sip-router.org>
 EOF
 } #usage
 
@@ -175,7 +177,7 @@ if [ $? != 0 ] ; then
 	exit 1
 fi
 
-echo "Creating a new SER self-signed certificate for '$FQDN'" \
+echo "Creating a new $NAME self-signed certificate for '$FQDN'" \
      "valid for $DAYS days."
 openssl req -new -x509 -days "$DAYS" -nodes -out "$DIR/$CERT_FILENAME" \
         -keyout "$DIR/$KEY_FILENAME" > /dev/null 2>&1 <<+

File diff suppressed because it is too large
+ 403 - 164
modules/tm/README


+ 9 - 1
modules/tm/config.c

@@ -93,7 +93,8 @@ struct cfg_group_tm	default_tm_cfg = {
 			 * for every method except BYE by default */
 	1,	/* cancel_b_method used for e2e and 6xx cancels*/
 	1,	/* reparse_on_dns_failover */
-	0 /* disable_6xx, by default off */
+	0, /* disable_6xx, by default off */
+	0  /* local_ack_mode, default 0 (rfc3261 conformant) */
 };
 
 void	*tm_cfg = &default_tm_cfg;
@@ -188,5 +189,12 @@ cfg_def_t	tm_cfg_def[] = {
 		"branch instead of from the received request"},
 	{"disable_6xx_block",	CFG_VAR_INT | CFG_ATOMIC,	0, 1, 0, 0,
 		"if set to 1, 6xx is treated like a normal reply (breaks rfc)"},
+	{"local_ack_mode",		CFG_VAR_INT | CFG_ATOMIC,	0, 2, 0, 0,
+		"if set to 1 or 2, local 200 ACKs are sent to the same address as the"
+		" corresponding INVITE (1) or the source of the 200 reply (2) instead"
+		" of using the contact and the route set (it breaks the rfc, if "
+		" it is not set to 0 but allows dealing with NATed contacts in some "
+		"simple cases)"
+		},
 	{0, 0, 0, 0, 0, 0}
 };

+ 1 - 0
modules/tm/config.h

@@ -135,6 +135,7 @@ struct cfg_group_tm {
 	unsigned int	cancel_b_flags;
 	int	reparse_on_dns_failover;
 	int disable_6xx;
+	int local_ack_mode;
 };
 
 extern struct cfg_group_tm	default_tm_cfg;

+ 47 - 0
modules/tm/doc/params.xml

@@ -1119,4 +1119,51 @@ modparam("tm", "disable_6xx_block", 1)
 	</example>
 	</section>
 
+<section id="local_ack_mode">
+	<title><varname>local_ack_mode</varname> (integer)</title>
+	<para>
+		It controls where locally generated ACKs for 2xx replies to local
+		transactions (transactions created via <function>t_uac*()</function>
+		either thorugh the tm api or via RPC/mi/fifo) are sent.
+	</para>
+	<para> It has 3 possible values:</para>
+	<itemizedlist>
+		<listitem><para>
+		<emphasis>0</emphasis> - the ACK destination is choosen according to
+		the rfc: the next hop is found using the contact and the route set and
+		then DNS resolution is used on it.
+		</para></listitem>
+		<listitem><para>
+		<emphasis>1</emphasis> - the ACK is sent to the same address as the
+		corresponding INVITE branch.
+		</para></listitem>
+		<listitem><para>
+		<emphasis>2</emphasis> - the ACK is sent to the source of the 2xx
+		reply.
+		</para></listitem>
+	</itemizedlist>
+	<note>
+	Mode 1 and 2 break the rfc, but are useful to deal with some simple UAs
+	behind the NAT cases (no different routing for the ACK and the contact 
+	contains an address behind the NAT).
+	</note>
+	<para>
+		The default value is 0 (rfc conformant behaviour).
+	</para>
+	<para>
+		Can be set at runtime, e.g.:
+		<programlisting>
+	$ sercmd cfg.set_now_int tm local_ack_mode 0
+		</programlisting>
+	</para>
+	<example>
+		<title>Set <varname>local_ack_mode</varname> parameter</title>
+		<programlisting>
+...
+modparam("tm", "local_ack_mode", 1)
+...
+	    </programlisting>
+	</example>
+	</section>
+
 </section>

+ 36 - 20
modules/tm/t_msgbuilder.c

@@ -982,33 +982,49 @@ char *build_dlg_ack(struct sip_msg* rpl, struct cell *Trans,
 	*len = SIP_VERSION_LEN + ACK_LEN + 2 /* spaces */ + CRLF_LEN;
 	*len += ruri.len;
 	
-	
-	 /* via */
+	/* dst */
+	switch(cfg_get(tm, tm_cfg, local_ack_mode)){
+		case 1:
+			/* send the local 200 ack to the same dst as the corresp. invite*/
+			*dst=Trans->uac[branch].request.dst;
+			break;
+		case 2: 
+			/* send the local 200 ack to the same dst as the 200 reply source*/
+			init_dst_from_rcv(dst, &rpl->rcv);
+			dst->send_flags=rpl->fwd_send_flags;
+			break;
+		case 0:
+		default:
+			/* rfc conformant behaviour: use the next_hop determined from the
+			   contact and the route set */
 #ifdef USE_DNS_FAILOVER
-	if (cfg_get(core, core_cfg, use_dns_failover)){
-		dns_srv_handle_init(&dns_h);
-		if ((uri2dst(&dns_h , dst, rpl, &next_hop, PROTO_NONE)==0) ||
-				(dst->send_sock==0)){
-			dns_srv_handle_put(&dns_h);
-			LOG(L_ERR, "build_dlg_ack: no socket found\n");
-			goto error;
+		if (cfg_get(core, core_cfg, use_dns_failover)){
+			dns_srv_handle_init(&dns_h);
+			if ((uri2dst(&dns_h , dst, rpl, &next_hop, PROTO_NONE)==0) ||
+					(dst->send_sock==0)){
+				dns_srv_handle_put(&dns_h);
+				LOG(L_ERR, "build_dlg_ack: no socket found\n");
+				goto error;
+			}
+			dns_srv_handle_put(&dns_h); /* not needed any more */
+		}else{
+			if ((uri2dst(0 , dst, rpl, &next_hop, PROTO_NONE)==0) ||
+					(dst->send_sock==0)){
+				LOG(L_ERR, "build_dlg_ack: no socket found\n");
+				goto error;
+			}
 		}
-		dns_srv_handle_put(&dns_h); /* not needed any more */
-	}else{
-		if ((uri2dst(0 , dst, rpl, &next_hop, PROTO_NONE)==0) ||
+#else /* USE_DNS_FAILOVER */
+		if ( (uri2dst( dst, rpl, &next_hop, PROTO_NONE)==0) ||
 				(dst->send_sock==0)){
-			LOG(L_ERR, "build_dlg_ack: no socket found\n");
+				LOG(L_ERR, "build_dlg_ack: no socket found\n");
 			goto error;
 		}
+#endif /* USE_DNS_FAILOVER */
+		break;
 	}
-#else
-	if ( (uri2dst( dst, rpl, &next_hop, PROTO_NONE)==0) ||
-			(dst->send_sock==0)){
-			LOG(L_ERR, "build_dlg_ack: no socket found\n");
-		goto error;
-	}
-#endif
 	
+	 /* via */
 	if (!t_calc_branch(Trans,  branch, branch_buf, &branch_len)) goto error;
 	branch_str.s = branch_buf;
 	branch_str.len = branch_len;

+ 30 - 13
modules/tm/t_reply.c

@@ -89,7 +89,9 @@
  * 2008-03-12  use cancel_b_method on 6xx (andrei)
  * 2008-05-30  make sure the wait timer is started after we don't need t
  *             anymore to allow safe calls from fr_timer (andrei)
- * 2009-06-01  Pre- and post-script callbacks of branch route are executed (Miklos)
+ * 2009-06-01  Pre- and post-script callbacks of branch route are 
+ *             executed (Miklos)
+ * 2009-12-10  reply route is executed under lock to protect the avps (andrei)
  *
  */
 
@@ -1246,16 +1248,19 @@ discard:
 
 branches_failed:
 	*should_store=0;
-	*should_relay=-1;
-	/* We have hopefully set tm_error in failure_route when
-	the branches failed. If not, reply with E_UNSPEC */
-	if ((kill_transaction_unsafe(Trans,
-				    tm_error ? tm_error : E_UNSPEC)
-				    ) <=0 ){
-		LOG(L_ERR, "ERROR: t_should_relay_response: "
-			"reply generation failed\n");
+	if (is_local(Trans)){
+		/* for local transactions use the current reply */
+		*should_relay=branch;
+	}else{
+		*should_relay=-1;
+		/* We have hopefully set tm_error in failure_route when
+			the branches failed. If not, reply with E_UNSPEC */
+		if ((kill_transaction_unsafe(Trans,
+				tm_error ? tm_error : E_UNSPEC)) <=0 ){
+			LOG(L_ERR, "ERROR: t_should_relay_response: "
+						"reply generation failed\n");
+		}
 	}
-	
 	return RPS_COMPLETED;
 }
 
@@ -1800,7 +1805,7 @@ error:
 	prepare_to_cancel(t, cancel_bitmap, 0);
 	UNLOCK_REPLIES(t);
 	cleanup_uac_timers(t);
-	if ( get_cseq(p_msg)->method.len==INVITE_LEN
+	if (p_msg && p_msg!=FAKED_REPLY && get_cseq(p_msg)->method.len==INVITE_LEN
 		&& memcmp( get_cseq(p_msg)->method.s, INVITE, INVITE_LEN)==0)
 		cancel_uacs( t, *cancel_bitmap, F_CANCEL_B_KILL);
 	*cancel_bitmap=0; /* we've already took care of everything */
@@ -1834,6 +1839,7 @@ int reply_received( struct sip_msg  *p_msg )
 	avp_list_t* backup_user_from, *backup_user_to;
 	avp_list_t* backup_domain_from, *backup_domain_to;
 	avp_list_t* backup_uri_from, *backup_uri_to;
+	int replies_locked;
 #ifdef USE_DNS_FAILOVER
 	int branch_ret;
 	int prev_branch;
@@ -1860,6 +1866,7 @@ int reply_received( struct sip_msg  *p_msg )
 	tm_ctx_set_branch_index(branch);
 	cancel_bitmap=0;
 	msg_status=p_msg->REPLY_STATUS;
+	replies_locked=0;
 
 	uac=&t->uac[branch];
 	DBG("DEBUG: reply_received: org. status uas=%d, "
@@ -1984,6 +1991,9 @@ int reply_received( struct sip_msg  *p_msg )
 		/* Pre- and post-script callbacks have already
 		 * been executed by the core. (Miklos)
 		 */
+		/* 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");
 		/* transfer current message context back to t */
@@ -2035,15 +2045,22 @@ int reply_received( struct sip_msg  *p_msg )
 		 *  reply lock is held (the lock won't be held while sending the
 		 *   message)*/
 		if (cfg_get(core, core_cfg, use_dns_failover) && (msg_status==503)) {
-			branch_ret=add_uac_dns_fallback(t, t->uas.request, uac, 1);
+			branch_ret=add_uac_dns_fallback(t, t->uas.request,
+												uac, !replies_locked);
 			prev_branch=-1;
+			/* unlock replies to avoid sending() while holding a lock */
+			if (unlikely(replies_locked)) {
+				UNLOCK_REPLIES( t );
+				replies_locked = 0;
+			}
 			while((branch_ret>=0) &&(branch_ret!=prev_branch)){
 				prev_branch=branch_ret;
 				branch_ret=t_send_branch(t, branch_ret, t->uas.request , 0, 1);
 			}
 		}
 #endif
-	LOCK_REPLIES( t );
+	if (unlikely(!replies_locked))
+		LOCK_REPLIES( t );
 	if ( is_local(t) ) {
 		reply_status=local_reply( t, p_msg, branch, msg_status, &cancel_bitmap );
 		if (reply_status == RPS_COMPLETED) {

+ 1 - 0
modules/tm/tm.c

@@ -517,6 +517,7 @@ static param_export_t params[]={
 	{"on_sl_reply",         PARAM_STRING|PARAM_USE_FUNC, fixup_on_sl_reply   },
 	{"contacts_avp",        PARAM_STRING, &contacts_avp_param                },
 	{"disable_6xx_block",   PARAM_INT, &default_tm_cfg.disable_6xx           },
+	{"local_ack_mode",      PARAM_INT, &default_tm_cfg.local_ack_mode        },
 	{0,0,0}
 };
 

+ 2 - 1
modules_k/dialog/dlg_handlers.c

@@ -967,13 +967,14 @@ void dlg_ontimeout( struct dlg_tl *tl)
 	if(dlg->toroute>0 && dlg->toroute<main_rt.entries
 			&& main_rt.rlist[dlg->toroute]!=NULL)
 	{
-		dlg_set_ctx_dialog(dlg);
 		fmsg = faked_msg_next();
 		if (exec_pre_script_cb(fmsg, REQUEST_CB_TYPE)>0)
 		{
+			dlg_set_ctx_dialog(dlg);
 			LM_DBG("executing route %d on timeout\n", dlg->toroute);
 			set_route_type(REQUEST_ROUTE);
 			run_top_route(main_rt.rlist[dlg->toroute], fmsg, 0);
+			dlg_set_ctx_dialog(0);
 			exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
 		}
 	}

+ 1 - 1
modules_k/dialog/dlg_req_within.c

@@ -252,7 +252,7 @@ static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs)
 	ref_dlg(cell, 1);
 
 	memset(&uac_r,'\0', sizeof(uac_req_t));
-	set_uac_req(&uac_r, &met, hdrs, NULL, dialog_info, 0,
+	set_uac_req(&uac_r, &met, hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED,
 				bye_reply_cb, (void*)cell);
 	result = d_tmb.t_request_within(&uac_r);
 

+ 2 - 1
modules_k/dialog/dlg_transfer.c

@@ -160,7 +160,7 @@ static int dlg_refer_callee(dlg_transfer_ctx_t *dtc)
 			CRLF, CRLF_LEN);
 
 	memset(&uac_r, '\0', sizeof(uac_req_t));
-	set_uac_req(&uac_r, &met, &hdrs, NULL, dialog_info, 0,
+	set_uac_req(&uac_r, &met, &hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED,
 				dlg_refer_tm_callback, (void*)dtc);
 	result = d_tmb.t_request_within(&uac_r);
 
@@ -320,6 +320,7 @@ int dlg_bridge(str *from, str *to, str *op)
 	uac_r.method = &s_method;
 	uac_r.headers = &s_hdrs;
 	uac_r.body = &s_body;
+	uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
 	uac_r.cb = dlg_bridge_tm_callback;
 	uac_r.cbp = (void*)(long)dtc;
 	ret = d_tmb.t_request(&uac_r, /* UAC Req */

+ 2 - 1
modules_k/dispatcher/dispatch.c

@@ -1653,7 +1653,8 @@ void ds_check_timer(unsigned int ticks, void* param)
 				 * int request(str* m, str* ruri, str* to, str* from, str* h,
 				 *		str* b, str *oburi,
 				 *		transaction_cb cb, void* cbp); */
-				set_uac_req(&uac_r, &ds_ping_method, 0, 0, 0, 0, ds_options_callback,
+				set_uac_req(&uac_r, &ds_ping_method, 0, 0, 0,
+						TMCB_LOCAL_COMPLETED, ds_options_callback,
 							(void*)(long)list->id);
 				if (tmb.t_request(&uac_r,
 							&list->dlist[j].uri,

+ 1 - 1
modules_k/imc/imc_cmd.c

@@ -491,7 +491,7 @@ int imc_handle_invite(struct sip_msg* msg, imc_cmd_t *cmd,
 	cback_param->inv_uri = member->uri;
 	/*?!?! possible race with 'remove user' */
 
-	set_uac_req(&uac_r, &imc_msg_type, &all_hdrs, &body, 0, 0,
+	set_uac_req(&uac_r, &imc_msg_type, &all_hdrs, &body, 0, TMCB_LOCAL_COMPLETED,
 				imc_inv_callback, (void*)(cback_param));
 	result= tmb.t_request(&uac_r,
 				&member->uri,							/* Request-URI */

+ 2 - 1
modules_k/jabber/xjab_worker.c

@@ -1184,7 +1184,8 @@ int xj_send_sip_msg(str *proxy, str *to, str *from, str *msg, int *cbp)
 #ifdef XJ_EXTRA_DEBUG
 		LM_DBG("uac callback parameter [%p==%d]\n", cbp, *cbp);
 #endif
-		set_uac_req(&uac_r, &msg_type, &str_hdr, msg, 0, 0, xj_tuac_callback, (void*)cbp);
+		set_uac_req(&uac_r, &msg_type, &str_hdr, msg, 0, TMCB_LOCAL_COMPLETED,
+				xj_tuac_callback, (void*)cbp);
 	} else {
 		set_uac_req(&uac_r, &msg_type, &str_hdr, msg, 0, 0, 0, 0);		
 	}

+ 77 - 0
modules_k/kex/README

@@ -33,6 +33,10 @@ Daniel-Constantin Mierla
               3.5. isbflagset(flag [, branch])
               3.6. resetsflag(flag [, branch])
               3.7. km_append_branch([uri])
+              3.8. setdsturi(uri)
+              3.9. resetdsturi()
+              3.10. isdsturiset()
+              3.11. pv_printf(var, str)
 
         4. Exported MI Functions
 
@@ -52,6 +56,10 @@ Daniel-Constantin Mierla
    1.5. setbflag usage
    1.6. resetsflag usage
    1.7. km_append_branch usage
+   1.8. >setdsturi usage
+   1.9. >resetdsturi usage
+   1.10. >isdsturiset usage
+   1.11. >pv_printf usage
 
 Chapter 1. Admin Guide
 
@@ -72,6 +80,10 @@ Chapter 1. Admin Guide
         3.5. isbflagset(flag [, branch])
         3.6. resetsflag(flag [, branch])
         3.7. km_append_branch([uri])
+        3.8. setdsturi(uri)
+        3.9. resetdsturi()
+        3.10. isdsturiset()
+        3.11. pv_printf(var, str)
 
    4. Exported MI Functions
 
@@ -113,6 +125,10 @@ Chapter 1. Admin Guide
    3.5. isbflagset(flag [, branch])
    3.6. resetsflag(flag [, branch])
    3.7. km_append_branch([uri])
+   3.8. setdsturi(uri)
+   3.9. resetdsturi()
+   3.10. isdsturiset()
+   3.11. pv_printf(var, str)
 
 3.1. setsflag(flag)
 
@@ -243,6 +259,67 @@ km_append_branch();
 km_append_branch("sip:[email protected]");
 ...
 
+3.8. setdsturi(uri)
+
+   Set the destination address URI (outbound proxy address).
+
+   Meaning of the parameters is as follows:
+     * uri - Valid SIP URI representing the address where to send the
+       request. It must be a static string, no variables are evaluated at
+       runtime. If you need to set outbound proxy address via a variable,
+       use assginment to $du.
+
+   This function can be used from ANY_ROUTE.
+
+   Example 1.8. >setdsturi usage
+...
+setdsturi("sip:10.0.0.10");
+...
+
+3.9. resetdsturi()
+
+   Reset the destination address URI (outbound proxy address).
+
+   This function can be used from ANY_ROUTE.
+
+   Example 1.9. >resetdsturi usage
+...
+resetdsturi();
+...
+
+3.10. isdsturiset()
+
+   Check if the destination address URI (outbound proxy address) is set.
+
+   This function can be used from ANY_ROUTE.
+
+   Example 1.10. >isdsturiset usage
+...
+if(isdsturiset())
+{
+   ...
+}
+...
+
+3.11. pv_printf(var, str)
+
+   Evalues the str and sets the resulted value to variable var. For
+   backward compatibility reasons, same function can be executed via
+   'avp_printf(var, str)'.
+
+   Meaning of the parameters is as follows:
+     * var - name of a writable variable
+     * str - string that may contain variables which will be evaluated at
+       runtime.
+
+   This function can be used from ANY_ROUTE.
+
+   Example 1.11. >pv_printf usage
+...
+pv_printf("$ru", "sip:$rU@$fd");
+pv_printf("$avp(x)", "From: $fU - To: $tU");
+...
+
 4. Exported MI Functions
 
    4.1. arg

+ 100 - 0
modules_k/kex/doc/kex_admin.xml

@@ -274,6 +274,106 @@ km_append_branch();
 ...
 km_append_branch("sip:[email protected]");
 ...
+</programlisting>
+		</example>
+		</section>
+		<section>
+		<title><function moreinfo="none">setdsturi(uri)</function></title>
+		<para>
+			Set the destination address URI (outbound proxy address).
+		</para>
+		<para>Meaning of the parameters is as follows:</para>
+		<itemizedlist>
+		<listitem>
+			<para>
+				<emphasis>uri</emphasis> - Valid SIP URI representing the
+				address where to send the request. It must be a static string,
+				no variables are evaluated at runtime. If you need to set
+				outbound proxy address via a variable, use assginment to $du.
+			</para>
+		</listitem>
+		</itemizedlist>
+		<para>
+		This function can be used from ANY_ROUTE.
+		</para>
+		<example>
+		<title><function>>setdsturi</function> usage</title>
+		<programlisting format="linespecific">
+...
+setdsturi("sip:10.0.0.10");
+...
+</programlisting>
+		</example>
+		</section>
+		<section>
+		<title><function moreinfo="none">resetdsturi()</function></title>
+		<para>
+			Reset the destination address URI (outbound proxy address).
+		</para>
+		<para>
+		This function can be used from ANY_ROUTE.
+		</para>
+		<example>
+		<title><function>>resetdsturi</function> usage</title>
+		<programlisting format="linespecific">
+...
+resetdsturi();
+...
+</programlisting>
+		</example>
+		</section>
+		<section>
+		<title><function moreinfo="none">isdsturiset()</function></title>
+		<para>
+			Check if the destination address URI (outbound proxy address)
+			is set.
+		</para>
+		<para>
+		This function can be used from ANY_ROUTE.
+		</para>
+		<example>
+		<title><function>>isdsturiset</function> usage</title>
+		<programlisting format="linespecific">
+...
+if(isdsturiset())
+{
+   ...
+}
+...
+</programlisting>
+		</example>
+		</section>
+		<section>
+		<title><function moreinfo="none">pv_printf(var, str)</function></title>
+		<para>
+			Evalues the str and sets the resulted value to variable var. For
+			backward compatibility reasons, same function can be executed via
+			'avp_printf(var, str)'.
+		</para>
+		<para>Meaning of the parameters is as follows:</para>
+		<itemizedlist>
+		<listitem>
+			<para>
+				<emphasis>var</emphasis> - name of a writable variable
+			</para>
+		</listitem>
+		<listitem>
+			<para>
+				<emphasis>str</emphasis> - string that may contain variables
+				which will be evaluated at runtime.
+			</para>
+		</listitem>
+		</itemizedlist>
+		<para>
+		This function can be used from ANY_ROUTE.
+		</para>
+		<example>
+		<title><function>>pv_printf</function> usage</title>
+		<programlisting format="linespecific">
+...
+pv_printf("$ru", "sip:$rU@$fd");
+pv_printf("$avp(x)", "From: $fU - To: $tU");
+...
 </programlisting>
 		</example>
 		</section>

+ 2 - 0
modules_k/kex/kex_mod.c

@@ -76,6 +76,8 @@ static cmd_export_t cmds[]={
 			0, ANY_ROUTE },
 	{"pv_printf", (cmd_function)w_pv_printf,    2, pv_printf_fixup,
 			0, ANY_ROUTE },
+	{"avp_printf", (cmd_function)w_pv_printf,   2, pv_printf_fixup,
+			0, ANY_ROUTE },
 
 	{0,0,0,0,0,0}
 };

+ 2 - 0
modules_k/msilo/msilo.c

@@ -1060,6 +1060,7 @@ static int m_dump(struct sip_msg* msg, char* owner, char* str2)
 		uac_r.method = &msg_type;
 		uac_r.headers = &hdr_str;
 		uac_r.body = (n<0)?&str_vals[2]:&body_str;
+		uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
 		uac_r.cb  = m_tm_callback;
 		uac_r.cbp = (void*)(long)mid;
 
@@ -1333,6 +1334,7 @@ void m_send_ontimer(unsigned int ticks, void *param)
 		uac_r.method  = &msg_type;
 		uac_r.headers = &hdr_str;
 		uac_r.body = (n<0)?&str_vals[2]:&body_str;
+		uac_r.cb_flags = TMCB_LOCAL_COMPLETED;
 		uac_r.cb  = m_tm_callback;
 		uac_r.cbp = (void*)(long)mid;
 		tmb.t_request(&uac_r,  /* UAC Req */

File diff suppressed because it is too large
+ 414 - 325
modules_k/nathelper/README


+ 19 - 0
modules_k/nathelper/doc/nathelper.xml

@@ -21,6 +21,14 @@
 			<email>[email protected]</email>
 		</address>
 		</author>
+		<author>
+		<firstname>Juha</firstname>
+		<surname>Heinanen</surname>
+		<affiliation><orgname>TuTPro, Inc.</orgname></affiliation>
+		<address>
+			<email>[email protected]</email>
+		</address>
+		</author>
 		<editor>
 		<firstname>Maxim</firstname>
 		<surname>Sobolev</surname>
@@ -35,6 +43,13 @@
 			<email>[email protected]</email>
 		</address>
 		</editor>
+		<editor>
+		<firstname>Juha</firstname>
+		<surname>Heinanen</surname>
+		<address>
+			<email>[email protected]</email>
+		</address>
+		</editor>
 	</authorgroup>
 	<copyright>
 		<year>2003-2008</year>
@@ -44,6 +59,10 @@
 		<year>2005</year>
 		<holder>&voicesystem;</holder>
 	</copyright>
+	<copyright>
+		<year>2009</year>
+		<holder>TuTPro Inc.</holder>
+	</copyright>
 	<revhistory>
 		<revision>
 		<revnumber>$Revision$</revnumber>

+ 129 - 4
modules_k/nathelper/doc/nathelper_admin.xml

@@ -17,13 +17,25 @@
 	<section>
 	<title>Overview</title>
 	<para>
-		This is a module to help with &nat; traversal. In particular, 
+		This is a module to help with &nat; traversal and reuse
+	of tcp connections.  In particular, 
 		it helps symmetric &ua;s that don't advertise they are symmetric 
-		and are not able to determine their public address. fix_nated_contact 
-		rewrites Contact header field with request's source address:port pair. 
-		fix_nated_sdp adds the active direction indication to &sdp; (flag
+		and are not able to determine their public
+	address. 
+	</para>
+	<para>
+	Function fix_nated_contact() 
+		rewrites Contact header field with request's source
+	address:port pair.  
+		Function fix_nated_sdp() adds the active direction
+	indication to &sdp; (flag 
 		0x01) and updates source &ip; address too (flag 0x02).
 	</para>
+	<para>
+	Alternative to fix_nated_contact() is add_contact_alias() that
+	together with handle_ruri_alias() also supports reuse of tcp
+	connections.
+	</para>
 	<para>
 		Known devices that get along over &nat;s with nathelper are ATAs 
 		(as clients) and Cisco Gateways (since 12.2(T)) as servers.  See <ulink
@@ -983,8 +995,121 @@ start_recording();
 		</programlisting>
 		</example>
 	</section>
+
+	<section>
+		<title>
+		<function moreinfo="none">add_contact_alias()</function>
+		</title>
+		<para>
+		Adds ;alias=ip:port parameter to contact URI containing
+		received ip:port if contact uri ip:port does not match
+		received ip:port.
+		</para>
+		<para>
+		This function can be used from
+		REQUEST_ROUTE, ONREPLY_ROUTE, BRANCH_ROUTE, and LOCAL_ROUTE.
+		</para>
+		<example>
+		<title><function>add_contact_alias</function> usage</title>
+		<programlisting format="linespecific">
+...
+    if (!is_present_hf("Record-Route")) {
+        if (!add_contact_alias()) {
+            xlog("L_ERR", "Error in aliasing contact $ct\n");
+            send_reply("400", "Bad request");
+            exit;
+        };
+    };
+...
+		</programlisting>
+		</example>
 	</section>
 
+	<section>
+		<title>
+		<function moreinfo="none">handle_ruri_alias()</function>
+		</title>
+		<para>
+		Checks if Request URI has alias param and if so, removes
+		it and sets $du based on its value.  Note that this
+		means that routing of request is based on alias
+		parameter value of Request URI rather than Request URI
+		itself. If you call handle_ruri_alias() on a request,
+		make thus sure that you screen alias parameter value of
+		Request URI the same way as you would screen
+		Request URI itself.
+		</para>
+		<para>
+		This function can be used from
+		REQUEST_ROUTE, BRANCH_ROUTE, and LOCAL_ROUTE.
+		</para>
+		<example>
+		<title><function>handle_ruri_alias</function> usage</title>
+		<programlisting format="linespecific">
+...
+    if ($du == "") {
+        handle_ruri_alias();
+        switch ($rc) {
+        case -1:
+            xlog("L_ERR", "Failed to handle alias of R-URI $ru\n");
+            send_reply("400", "Bad request");
+            exit;
+        case 1:
+            xlog("L_INFO", "Routing in-dialog $rm from $fu to $du\n");
+            break;
+        case 2:
+            xlog("L_INFO", "Routing in-dialog $rm from $fu to $ru\n");
+            break;
+         };
+    };
+...
+		</programlisting>
+		</example>
+	</section>
+
+	</section>
+
+	<section>
+		<title>Exported Pseudo Variables</title>
+		<section>
+			<title><function moreinfo="none">$rr_count</function></title>
+			<para>
+			Number of Record Routes in received SIP request
+			or reply.
+			</para>
+		<example>
+		<title>$rr_count usage</title>
+		<programlisting format="linespecific">
+...
+    $avp(rr_count) = $rr_count;
+...
+		</programlisting>
+		</example>
+	        </section>
+
+		<section>
+			<title><function moreinfo="none">$rr_top_count</function></title>
+			<para>
+			If topmost Record Route in received SIP request
+			or reply is a double Record Route, value of
+			$rr_top_count is 2.  If it a single Record
+			Route, value of $rr_top_count 
+			is 1.  If there is no Record Route(s), value of
+			$rr_top_count is 0.
+			</para>
+		<example>
+		<title>$rr_top_count usage</title>
+		<programlisting format="linespecific">
+...
+    if ($rr_count == $avp(rr_count) + $rr_top_count) {
+        route(ADD_CONTACT_ALIAS);
+    };
+...
+		</programlisting>
+		</example>
+	        </section>
+
+	</section>
 
 	<section>
 		<title><acronym>MI</acronym> Commands</title>

+ 305 - 1
modules_k/nathelper/nathelper.c

@@ -210,10 +210,12 @@
 #include "../../lib/kcore/km_ut.h"
 #include "../../lib/kcore/parser_helpers.h"
 #include "../../pvar.h"
+#include "../../lvalue.h"
 #include "../../msg_translator.h"
 #include "../../usr_avp.h"
 #include "../../socket_info.h"
 #include "../../mod_fix.h"
+#include "../../dset.h"
 #include "../registrar/sip_msg.h"
 #include "../usrloc/usrloc.h"
 #include "nathelper.h"
@@ -277,6 +279,10 @@ MODULE_VERSION
 #define	CPORT		"22222"
 static int nat_uac_test_f(struct sip_msg* msg, char* str1, char* str2);
 static int fix_nated_contact_f(struct sip_msg *, char *, char *);
+static int add_contact_alias_f(struct sip_msg *, char *, char *);
+static int handle_ruri_alias_f(struct sip_msg *, char *, char *);
+static int pv_get_rr_count_f(struct sip_msg *, pv_param_t *, pv_value_t *);
+static int pv_get_rr_top_count_f(struct sip_msg *, pv_param_t *, pv_value_t *);
 static int fix_nated_sdp_f(struct sip_msg *, char *, char *);
 static int extract_mediaip(str *, str *, int *, char *);
 static int extract_mediainfo(str *, str *, str *);
@@ -406,6 +412,12 @@ static cmd_export_t cmds[] = {
 	{"fix_nated_contact",  (cmd_function)fix_nated_contact_f,    0,
 		0, 0,
 		REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
+	{"add_contact_alias",  (cmd_function)add_contact_alias_f,    0,
+		0, 0,
+		REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
+	{"handle_ruri_alias",  (cmd_function)handle_ruri_alias_f,    0,
+		0, 0,
+		REQUEST_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
 	{"fix_nated_sdp",      (cmd_function)fix_nated_sdp_f,        1,
 		fixup_fix_sdp,  0,
 		REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE|LOCAL_ROUTE},
@@ -475,6 +487,14 @@ static cmd_export_t cmds[] = {
 	{0, 0, 0, 0, 0, 0}
 };
 
+static pv_export_t mod_pvs[] = {
+    {{"rr_count", (sizeof("rr_count")-1)}, /* number of records routes */
+     PVT_CONTEXT, pv_get_rr_count_f, 0, 0, 0, 0, 0},
+    {{"rr_top_count", (sizeof("rr_top_count")-1)}, /* number of topmost rrs */
+     PVT_CONTEXT, pv_get_rr_top_count_f, 0, 0, 0, 0, 0},
+    {{0, 0}, 0, 0, 0, 0, 0, 0, 0}
+};
+
 static param_export_t params[] = {
 	{"natping_interval",      INT_PARAM, &natping_interval      },
 	{"ping_nated_only",       INT_PARAM, &ping_nated_only       },
@@ -509,7 +529,7 @@ struct module_exports exports = {
 	params,
 	0,           /* exported statistics */
 	mi_cmds,     /* exported MI functions */
-	0,           /* exported pseudo-variables */
+	mod_pvs,     /* exported pseudo-variables */
 	0,           /* extra processes */
 	mod_init,
 	0,           /* reply processing */
@@ -1371,6 +1391,290 @@ fix_nated_contact_f(struct sip_msg* msg, char* str1, char* str2)
 }
 
 
+#define SALIAS        ";alias="
+#define SALIAS_LEN (sizeof(SALIAS) - 1)
+
+/*
+ * Adds ;alias=ip:port param to cotact uri containing received ip:port
+ * if contact uri ip:port does not match received ip:port.
+ */
+static int
+add_contact_alias_f(struct sip_msg* msg, char* str1, char* str2)
+{
+    int len, param_len, ip_len;
+    contact_t *c;
+    struct lump *anchor;
+    struct sip_uri uri;
+    struct ip_addr *ip;
+    char *param, *at, *port, *start;
+
+    /* Do nothing if Contact header does not exist */
+    if (!msg->contact) {
+	if (parse_headers(msg, HDR_CONTACT_F, 0) == -1)  {
+	    LM_ERR("while parsing headers\n");
+	    return -1;
+	}
+	if (!msg->contact) {
+	    LM_DBG("no contact header\n");
+	    return 2;
+	}
+    }
+    if (get_contact_uri(msg, &uri, &c) == -1) {
+	LM_ERR("failed to get contact uri\n");
+	return -1;
+    }
+
+    /* Compare source ip and port against contact uri */
+    if ((ip = str2ip(&(uri.host))) == NULL) {
+	LM_ERR("contact uri host is not an ip address\n");
+	return -1;
+    }
+    if (ip_addr_cmp(ip, &(msg->rcv.src_ip)) &&
+	((msg->rcv.src_port == uri.port_no) ||
+	 ((uri.port.len == 0) && (msg->rcv.src_port == 5060)))) {
+	LM_DBG("no need to add alias param\n");
+	return 2;
+    }
+	
+    /* Add alias param */
+    if ((c->uri.s < msg->buf) || (c->uri.s > (msg->buf + msg->len))) {
+	LM_ERR("you can't call alias_contact twice, check your config!\n");
+	return -1;
+    }
+    param_len = SALIAS_LEN + IP6_MAX_STR_SIZE + 1 /* : */ + 5 /* port */ +
+	1 /* t */ + 1 /* proto */;
+    param = (char*)pkg_malloc(param_len);
+    if (!param) {
+	LM_ERR("no pkg memory left for alias param\n");
+	return -1;
+    }
+    at = param;
+    append_str(at, SALIAS, SALIAS_LEN);
+    ip_len = ip_addr2sbuf(&(msg->rcv.src_ip), at, param_len - SALIAS_LEN);
+    if (ip_len <= 0) {
+	pkg_free(param);
+	LM_ERR("failed to copy source ip\n");
+	return -1;
+    }
+    at = at + ip_len;
+    append_chr(at, ':');
+    port = int2str(msg->rcv.src_port, &len);
+    append_str(at, port, len);
+    append_chr(at, 't');
+    if ((msg->rcv.proto < PROTO_UDP) || (msg->rcv.proto > PROTO_SCTP)) {
+	pkg_free(param);
+	LM_ERR("invalid transport protocol\n");
+	return -1;
+    }
+    append_chr(at, msg->rcv.proto + '0');
+    param_len = at - param;
+    LM_DBG("adding param <%.*s>\n", param_len, param);
+    if (uri.port.len > 0) {
+	start = uri.port.s + uri.port.len;
+    } else {
+	start = uri.host.s + uri.host.len;
+    }
+    anchor = anchor_lump(msg, start - msg->buf, 0, 0);
+    if (anchor == NULL) {
+	pkg_free(param);
+	LM_ERR("anchor_lump failed\n");
+	return -1;
+    }
+    if (insert_new_lump_after(anchor, param, param_len, 0) == 0) {
+	LM_ERR("insert_new_lump_after failed\n");
+	pkg_free(param);
+	return -1;
+    }
+    return 1;
+}
+
+
+#define ALIAS        "alias="
+#define ALIAS_LEN (sizeof(ALIAS) - 1)
+
+/*
+ * Checks if r-uri has alias param and if so, removes it and sets $du
+ * based on its value.
+ */
+static int
+handle_ruri_alias_f(struct sip_msg* msg, char* str1, char* str2)
+{
+    str uri, proto;
+    char buf[MAX_URI_SIZE], *val, *sep, *trans, *at, *next, *cur_uri, *rest;
+    unsigned int len, rest_len, val_len, alias_len, proto_type, cur_uri_len,
+	ip_port_len;
+
+    if ((msg->parsed_uri_ok == 0) && (parse_sip_msg_uri(msg) < 0)) {
+	LM_ERR("while parsing Request-URI\n");
+	return -1;
+    }
+    rest = msg->parsed_uri.params.s;
+    rest_len = msg->parsed_uri.params.len;
+    if (rest_len == 0) {
+	LM_DBG("no params\n");
+	return 2;
+    }
+    while (rest_len >= ALIAS_LEN) {
+	if (strncmp(rest, ALIAS, ALIAS_LEN) == 0) break;
+	sep = memchr(rest, 59 /* ; */, rest_len);
+	if (sep == NULL) {
+	    LM_DBG("no alias param\n");
+	    return 2;
+	} else {
+	    rest_len = rest_len - (sep - rest + 1);
+	    rest = sep + 1;
+	}
+    }
+
+    if (rest_len < ALIAS_LEN) {
+	LM_DBG("no alias param\n");
+	return 2;
+    }
+
+    /* set dst uri based on alias param value */
+    val = rest + ALIAS_LEN;
+    val_len = rest_len - ALIAS_LEN;
+    sep = memchr(val, 116 /* t */, val_len);
+    if (sep == NULL) {
+	LM_ERR("no 't' in alias param value\n");
+	return -1;
+    }
+    at = &(buf[0]);
+    append_str(at, "sip:", 4);
+    ip_port_len = sep - val;
+    alias_len = SALIAS_LEN + ip_port_len + 2 /* tn */;
+    memcpy(at, val, ip_port_len);
+    at = at + ip_port_len;
+    trans = sep + 1;
+    if ((ip_port_len + 2 > val_len) || (*trans == ';') || (*trans == '?')) {
+	LM_ERR("no proto in alias param\n");
+	return -1;
+    }
+    proto_type = *trans - 48 /* char 0 */;
+    if (proto_type != PROTO_UDP) {
+	proto_type_to_str(proto_type, &proto);
+	if (proto.len == 0) {
+	    LM_ERR("unknown proto in alias param\n");
+	    return -1;
+	}
+	append_str(at, ";transport=", 11);
+	memcpy(at, proto.s, proto.len);
+	at = at + proto.len;
+    }
+    next = trans + 1;
+    if ((ip_port_len + 2 < val_len) && (*next != ';') && (*next != '?')) {
+	LM_ERR("invalid alias param value\n");
+	return -1;
+    }
+    uri.s = &(buf[0]);
+    uri.len = at - &(buf[0]);
+    LM_DBG("setting dst_uri to <%.*s>\n", uri.len, uri.s);
+    if (set_dst_uri(msg, &uri) == -1) {
+	LM_ERR("failed to set dst uri\n");
+	return -1;
+    }
+    
+    /* remove alias param */
+    if (msg->new_uri.s) {
+	cur_uri = msg->new_uri.s;
+	cur_uri_len = msg->new_uri.len;
+    } else {
+	cur_uri = msg->first_line.u.request.uri.s;
+	cur_uri_len = msg->first_line.u.request.uri.len;
+    }
+    at = &(buf[0]);
+    len = rest - 1 /* ; */ - cur_uri;
+    memcpy(at, cur_uri, len);
+    at = at + len;
+    len = cur_uri_len - alias_len - len;
+    memcpy(at, rest + alias_len - 1, len);
+    uri.s = &(buf[0]);
+    uri.len = cur_uri_len - alias_len;
+    LM_DBG("rewriting r-uri to <%.*s>\n", uri.len, uri.s);
+    return rewrite_uri(msg, &uri);
+}
+
+
+/*
+ * Counts and return the number of record routes in rr headers of the message.
+ */
+static int
+pv_get_rr_count_f(struct sip_msg *msg, pv_param_t *param,
+		  pv_value_t *res)
+{
+    unsigned int count;
+    struct hdr_field *header;
+    rr_t *body;
+
+    if (msg == NULL) return -1;
+
+    if (parse_headers(msg, HDR_EOH_F, 0) == -1) {
+	LM_ERR("while parsing message\n");
+	return -1;
+    }
+
+    count = 0;
+    header = msg->record_route;
+
+    while (header) {
+	if (header->type == HDR_RECORDROUTE_T) {
+	    if (parse_rr(header) == -1) {
+		LM_ERR("while parsing rr header\n");
+		return -1;
+	    }
+	    body = (rr_t *)header->parsed;
+	    while (body) {
+		count++;
+		body = body->next;
+	    }
+	}
+	header = header->next;
+    }
+
+    return pv_get_uintval(msg, param, res, (unsigned int)count);
+}
+
+/*
+ * Return count of topmost record routes in rr headers of the message.
+ */
+static int
+pv_get_rr_top_count_f(struct sip_msg *msg, pv_param_t *param,
+		      pv_value_t *res)
+{
+    str uri;
+    struct sip_uri puri;
+
+    if (msg == NULL) return -1;
+
+    if (!msg->record_route &&
+	(parse_headers(msg, HDR_RECORDROUTE_F, 0) == -1)) {
+	LM_ERR("while parsing Record-Route header\n");
+	return -1;
+    }
+
+    if (!msg->record_route) {
+	return pv_get_uintval(msg, param, res, 0);
+    }
+    
+    if (parse_rr(msg->record_route) == -1) {
+	LM_ERR("while parsing rr header\n");
+	return -1;
+    }
+
+    uri = ((rr_t *)msg->record_route->parsed)->nameaddr.uri;
+    if (parse_uri(uri.s, uri.len, &puri) < 0) {
+	LM_ERR("while parsing rr uri\n");
+	return -1;
+    }
+	
+    if (puri.r2.len > 0) {
+	return pv_get_uintval(msg, param, res, 2);
+    } else {
+	return pv_get_uintval(msg, param, res, 1);
+    }
+}
+
+
 /*
  * Test if IP address pointed to by saddr belongs to RFC1918 networks
  */

+ 2 - 2
modules_k/nathelper/rtpproxy_stream.c

@@ -62,8 +62,8 @@ fixup_var_str_int(void **param, int param_no)
 	s.s = (char *)(*param);
 	s.len = strlen(s.s);
 	if (str2sint(&s, &ret)==0) {
-            pkg_free(*param);
-            *param = (void *)ret;
+		pkg_free(*param);
+		*param = (void *)ret;
         } else {
             LM_ERR("bad number <%s>\n", (char *)(*param));
             return E_CFG;

+ 3 - 4
modules_k/presence/notify.c

@@ -1569,8 +1569,8 @@ jump_over_body:
 		goto error;	
 	}	
 
-	set_uac_req(&uac_r, &met, &str_hdr, notify_body, td, 0, p_tm_callback,
-				(void*)cb_param);
+	set_uac_req(&uac_r, &met, &str_hdr, notify_body, td, TMCB_LOCAL_COMPLETED,
+			p_tm_callback, (void*)cb_param);
 	result = tmb.t_request_within(&uac_r);
 	if(result< 0)
 	{
@@ -1793,8 +1793,7 @@ str* create_winfo_xml(watcher_t* watchers, char* version,
 		LM_ERR("while adding child\n");
 		goto error;
 	}
-	res= (char*)pkg_malloc((resource.len>event.len)?resource.len:event.len
-			+ 1);
+	res= (char*)pkg_malloc(MAX_unsigned(resource.len, event.len) + 1);
 	if(res== NULL)
 	{
 		ERR_MEM(PKG_MEM_STR);

+ 4 - 4
modules_k/pua/pua.c

@@ -660,8 +660,8 @@ int update_pua(ua_pres_t* p, unsigned int hash_code)
 			goto error;
 		}	
 		
-		set_uac_req(&uac_r, &met, str_hdr, 0, 0, 0, publ_cback_func, 
-					(void*)cb_param);
+		set_uac_req(&uac_r, &met, str_hdr, 0, 0, TMCB_LOCAL_COMPLETED,
+				publ_cback_func, (void*)cb_param);
 
 		result= tmb.t_request(&uac_r,
 				p->pres_uri,					/* Request-URI */
@@ -705,8 +705,8 @@ int update_pua(ua_pres_t* p, unsigned int hash_code)
 
 		}	
 
-		set_uac_req(&uac_r, &met, str_hdr, 0, td, 0, subs_cback_func, 
-					(void*)cb_param);
+		set_uac_req(&uac_r, &met, str_hdr, 0, td, TMCB_LOCAL_COMPLETED,
+				subs_cback_func, (void*)cb_param);
 		
 		result= tmb.t_request_within(&uac_r);
 		if(result< 0)

+ 2 - 2
modules_k/pua/send_publish.c

@@ -551,8 +551,8 @@ send_publish:
 	if(body && body->len && body->s )
 		LM_DBG("body:\n%.*s\n ", body->len, body->s);
 
-	set_uac_req(&uac_r, &met, str_hdr, body, 0, 0, publ_cback_func,
-				(void*)cb_param);
+	set_uac_req(&uac_r, &met, str_hdr, body, 0, TMCB_LOCAL_COMPLETED,
+			publ_cback_func, (void*)cb_param);
 	result= tmb.t_request(&uac_r,
 			publ->pres_uri,			/*! Request-URI */
 			publ->pres_uri,			/*! To */

+ 4 - 4
modules_k/pua/send_subscribe.c

@@ -885,8 +885,8 @@ insert:
 		}
 		hentity->flag= flag;
 
-		set_uac_req(&uac_r, &met, str_hdr, 0, 0, 0,subs_cback_func, 
-					(void*)hentity);
+		set_uac_req(&uac_r, &met, str_hdr, 0, 0, TMCB_LOCAL_COMPLETED,
+				subs_cback_func, (void*)hentity);
 		result= tmb.t_request
 			(&uac_r,						  /* Type of the message */
 		subs->remote_target?subs->remote_target:subs->pres_uri,/* Request-URI*/
@@ -971,8 +971,8 @@ insert:
 	//	hentity->flag= flag;
 		LM_DBG("event parameter: %d\n", hentity->event);	
 
-		set_uac_req(&uac_r, &met, str_hdr, 0, td, 0,subs_cback_func, 
-					(void*)hentity);
+		set_uac_req(&uac_r, &met, str_hdr, 0, td, TMCB_LOCAL_COMPLETED,
+				subs_cback_func, (void*)hentity);
 		result= tmb.t_request_within(&uac_r);
 		if(result< 0)
 		{

+ 3 - 3
modules_k/pv/pv_trans.c

@@ -925,7 +925,7 @@ int tr_eval_tobody(struct sip_msg *msg, tr_param_t *tp, int subtype,
 	{
 		if(_tr_tobody_str.len==0)
 			memset(&_tr_tobody, 0, sizeof(struct to_body));
-		if(val->rs.len>_tr_tobody_str.len)
+		if(_tr_tobody_str.s==NULL || val->rs.len>_tr_tobody_str.len)
 		{
 			if(_tr_tobody_str.s) pkg_free(_tr_tobody_str.s);
 				_tr_tobody_str.s =
@@ -954,7 +954,7 @@ int tr_eval_tobody(struct sip_msg *msg, tr_param_t *tp, int subtype,
 		{
 			memset(&_tr_tobody, 0, sizeof(struct to_body));
 			pkg_free(_tr_tobody_str.s);
-			_tr_tobody_str.len = 0;
+			memset(&_tr_tobody_str, 0, sizeof(str));
 			return -1;
 		}
 		if (parse_uri(_tr_tobody.uri.s, _tr_tobody.uri.len,
@@ -963,7 +963,7 @@ int tr_eval_tobody(struct sip_msg *msg, tr_param_t *tp, int subtype,
 			free_to_params(&_tr_tobody);
 			memset(&_tr_tobody, 0, sizeof(struct to_body));
 			pkg_free(_tr_tobody_str.s);
-			_tr_tobody_str.len = 0;
+			memset(&_tr_tobody_str, 0, sizeof(str));
 			return -1;
 		}
 

+ 105 - 125
modules_k/registrar/README

@@ -40,22 +40,21 @@ Bogdan-Andre Iancu
               3.2. min_expires (integer)
               3.3. max_expires (integer)
               3.4. default_q (integer)
-              3.5. tcp_persistent_flag (integer)
-              3.6. realm_prefix (string)
-              3.7. append_branches (integer)
-              3.8. aor_avp (str)
-              3.9. case_sensitive (integer)
-              3.10. received_avp (str)
-              3.11. received_param (string)
-              3.12. max_contacts (integer)
-              3.13. retry_after (integer)
-              3.14. sock_flag (integer)
-              3.15. sock_hdr_name (string)
-              3.16. method_filtering (integer)
-              3.17. use_path (integer)
-              3.18. path_mode (integer)
-              3.19. path_use_received (integer)
-              3.20. reg_callid_avp (string)
+              3.5. realm_prefix (string)
+              3.6. append_branches (integer)
+              3.7. aor_avp (str)
+              3.8. case_sensitive (integer)
+              3.9. received_avp (str)
+              3.10. received_param (string)
+              3.11. max_contacts (integer)
+              3.12. retry_after (integer)
+              3.13. sock_flag (integer)
+              3.14. sock_hdr_name (string)
+              3.15. method_filtering (integer)
+              3.16. use_path (integer)
+              3.17. path_mode (integer)
+              3.18. path_use_received (integer)
+              3.19. reg_callid_avp (string)
 
         4. Exported Functions
 
@@ -88,31 +87,30 @@ Bogdan-Andre Iancu
    1.2. Set min_expires parameter
    1.3. Set max_expires parameter
    1.4. Set default_q parameter
-   1.5. Set tcp_persistent_flag parameter
-   1.6. Set realm_prefix parameter
-   1.7. Set append_branches parameter
-   1.8. Set aor_avp parameter
-   1.9. Set case_sensitive parameter
-   1.10. Set received_avp parameter
-   1.11. Set received_param parameter
-   1.12. Set max_contacts parameter
-   1.13. Set retry_after parameter
-   1.14. Set sock_flag parameter
-   1.15. Set sock_hdr_namer parameter
-   1.16. Set method_filtering parameter
-   1.17. Set use_path parameter
-   1.18. Set path_mode parameter
-   1.19. Set path_use_received parameter
-   1.20. Set reg_callid_avp parameter
+   1.5. Set realm_prefix parameter
+   1.6. Set append_branches parameter
+   1.7. Set aor_avp parameter
+   1.8. Set case_sensitive parameter
+   1.9. Set received_avp parameter
+   1.10. Set received_param parameter
+   1.11. Set max_contacts parameter
+   1.12. Set retry_after parameter
+   1.13. Set sock_flag parameter
+   1.14. Set sock_hdr_namer parameter
+   1.15. Set method_filtering parameter
+   1.16. Set use_path parameter
+   1.17. Set path_mode parameter
+   1.18. Set path_use_received parameter
+   1.19. Set reg_callid_avp parameter
+   1.20. save usage
    1.21. save usage
-   1.22. save usage
-   1.23. lookup usage
-   1.24. registered usage
-   1.25. add_sock_hdr usage
+   1.22. lookup usage
+   1.23. registered usage
+   1.24. add_sock_hdr usage
+   1.25. registered usage
    1.26. registered usage
    1.27. registered usage
-   1.28. registered usage
-   1.29. $sht(name) usage
+   1.28. $sht(name) usage
 
 Chapter 1. Admin Guide
 
@@ -133,22 +131,21 @@ Chapter 1. Admin Guide
         3.2. min_expires (integer)
         3.3. max_expires (integer)
         3.4. default_q (integer)
-        3.5. tcp_persistent_flag (integer)
-        3.6. realm_prefix (string)
-        3.7. append_branches (integer)
-        3.8. aor_avp (str)
-        3.9. case_sensitive (integer)
-        3.10. received_avp (str)
-        3.11. received_param (string)
-        3.12. max_contacts (integer)
-        3.13. retry_after (integer)
-        3.14. sock_flag (integer)
-        3.15. sock_hdr_name (string)
-        3.16. method_filtering (integer)
-        3.17. use_path (integer)
-        3.18. path_mode (integer)
-        3.19. path_use_received (integer)
-        3.20. reg_callid_avp (string)
+        3.5. realm_prefix (string)
+        3.6. append_branches (integer)
+        3.7. aor_avp (str)
+        3.8. case_sensitive (integer)
+        3.9. received_avp (str)
+        3.10. received_param (string)
+        3.11. max_contacts (integer)
+        3.12. retry_after (integer)
+        3.13. sock_flag (integer)
+        3.14. sock_hdr_name (string)
+        3.15. method_filtering (integer)
+        3.16. use_path (integer)
+        3.17. path_mode (integer)
+        3.18. path_use_received (integer)
+        3.19. reg_callid_avp (string)
 
    4. Exported Functions
 
@@ -230,22 +227,21 @@ Chapter 1. Admin Guide
    3.2. min_expires (integer)
    3.3. max_expires (integer)
    3.4. default_q (integer)
-   3.5. tcp_persistent_flag (integer)
-   3.6. realm_prefix (string)
-   3.7. append_branches (integer)
-   3.8. aor_avp (str)
-   3.9. case_sensitive (integer)
-   3.10. received_avp (str)
-   3.11. received_param (string)
-   3.12. max_contacts (integer)
-   3.13. retry_after (integer)
-   3.14. sock_flag (integer)
-   3.15. sock_hdr_name (string)
-   3.16. method_filtering (integer)
-   3.17. use_path (integer)
-   3.18. path_mode (integer)
-   3.19. path_use_received (integer)
-   3.20. reg_callid_avp (string)
+   3.5. realm_prefix (string)
+   3.6. append_branches (integer)
+   3.7. aor_avp (str)
+   3.8. case_sensitive (integer)
+   3.9. received_avp (str)
+   3.10. received_param (string)
+   3.11. max_contacts (integer)
+   3.12. retry_after (integer)
+   3.13. sock_flag (integer)
+   3.14. sock_hdr_name (string)
+   3.15. method_filtering (integer)
+   3.16. use_path (integer)
+   3.17. path_mode (integer)
+   3.18. path_use_received (integer)
+   3.19. reg_callid_avp (string)
 
 3.1. default_expires (integer)
 
@@ -301,23 +297,7 @@ modparam("registrar", "max_expires", 120)
 modparam("registrar", "default_q", 1000)
 ...
 
-3.5. tcp_persistent_flag (integer)
-
-   The parameter specifies the message flag to be used to control the
-   module behaviour regarding TCP connections. If the flag is set for a
-   REGISTER via TCP containing a TCP contact, the module, via the "save()"
-   functions will set the lifetime of the TCP connection to the contact
-   expire value. By doing this, the TCP connection will stay on as long as
-   the contact is valid.
-
-   Default value is -1 (disabled).
-
-   Example 1.5. Set tcp_persistent_flag parameter
-...
-modparam("registrar", "tcp_persistent_flag", 7)
-...
-
-3.6. realm_prefix (string)
+3.5. realm_prefix (string)
 
    Prefix to be automatically strip from realm. As an alternative to SRV
    records (not all SIP clients support SRV lookup), a subdomain of the
@@ -328,12 +308,12 @@ modparam("registrar", "tcp_persistent_flag", 7)
 
    Default value is NULL (none).
 
-   Example 1.6. Set realm_prefix parameter
+   Example 1.5. Set realm_prefix parameter
 ...
 modparam("registrar", "realm_prefix", "sip.")
 ...
 
-3.7. append_branches (integer)
+3.6. append_branches (integer)
 
    The parameter controls how lookup function processes multiple contacts.
    If there are multiple contacts for the given username in usrloc and
@@ -345,12 +325,12 @@ modparam("registrar", "realm_prefix", "sip.")
 
    Default value is 1.
 
-   Example 1.7. Set append_branches parameter
+   Example 1.6. Set append_branches parameter
 ...
 modparam("registrar", "append_branches", 0)
 ...
 
-3.8. aor_avp (str)
+3.7. aor_avp (str)
 
    If set, the module will try first to get the AOR from this AVP instead
    of fetching it form the processed request.
@@ -360,24 +340,24 @@ modparam("registrar", "append_branches", 0)
 
    Default value is "NULL" (disabled).
 
-   Example 1.8. Set aor_avp parameter
+   Example 1.7. Set aor_avp parameter
 ...
 modparam("registrar", "aor_avp", "$avp(i:3223)")
 ...
 
-3.9. case_sensitive (integer)
+3.8. case_sensitive (integer)
 
    If set to 1 then AOR comparison will be case sensitive, if set to 0
    then AOR comparison will be case insensitive--This is recommended.
 
    Default value is 0.
 
-   Example 1.9. Set case_sensitive parameter
+   Example 1.8. Set case_sensitive parameter
 ...
 modparam("registrar", "case_sensitive", 1)
 ...
 
-3.10. received_avp (str)
+3.9. received_avp (str)
 
    Registrar will store the value of the AVP configured by this parameter
    in the received column in the user location database. It will leave the
@@ -392,24 +372,24 @@ Note
 
    Default value is "NULL" (disabled).
 
-   Example 1.10. Set received_avp parameter
+   Example 1.9. Set received_avp parameter
 ...
 modparam("registrar", "received_avp", "$avp(s:rcv)")
 ...
 
-3.11. received_param (string)
+3.10. received_param (string)
 
    The name of the parameter that will be appended to Contacts of 200 OK
    when the received URI was set by nathelper module.
 
    Default value is "received".
 
-   Example 1.11. Set received_param parameter
+   Example 1.10. Set received_param parameter
 ...
 modparam("registrar", "received_param", "rcv")
 ...
 
-3.12. max_contacts (integer)
+3.11. max_contacts (integer)
 
    The parameter can be used to limit the number of contacts per AOR
    (Address of Record) in the user location database. Value 0 disables the
@@ -417,13 +397,13 @@ modparam("registrar", "received_param", "rcv")
 
    Default value is 0.
 
-   Example 1.12. Set max_contacts parameter
+   Example 1.11. Set max_contacts parameter
 ...
 # Allow no more than 10 contacts per AOR
 modparam("registrar", "max_contacts", 10)
 ...
 
-3.13. retry_after (integer)
+3.12. retry_after (integer)
 
    The registrar can generate 5xx reply to REGISTER in various situations.
    It can, for example, happen when the max_contacts parameter is set and
@@ -436,12 +416,12 @@ modparam("registrar", "max_contacts", 10)
 
    Default value is 0 (disabled).
 
-   Example 1.13. Set retry_after parameter
+   Example 1.12. Set retry_after parameter
 ...
 modparam("registrar", "retry_after", 30)
 ...
 
-3.14. sock_flag (integer)
+3.13. sock_flag (integer)
 
    Message flag to signal to register module to look into REGISTER request
    for a header which contains a socket description (IP:port). This socket
@@ -451,12 +431,12 @@ modparam("registrar", "retry_after", 30)
 
    Default value is -1 (no flag).
 
-   Example 1.14. Set sock_flag parameter
+   Example 1.13. Set sock_flag parameter
 ...
 modparam("registrar", "sock_flag", 18)
 ...
 
-3.15. sock_hdr_name (string)
+3.14. sock_hdr_name (string)
 
    Header which contains a socket description (proto:IP:port) to override
    the received socket info. The header will be read only if the flag
@@ -466,36 +446,36 @@ modparam("registrar", "sock_flag", 18)
 
    Default value is NULL.
 
-   Example 1.15. Set sock_hdr_namer parameter
+   Example 1.14. Set sock_hdr_namer parameter
 ...
 modparam("registrar", "sock_hdr_name", "Sock-Info")
 ...
 
-3.16. method_filtering (integer)
+3.15. method_filtering (integer)
 
    Tells if the contact filtering based on supported methods should be
    performed during lookup. It's enabled only if it has a non zero value.
 
    Default value is 0 (disabled).
 
-   Example 1.16. Set method_filtering parameter
+   Example 1.15. Set method_filtering parameter
 ...
 modparam("registrar", "method_filtering", 1)
 ...
 
-3.17. use_path (integer)
+3.16. use_path (integer)
 
    If set to 1, the Path header is handled according to the parameter
    "path_mode".
 
    Default value is 0 (disabled).
 
-   Example 1.17. Set use_path parameter
+   Example 1.16. Set use_path parameter
 ...
 modparam("registrar", "use_path", 1)
 ...
 
-3.18. path_mode (integer)
+3.17. path_mode (integer)
 
    The registrar module implements three different modes regarding the
    response to a registration which includes one or more Path headers:
@@ -513,12 +493,12 @@ modparam("registrar", "use_path", 1)
 
    Default value is 2.
 
-   Example 1.18. Set path_mode parameter
+   Example 1.17. Set path_mode parameter
 ...
 modparam("registrar", "path_mode", 0)
 ...
 
-3.19. path_use_received (integer)
+3.18. path_use_received (integer)
 
    If set to 1, the "received" parameter of the first Path URI of a
    registration is set as received-uri and the NAT branch flag is set for
@@ -528,12 +508,12 @@ modparam("registrar", "path_mode", 0)
 
    Default value is 0 (disabled).
 
-   Example 1.19. Set path_use_received parameter
+   Example 1.18. Set path_use_received parameter
 ...
 modparam("registrar", "path_use_received", 1)
 ...
 
-3.20. reg_callid_avp (string)
+3.19. reg_callid_avp (string)
 
    If reg_callid_avp is defined and populated when registered() is
    invoked, the result is TRUE only if an active registration with the
@@ -541,7 +521,7 @@ modparam("registrar", "path_use_received", 1)
 
    Default value is NULL (disabled).
 
-   Example 1.20. Set reg_callid_avp parameter
+   Example 1.19. Set reg_callid_avp parameter
 ...
 modparam("registrar", "reg_callid_avp", "$avp(s:avp)")
 ...
@@ -579,7 +559,7 @@ modparam("registrar", "reg_callid_avp", "$avp(s:avp)")
 
    This function can be used from REQUEST_ROUTE and REPLY_ROUTE.
 
-   Example 1.21. save usage
+   Example 1.20. save usage
 ...
 save("location");
 ...
@@ -606,7 +586,7 @@ save("location");
 
    This function can be used from REQUEST_ROUTE and ONREPLY_ROUTE.
 
-   Example 1.22. save usage
+   Example 1.21. save usage
 ...
 save("location","0x01");
 ...
@@ -635,7 +615,7 @@ save("location","0x01");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.23. lookup usage
+   Example 1.22. lookup usage
 ...
 lookup("location");
 switch ($retcode) {
@@ -661,7 +641,7 @@ switch ($retcode) {
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.24. registered usage
+   Example 1.23. registered usage
 ...
 if (registered("location")) {
         sl_send_reply("100", "Trying");
@@ -681,7 +661,7 @@ if (registered("location")) {
 
    This function can be used from REQUEST_ROUTE.
 
-   Example 1.25. add_sock_hdr usage
+   Example 1.24. add_sock_hdr usage
 ...
 add_sock_hdr("Sock-Info");
 ...
@@ -699,7 +679,7 @@ add_sock_hdr("Sock-Info");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.26. registered usage
+   Example 1.25. registered usage
 ...
 unregister("location", "$ru");
 unregister("location", "sip:[email protected]");
@@ -721,7 +701,7 @@ unregister("location", "sip:[email protected]");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.27. registered usage
+   Example 1.26. registered usage
 ...
 reg_fetch_contacts("location", "$ru", "callee");
 reg_fetch_contacts("location", "sip:[email protected]", "caller");
@@ -740,7 +720,7 @@ reg_fetch_contacts("location", "sip:[email protected]", "caller");
 
    This function can be used from REQUEST_ROUTE, FAILURE_ROUTE.
 
-   Example 1.28. registered usage
+   Example 1.27. registered usage
 ...
 reg_free_contacts("callee");
 ...
@@ -806,7 +786,7 @@ reg_free_contacts("callee");
    The pseudo-variable accepts positive index value to access a specific
    contact record.
 
-   Example 1.29. $sht(name) usage
+   Example 1.28. $sht(name) usage
 ...
 if(reg_fetch_contacts("location", "$fu", "caller"))
 {

+ 0 - 25
modules_k/registrar/doc/registrar_admin.xml

@@ -197,31 +197,6 @@ modparam("registrar", "default_q", 1000)
 		</example>
 	</section>
 
-	<section>
-		<title><varname>tcp_persistent_flag</varname> (integer)</title>
-		<para>
-		The parameter specifies the message flag to be used to control the 
-		module behaviour regarding TCP connections. If the flag is set for a 
-		REGISTER via TCP containing a TCP contact, the module, via the 
-		<quote>save()</quote> functions will set the lifetime of the TCP
-		connection to the contact expire value. By doing this, the TCP 
-		connection will stay on as long as the contact is valid.
-		</para>
-		<para>
-		<emphasis>
-			Default value is -1 (disabled).
-		</emphasis>
-		</para>
-		<example>
-		<title>Set <varname>tcp_persistent_flag</varname> parameter</title>
-		<programlisting format="linespecific">
-...
-modparam("registrar", "tcp_persistent_flag", 7)
-...
-</programlisting>
-		</example>
-	</section>
-
 	<section>
 		<title><varname>realm_prefix</varname> (string)</title>
 		<para>

+ 3 - 1
modules_k/registrar/reg_mod.c

@@ -41,6 +41,8 @@
  *              contacts and default expiry time(Jeffrey Magder-SOMA Networks)
  *  2007-02-24  sip_natping_flag moved into branch flags, so migrated to 
  *              nathelper module (bogdan)
+ *  2009-12-09  Commented out tcp_persistent_flag param, because sr_3.0 tm
+ *              does not support it (Juha)
  *
  */
 
@@ -191,7 +193,7 @@ static param_export_t params[] = {
 	{"default_q",          INT_PARAM, &default_q           },
 	{"append_branches",    INT_PARAM, &append_branches     },
 	{"case_sensitive",     INT_PARAM, &case_sensitive      },
-	{"tcp_persistent_flag",INT_PARAM, &tcp_persistent_flag },
+	/*	{"tcp_persistent_flag",INT_PARAM, &tcp_persistent_flag }, */
 	{"realm_prefix",       STR_PARAM, &realm_pref          },
 	{"min_expires",        INT_PARAM, &min_expires         },
 	{"max_expires",        INT_PARAM, &max_expires         },

+ 2 - 2
modules_k/rls/notify.c

@@ -686,8 +686,8 @@ int rls_send_notify(subs_t* subs, str* body, char* start_cid,
 	}
 	LM_DBG("str_hdr= %.*s\n", str_hdr->len, str_hdr->s);
 
-	set_uac_req(&uac_r, &met, str_hdr, body, td, 0, rls_notify_callback,
-				(void*)cb_param);
+	set_uac_req(&uac_r, &met, str_hdr, body, td, TMCB_LOCAL_COMPLETED,
+			rls_notify_callback, (void*)cb_param);
 
 	rt = tmb.t_request_within(&uac_r);
 	if(rt < 0)

+ 1 - 1
modules_k/usrloc/ul_mi.c

@@ -51,7 +51,7 @@
 /*! call-id used for ul_add and ul_rm_contact */
 static str mi_ul_cid = str_init("[email protected]");
 /*! user agent used for ul_add */
-static str mi_ul_ua  = str_init("Kamailio MI Server");
+static str mi_ul_ua  = str_init("SIP Router MI Server");
 
 
 /************************ helper functions ****************************/

+ 7 - 6
modules_k/xlog/README

@@ -163,13 +163,14 @@ modparam("xlog", "prefix", "-xlog: ")
 
    Meaning of the parameters are as follows:
      * level - The level that will be used in LOG function. It can be:
-          + L_ALERT - log level -3
-          + L_CRIT - log level -2
+          + L_ALERT - log level -5
+          + L_BUG - log level -4
+          + L_CRIT - log level -3
           + L_ERR - log level -1
-          + L_WARN - log level 1
-          + L_NOTICE - log level 2
-          + L_INFO - log level 3
-          + L_DBG - log level 4
+          + L_WARN - log level 0
+          + L_NOTICE - log level 1
+          + L_INFO - log level 2
+          + L_DBG - log level 3
           + $pv - any valid pseudo-variable, that has an integer value.
             See above options for valid log levels.
        If it is not a pseudo-variable, then what really matters is the

+ 11 - 6
modules_k/xlog/doc/xlog_admin.xml

@@ -168,12 +168,17 @@ modparam("xlog", "prefix", "-xlog: ")
 			<itemizedlist>
 			<listitem>
 				<para>
-				L_ALERT - log level -3
+				L_ALERT - log level -5
 				</para>
 			</listitem>
 			<listitem>
 				<para>
-				L_CRIT - log level -2
+				L_BUG - log level -4
+				</para>
+			</listitem>
+			<listitem>
+				<para>
+				L_CRIT - log level -3
 				</para>
 			</listitem>
 			<listitem>
@@ -183,22 +188,22 @@ modparam("xlog", "prefix", "-xlog: ")
 			</listitem>
 			<listitem>
 				<para>
-				L_WARN - log level 1
+				L_WARN - log level 0
 				</para>
 			</listitem>
 			<listitem>
 				<para>
-				L_NOTICE - log level 2
+				L_NOTICE - log level 1
 				</para>
 			</listitem>
 			<listitem>
 				<para>
-				L_INFO - log level 3
+				L_INFO - log level 2
 				</para>
 			</listitem>
 			<listitem>
 				<para>
-				L_DBG - log level 4
+				L_DBG - log level 3
 				</para>
 			</listitem>
 			<listitem>

+ 2 - 1
modules_k/xlog/xlog.c

@@ -257,7 +257,8 @@ static int xlog_fixup(void** param, int param_no)
 			switch(((char*)(*param))[2])
 			{
 				case 'A': xlp->v.level = L_ALERT; break;
-				case 'C': xlp->v.level = L_CRIT; break;
+				case 'B': xlp->v.level = L_BUG; break;
+				case 'C': xlp->v.level = L_CRIT2; break;
 				case 'E': xlp->v.level = L_ERR; break;
 				case 'W': xlp->v.level = L_WARN; break;
 				case 'N': xlp->v.level = L_NOTICE; break;

+ 0 - 0
modules_s/pa/ChangeLog → obsolete/pa/ChangeLog


+ 0 - 0
modules_s/pa/Makefile → obsolete/pa/Makefile


+ 0 - 0
modules_s/pa/README → obsolete/pa/README


+ 0 - 0
modules_s/pa/async_auth.c → obsolete/pa/async_auth.c


+ 0 - 0
modules_s/pa/async_auth.h → obsolete/pa/async_auth.h


+ 0 - 0
modules_s/pa/auth.c → obsolete/pa/auth.c


+ 0 - 0
modules_s/pa/auth.h → obsolete/pa/auth.h


+ 0 - 0
modules_s/pa/dlist.c → obsolete/pa/dlist.c


+ 0 - 0
modules_s/pa/dlist.h → obsolete/pa/dlist.h


+ 0 - 0
modules_s/pa/doc/Makefile → obsolete/pa/doc/Makefile


+ 0 - 0
modules_s/pa/doc/auth.xml → obsolete/pa/doc/auth.xml


+ 0 - 0
modules_s/pa/doc/functions.xml → obsolete/pa/doc/functions.xml


+ 0 - 0
modules_s/pa/doc/pa.xml → obsolete/pa/doc/pa.xml


+ 0 - 0
modules_s/pa/doc/pa_base.xml → obsolete/pa/doc/pa_base.xml


+ 0 - 0
modules_s/pa/doc/pa_db_src.xml → obsolete/pa/doc/pa_db_src.xml


+ 0 - 0
modules_s/pa/doc/pa_incl.xml → obsolete/pa/doc/pa_incl.xml


+ 0 - 0
modules_s/pa/doc/params.xml → obsolete/pa/doc/params.xml


+ 0 - 0
modules_s/pa/doc/xcap.xml → obsolete/pa/doc/xcap.xml


+ 0 - 0
modules_s/pa/extension_elements.c → obsolete/pa/extension_elements.c


+ 0 - 0
modules_s/pa/extension_elements.h → obsolete/pa/extension_elements.h


+ 0 - 0
modules_s/pa/hslot.c → obsolete/pa/hslot.c


+ 0 - 0
modules_s/pa/hslot.h → obsolete/pa/hslot.h


+ 0 - 0
modules_s/pa/message.c → obsolete/pa/message.c


+ 0 - 0
modules_s/pa/message.h → obsolete/pa/message.h


+ 0 - 0
modules_s/pa/mimetypes.c → obsolete/pa/mimetypes.c


+ 0 - 0
modules_s/pa/mimetypes.h → obsolete/pa/mimetypes.h


+ 0 - 0
modules_s/pa/notify.c → obsolete/pa/notify.c


+ 0 - 0
modules_s/pa/notify.h → obsolete/pa/notify.h


+ 0 - 0
modules_s/pa/offline_winfo.c → obsolete/pa/offline_winfo.c


+ 0 - 0
modules_s/pa/offline_winfo.h → obsolete/pa/offline_winfo.h


+ 0 - 0
modules_s/pa/pa_mod.c → obsolete/pa/pa_mod.c


+ 0 - 0
modules_s/pa/pa_mod.h → obsolete/pa/pa_mod.h


+ 0 - 0
modules_s/pa/paerrno.c → obsolete/pa/paerrno.c


+ 0 - 0
modules_s/pa/paerrno.h → obsolete/pa/paerrno.h


+ 0 - 0
modules_s/pa/pdomain.c → obsolete/pa/pdomain.c


+ 0 - 0
modules_s/pa/pdomain.h → obsolete/pa/pdomain.h


+ 0 - 0
modules_s/pa/pres_notes.c → obsolete/pa/pres_notes.c


+ 0 - 0
modules_s/pa/pres_notes.h → obsolete/pa/pres_notes.h


+ 0 - 0
modules_s/pa/pres_timer.c → obsolete/pa/pres_timer.c


+ 0 - 0
modules_s/pa/presentity.c → obsolete/pa/presentity.c


+ 0 - 0
modules_s/pa/presentity.h → obsolete/pa/presentity.h


+ 0 - 0
modules_s/pa/ptime.c → obsolete/pa/ptime.c


+ 0 - 0
modules_s/pa/ptime.h → obsolete/pa/ptime.h


+ 0 - 0
modules_s/pa/publish.c → obsolete/pa/publish.c


+ 0 - 0
modules_s/pa/publish.h → obsolete/pa/publish.h


+ 0 - 0
modules_s/pa/qsa_interface.c → obsolete/pa/qsa_interface.c


+ 0 - 0
modules_s/pa/qsa_interface.h → obsolete/pa/qsa_interface.h


+ 0 - 0
modules_s/pa/reply.c → obsolete/pa/reply.c


+ 0 - 0
modules_s/pa/reply.h → obsolete/pa/reply.h


+ 0 - 0
modules_s/pa/rpc.c → obsolete/pa/rpc.c


+ 0 - 0
modules_s/pa/rpc.h → obsolete/pa/rpc.h


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