Browse Source

Merge commit 'origin/ser_core_cvs'

* commit 'origin/ser_core_cvs':
  tcp: minor optimization
  sercmd: minor makefile fix
  tcp internal: send timeout is now kept only in ticks
  core: typo fix
  tcp: typo & minor optimization
  Rename Contact parameter select 'method' to 'methods'
  Rename Contact parameter 'method' to 'methods'
  make install: avoid re-linking lib dependent modules
  build system: avoid libraries re-compiling
  fixing missing $ in ser_mysql.sh script
  Debian packaging - fixing path to mysql sql files in my_create.sh script
  The fixup function prototypes of the config variables have been
  Strip, prefix, rewriteuser, ... all the SET_* actions preserve the
  core: check & fix Content-Length when sending on tcp
  tcp: config option for the async write block size
  tcp: config option for the read buffer size
  tcp: dyn. config fix for tcp_con_lifetime
  tcp: diff. connect timeout for async & states cleanup

Conflicts:
	Makefile.rules
	action.c
	cfg.lex
	cfg.y
	route_struct.h
Andrei Pelinescu-Onciul 16 years ago
parent
commit
d240dd18e0
53 changed files with 579 additions and 353 deletions
  1. 6 3
      Makefile
  2. 78 75
      Makefile.defs
  3. 2 3
      Makefile.libs
  4. 5 1
      Makefile.modules
  5. 1 1
      Makefile.radius
  6. 19 13
      Makefile.rules
  7. 14 0
      NEWS
  8. 115 15
      action.c
  9. 10 0
      cfg.lex
  10. 31 5
      cfg.y
  11. 2 2
      cfg/cfg.h
  12. 14 8
      cfg/cfg_ctx.c
  13. 6 2
      cfg/cfg_struct.c
  14. 3 3
      cfg/cfg_struct.h
  15. 3 4
      core_cmd.c
  16. 5 5
      dns_cache.c
  17. 4 4
      dns_cache.h
  18. 2 2
      doc/cfg.txt
  19. 1 1
      dprint.c
  20. 1 1
      dprint.h
  21. 2 2
      dst_blacklist.c
  22. 2 2
      dst_blacklist.h
  23. 1 1
      modules/tm/t_cancel.c
  24. 1 1
      modules/tm/t_cancel.h
  25. 1 1
      modules/tm/t_fwd.c
  26. 1 1
      modules/tm/t_fwd.h
  27. 1 1
      modules/tm/timer.c
  28. 1 1
      modules/tm/timer.h
  29. 42 12
      msg_translator.c
  30. 1 1
      msg_translator.h
  31. 2 2
      parser/contact/contact.c
  32. 1 1
      parser/contact/contact.h
  33. 6 6
      parser/parse_param.c
  34. 2 2
      parser/parse_param.h
  35. 4 4
      parser/parse_uri.c
  36. 1 0
      parser/parse_uri.h
  37. 1 3
      pkg/debian/rules
  38. 2 2
      pt.c
  39. 2 2
      pt.h
  40. 1 1
      receive.c
  41. 4 4
      resolve.c
  42. 4 4
      resolve.h
  43. 1 0
      route_struct.h
  44. 1 1
      scripts/mysql/ser_mysql.sh
  45. 2 2
      select_core.c
  46. 2 2
      select_core.h
  47. 18 8
      tcp_conn.h
  48. 4 0
      tcp_init.h
  49. 45 36
      tcp_main.c
  50. 65 70
      tcp_options.c
  51. 5 5
      tcp_options.h
  52. 29 26
      tcp_read.c
  53. 2 1
      utils/sercmd/Makefile

+ 6 - 3
Makefile

@@ -54,6 +54,8 @@
 #               the modules list can be changed without rebuilding the whole
 #               ser (andrei)
 #              added cfg-defs, new target that only rebuilds config.mak
+#  2009-03-10  replaced DEFS with C_DEFS (DEFS are now used only for
+#              "temporary" defines inside modules or libs) (andrei)
 #
 
 auto_gen=lex.yy.c cfg.tab.c #lexx, yacc etc
@@ -203,7 +205,7 @@ ALLDEP=config.mak Makefile Makefile.sources Makefile.rules
 # hack to force makefile.defs re-inclusion (needed when make calls itself with
 # other options -- e.g. make bin)
 #makefile_defs=0
-#DEFS:=
+#C_DEFS:=
 
 
 # try saved cfg, unless we are in the process of building it
@@ -331,7 +333,7 @@ config.mak: Makefile.defs
 	@$(call mapf2,cfg_save_var,saved_fixed_vars,$(@))
 	@$(call mapf2,cfg_save_var2,saved_chg_vars,$(@))
 	@echo "override makefile_defs:=1" >>$@
-	@echo "DEFS:=\$$(filter-out \$$(DEFS_RM) \$$(extra_defs),\$$(DEFS))" \
+	@echo "C_DEFS:=\$$(filter-out \$$(DEFS_RM) \$$(extra_defs),\$$(C_DEFS))" \
 					"\$$(extra_defs)"  >>$@
 	@echo "CFLAGS:=\$$(filter-out \$$(CFLAGS_RM) \$$(CC_EXTRA_OPTS)," \
 						"\$$(CFLAGS)) \$$(CC_EXTRA_OPTS)" >>$@
@@ -538,7 +540,8 @@ man: modules.lst
 	done; true
 
 .PHONY: install
-install:all install-bin install-modules install-cfg \
+install: export compile_for_install=yes
+install: install-bin install-modules install-cfg \
 	install-doc install-man install-utils install-share
 
 .PHONY: dbinstall

+ 78 - 75
Makefile.defs

@@ -66,6 +66,9 @@
 #  2008-06-26  support for make cfg / config.mak and hack to load 
 #               automatically config.mak when included from a module, lib 
 #               a.s.o (not from the main Makefile)  (andrei)
+#  2009-03-10  replaced DEFS with C_DEFS and INCLUDES with C_INCLUDES (DEFS
+#              and INCLUDES are now used only for "temporary" defines/includes
+#              inside modules or libs) (andrei)
 
 
 # check if already included/exported
@@ -460,7 +463,7 @@ endif
 #		adds support for Application Server interface
 # Sometimes is needes correct non-quoted $OS. HACK: gcc translates known OS to number ('linux'), so there is added underscore
 
-DEFS= $(extra_defs) \
+C_DEFS= $(extra_defs) \
 	 -DNAME='"$(MAIN_NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
 	 -DOS='$(OS)_' -DOS_QUOTED='"$(OS)"' -DCOMPILER='"$(CC_VER)"' -D__CPU_$(ARCH) -D__OS_$(OS) \
 	 -DSER_VER=$(SER_VER) \
@@ -507,14 +510,14 @@ DEFS= $(extra_defs) \
 # debugging symbols in all cases (-g). --andrei
 
 ifeq ($(CORE_TLS), 1)
-	DEFS+= -DUSE_TLS -DCORE_TLS
+	C_DEFS+= -DUSE_TLS -DCORE_TLS
 endif
 ifeq ($(TLS_HOOKS), 1)
-	DEFS+= -DUSE_TLS -DTLS_HOOKS
+	C_DEFS+= -DUSE_TLS -DTLS_HOOKS
 endif
 
 ifneq ($(STUN),)
-	DEFS+= -DUSE_STUN
+	C_DEFS+= -DUSE_STUN
 endif
 
 ifeq ($(mode),)
@@ -522,7 +525,7 @@ ifeq ($(mode),)
 endif
 
 ifeq ($(mode),debug)
-	DEFS+= -DEXTRA_DEBUG
+	C_DEFS+= -DEXTRA_DEBUG
 endif
 
 # platform dependent settings
@@ -598,7 +601,7 @@ endif
 
 ifeq ($(ARCH), arm)
 	use_fast_lock=yes
-	DEFS+=-DNOSMP # very unlikely to have an smp arm
+	C_DEFS+=-DNOSMP # very unlikely to have an smp arm
 endif
 
 ifeq ($(ARCH), arm6)
@@ -616,8 +619,8 @@ endif
 ifeq ($(ARCH), mips)
 # mips1 arch. (e.g. R3000) - no hardware locking support
 	use_fast_lock=no
-	DEFS+=-DMIPS_HAS_LLSC # likely
-	DEFS+=-DNOSMP # very likely
+	C_DEFS+=-DMIPS_HAS_LLSC # likely
+	C_DEFS+=-DNOSMP # very likely
 endif
 
 ifeq ($(ARCH), mips2)
@@ -632,24 +635,24 @@ endif
 
 ifeq ($(ARCH), alpha)
 	use_fast_lock=yes
-	DEFS+=-DNOSMP # very likely
+	C_DEFS+=-DNOSMP # very likely
 endif
 
 ifeq ($(use_fast_lock), yes)
-	DEFS+= -DFAST_LOCK -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 
+	C_DEFS+= -DFAST_LOCK -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 
 	found_lock_method=yes
 endif
 
 CFLAGS=
 LDFLAGS=
-INCLUDES=
+C_INCLUDES=
 # setting CFLAGS
 ifeq ($(mode), release)
 	#if i386
 ifeq	($(ARCH), i386)
 		# if gcc 
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM
+				C_DEFS+=-DCC_GCC_LIKE_ASM
 				#common stuff
 				CFLAGS=-g -O9 -funroll-loops  -Wcast-align $(PROFILE)
 			#if gcc 4.0+
@@ -692,7 +695,7 @@ endif			# CC_SHORTVER, 4.x
 
 else		# CC_NAME, gcc
 ifeq		($(CC_NAME), icc)
-			DEFS+=-DCC_GCC_LIKE_ASM
+			C_DEFS+=-DCC_GCC_LIKE_ASM
 			CFLAGS=-g -O3  -ipo -ipo_obj -unroll  $(PROFILE) \
 					 -tpp6 -xK  #-openmp  #optimize for PIII 
 				# -prefetch doesn't seem to work
@@ -710,7 +713,7 @@ endif	#ARCH, i386
 ifeq	($(ARCH), x86_64)
 		# if gcc 
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM
+				C_DEFS+=-DCC_GCC_LIKE_ASM
 				#common stuff
 				CFLAGS=-m64 -g -O9 -funroll-loops  -Wcast-align $(PROFILE)
 				LDFLAGS+=-m64
@@ -754,7 +757,7 @@ endif			# CC_SHORTVER, 4.x
 
 else		# CC_NAME, gcc
 ifeq		($(CC_NAME), icc)
-			DEFS+=-DCC_GCC_LIKE_ASM
+			C_DEFS+=-DCC_GCC_LIKE_ASM
 			CFLAGS=-g -O3  -ipo -ipo_obj -unroll  $(PROFILE) \
 					 -tpp6 -xK  #-openmp  #optimize for PIII 
 				# -prefetch doesn't seem to work
@@ -772,7 +775,7 @@ endif	#ARCH, x86_64
 ifeq	($(ARCH), sparc64)
 			#if gcc
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM -DSPARC64_MODE
+				C_DEFS+=-DCC_GCC_LIKE_ASM -DSPARC64_MODE
 				#common stuff
 				CFLAGS=-m64 -g -O9 -funroll-loops  $(PROFILE) \
 					#-Wcast-align \
@@ -834,7 +837,7 @@ endif			#CC_SHORTVER, 4.x
 	
 else		#CC_NAME, gcc
 ifeq		($(CC_NAME), suncc)
-			DEFS+=-DSPARC64_MODE
+			C_DEFS+=-DSPARC64_MODE
 			CFLAGS+= -m64 -g -xO5 -fast -native -xarch=v9 -xCC \
 					-xc99 # C99 support
 			# -Dinline="" # add this if cc < 5.3 (define inline as null)
@@ -849,7 +852,7 @@ endif	#ARCH, sparc64
 ifeq	($(ARCH), sparc)
 			#if gcc
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM
+				C_DEFS+=-DCC_GCC_LIKE_ASM
 				#common stuff
 				CFLAGS=-g -O9 -funroll-loops  $(PROFILE) \
 					#-Wcast-align \
@@ -906,7 +909,7 @@ endif	#ARCH, sparc
 ifeq	($(ARCH), arm)
 		# if gcc 
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM
+				C_DEFS+=-DCC_GCC_LIKE_ASM
 				#common stuff
 				CFLAGS=-O9 -funroll-loops $(PROFILE)
 			#if gcc 4.x+
@@ -948,7 +951,7 @@ endif	#ARCH, arm
 ifeq	($(ARCH), arm6)
 		# if gcc 
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM
+				C_DEFS+=-DCC_GCC_LIKE_ASM
 				#common stuff
 				CFLAGS=-march=armv6 -O9 -funroll-loops \
 						$(PROFILE)
@@ -990,7 +993,7 @@ endif	#ARCH, arm6
 ifeq	($(ARCH), mips)
 		# if gcc 
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM
+				C_DEFS+=-DCC_GCC_LIKE_ASM
 				#common stuff
 				CFLAGS=-O9 -funroll-loops  $(PROFILE)
 			#if gcc 4.0+
@@ -1031,7 +1034,7 @@ endif	#ARCH, mips
 ifeq	($(ARCH), mips2)
 		# if gcc 
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM
+				C_DEFS+=-DCC_GCC_LIKE_ASM
 				#common stuff
 				CFLAGS= -mips2 -O9 -funroll-loops $(PROFILE)
 			#if gcc 4.0+
@@ -1070,7 +1073,7 @@ endif	#ARCH, mips2
 ifeq	($(ARCH), mips64)
 		# if gcc 
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM
+				C_DEFS+=-DCC_GCC_LIKE_ASM
 				#common stuff
 				CFLAGS= -mips64 -O9 -funroll-loops $(PROFILE)
 			#if gcc 4.0+
@@ -1109,7 +1112,7 @@ endif	#ARCH, mips64
 ifeq	($(ARCH), alpha)
 		# if gcc 
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM
+				C_DEFS+=-DCC_GCC_LIKE_ASM
 				#common stuff
 				CFLAGS= -O9 -funroll-loops $(PROFILE)
 			#if gcc 4.0+
@@ -1149,7 +1152,7 @@ endif	#ARCH, alpha
 ifeq	($(ARCH), ppc)
 		# if gcc 
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM
+				C_DEFS+=-DCC_GCC_LIKE_ASM
 				#common stuff
 				CFLAGS= -O9 -funroll-loops $(PROFILE)
 			#if gcc 4.0+
@@ -1190,7 +1193,7 @@ endif	#ARCH, ppc
 ifeq	($(ARCH), ppc64)
 		# if gcc 
 ifeq		($(CC_NAME), gcc)
-				DEFS+=-DCC_GCC_LIKE_ASM
+				C_DEFS+=-DCC_GCC_LIKE_ASM
 				#common stuff
 				CFLAGS= -O9 -funroll-loops $(PROFILE)
 ifeq			($(CC_SHORTVER), 4.x)
@@ -1269,9 +1272,9 @@ endif
 else	#mode,release
 ifeq	($(CC_NAME), gcc)
 		CFLAGS=-g -Wcast-align $(PROFILE)
-		DEFS+=-DCC_GCC_LIKE_ASM
+		C_DEFS+=-DCC_GCC_LIKE_ASM
 ifeq		($(ARCH), sparc64)
-			DEFS+=SPARC64_MODE
+			C_DEFS+=SPARC64_MODE
 			CFLAGS+= -mcpu=ultrasparc -m64
 			LDFLAGS+=-m64
 endif
@@ -1292,7 +1295,7 @@ else
 endif
 endif
 ifeq	($(CC_NAME), icc)
-		DEFS+=-DCC_GCC_LIKE_ASM
+		C_DEFS+=-DCC_GCC_LIKE_ASM
 		CFLAGS=-g  $(PROFILE)
 		LDFLAGS+=-g -Wl,-E $(PROFILE)
 		MOD_LDFLAGS:=-shared $(LDFLAGS)
@@ -1357,27 +1360,27 @@ LIB_SUFFIX:=.so
 ifeq ($(OS), linux)
 # by default use futexes if available
 	use_futex= yes
-	DEFS+=-DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD \
+	C_DEFS+=-DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD \
 			-DHAVE_MSG_NOSIGNAL -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H \
 			-DHAVE_TIMEGM -DHAVE_SCHED_SETSCHEDULER
 	ifneq ($(found_lock_method), yes)
-		#DEFS+= -DUSE_POSIX_SEM
-		DEFS+=-DUSE_PTHREAD_MUTEX
+		#C_DEFS+= -DUSE_POSIX_SEM
+		C_DEFS+=-DUSE_PTHREAD_MUTEX
 		LIBS+= -lpthread
-		#DEFS+= -DUSE_SYSV_SEM  # try posix sems
+		#C_DEFS+= -DUSE_SYSV_SEM  # try posix sems
 		found_lock_method=yes
 	else
-		ifneq (,$(findstring -DUSE_POSIX_SEM, $(DEFS)))
+		ifneq (,$(findstring -DUSE_POSIX_SEM, $(C_DEFS)))
 			LIBS+=-lpthread
 		endif
-		ifneq (,$(findstring -DUSE_PTHREAD_MUTEX, $(DEFS)))
+		ifneq (,$(findstring -DUSE_PTHREAD_MUTEX, $(C_DEFS)))
 			LIBS+=-lpthread
 		endif
 	endif
 	# check for >= 2.5.44
 	ifeq ($(shell [ $(OSREL_N) -ge 2005044 ] && echo has_epoll), has_epoll)
 		ifeq ($(NO_EPOLL),)
-			DEFS+=-DHAVE_EPOLL
+			C_DEFS+=-DHAVE_EPOLL
 			# linux + gcc >= 3.0 + -malign-double + epoll => problems
 			CFLAGS_RM+=-malign-double
 			#CFLAGS:=$(filter-out -malign-double, $(CFLAGS))
@@ -1386,17 +1389,17 @@ ifeq ($(OS), linux)
 	# check for >= 2.2.0
 	ifeq ($(shell [ $(OSREL_N) -ge 2002000 ] && echo has_sigio), has_sigio)
 		ifeq ($(NO_SIGIO),)
-			DEFS+=-DHAVE_SIGIO_RT -DSIGINFO64_WORKARROUND
+			C_DEFS+=-DHAVE_SIGIO_RT -DSIGINFO64_WORKARROUND
 		endif
 	endif
 	# check for >= 2.5.70
 	ifeq ($(shell [ $(OSREL_N) -ge 2005070 ] && echo has_futex), has_futex)
 		ifeq ($(use_futex), yes)
-			DEFS+=-DUSE_FUTEX
+			C_DEFS+=-DUSE_FUTEX
 		endif
 	endif
 	ifeq ($(NO_SELECT),)
-		DEFS+=-DHAVE_SELECT
+		C_DEFS+=-DHAVE_SELECT
 	endif
 	# sctp support
 	ifeq ($(SCTP),1)
@@ -1418,27 +1421,27 @@ $(info "sctp libraries not installed -- sctp disabled")
 		
 		ifeq ($(SCTP),1)
 			# use lksctp
-			DEFS+=-DUSE_SCTP
+			C_DEFS+=-DUSE_SCTP
 			LIBS+=-lsctp
 		endif
 	endif # SCTP
 endif
 
 ifeq  ($(OS), solaris)
-	DEFS+= -DHAVE_GETIPNODEBYNAME -DHAVE_SYS_SOCKIO_H -DHAVE_SCHED_YIELD \
+	C_DEFS+= -DHAVE_GETIPNODEBYNAME -DHAVE_SYS_SOCKIO_H -DHAVE_SCHED_YIELD \
 			-DHAVE_ALLOCA_H -DUSE_SIGACTION
 	ifneq ($(found_lock_method), yes)
-		DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
+		C_DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
 		found_lock_method=yes
 	endif
 	# check for ver >= 5.7
 	ifeq ($(shell [ $(OSREL_N) -gt 5007 ] && echo has_devpoll), has_devpoll)
 		ifeq ($(NO_DEVPOLL),)
-			DEFS+=-DHAVE_DEVPOLL
+			C_DEFS+=-DHAVE_DEVPOLL
 		endif
 	endif
 	ifeq ($(NO_SELECT),)
-		DEFS+=-DHAVE_SELECT
+		C_DEFS+=-DHAVE_SELECT
 	endif
 	# check for filio.h
 	filio_h_locations= /usr/include/sys/filio.h \
@@ -1448,7 +1451,7 @@ ifeq  ($(OS), solaris)
 						done;\
 				)
 	ifeq ($(has_filio_h), yes)
-		DEFS+=-DHAVE_FILIO_H
+		C_DEFS+=-DHAVE_FILIO_H
 	endif
 	ifeq ($(mode), release)
 		#use these only if you're using gcc with Solaris ld
@@ -1475,12 +1478,12 @@ endif
 endif
 
 ifeq ($(OS), freebsd)
-	DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN \
+	C_DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN \
 		-DHAVE_SCHED_YIELD -DHAVE_MSGHDR_MSG_CONTROL \
 		-DHAVE_CONNECT_ECONNRESET_BUG -DHAVE_TIMEGM \
 		-DHAVE_NETINET_IN_SYSTM
 	ifneq ($(found_lock_method), yes)
-		DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
+		C_DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
 		found_lock_method=yes
 		LIBS+= -pthread   #dlopen is in libc
 	else
@@ -1489,11 +1492,11 @@ ifeq ($(OS), freebsd)
 	# check for ver >= 4.1
 	ifeq ($(shell [ $(OSREL_N) -gt 4001 ] && echo has_kqueue), has_kqueue)
 		ifeq ($(NO_KQUEUE),)
-			DEFS+=-DHAVE_KQUEUE
+			C_DEFS+=-DHAVE_KQUEUE
 		endif
 	endif
 	ifeq ($(NO_SELECT),)
-		DEFS+=-DHAVE_SELECT
+		C_DEFS+=-DHAVE_SELECT
 	endif
 	YACC=yacc
 	# sctp support
@@ -1512,29 +1515,29 @@ $(info "old freebsd version (>= 7.0 needed) -- sctp disabled")
 		endif
 		
 		ifeq ($(SCTP),1)
-			DEFS+=-DUSE_SCTP
+			C_DEFS+=-DUSE_SCTP
 			LIBS+=  # no extra libs needed on freebsd
 		endif
 	endif # SCTP
 endif
 
 ifeq ($(OS), openbsd)
-	DEFS+=-DHAVE_SOCKADDR_SA_LEN  -DHAVE_GETHOSTBYNAME2 \
+	C_DEFS+=-DHAVE_SOCKADDR_SA_LEN  -DHAVE_GETHOSTBYNAME2 \
 		-DHAVE_UNION_SEMUN -DHAVE_MSGHDR_MSG_CONTROL \
 		-DHAVE_CONNECT_ECONNRESET_BUG -DHAVE_TIMEGM \
 		-DHAVE_NETINET_IN_SYSTM -DUSE_SIGWAIT
 	ifneq ($(found_lock_method), yes)
-		DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
+		C_DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
 		found_lock_method=yes
 	endif
 	# check for ver >=2 9
 	ifeq ($(shell [ $(OSREL_N) -ge 2009 ] && echo has_kqueue), has_kqueue)
 		ifeq ($(NO_KQUEUE),)
-			DEFS+=-DHAVE_KQUEUE
+			C_DEFS+=-DHAVE_KQUEUE
 		endif
 	endif
 	ifeq ($(NO_SELECT),)
-		DEFS+=-DHAVE_SELECT
+		C_DEFS+=-DHAVE_SELECT
 	endif
 	# (symbols on openbsd are prefixed by "_")
 	YACC=yacc
@@ -1554,29 +1557,29 @@ endif
 endif
 	
 ifeq ($(OPENBSD_IS_AOUT), yes)
-		DEFS+=-DDLSYM_PREFIX='"_"'
+		C_DEFS+=-DDLSYM_PREFIX='"_"'
 		LDFLAGS=        # openbsd ld doesn't like -O2 or -E
 endif
 endif   # if opensd
 	
 ifeq ($(OS), netbsd)
-	DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 \
+	C_DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 \
 		-DHAVE_MSGHDR_MSG_CONTROL -DHAVE_CONNECT_ECONNRESET_BUG -DHAVE_TIMEGM
 	ifneq ($(found_lock_method), yes)
-		DEFS+= -DUSE_SYSV_SEM  # try pthread sems
+		C_DEFS+= -DUSE_SYSV_SEM  # try pthread sems
 		found_lock_method=yes
 	endif
 	# check for ver >= 2.0.0
 	ifeq ($(shell [ $(OSREL_N) -ge 2000000 ] && echo has_kqueue), has_kqueue)
 		ifeq ($(NO_KQUEUE),)
-			DEFS+=-DHAVE_KQUEUE
+			C_DEFS+=-DHAVE_KQUEUE
 			# netbsd + kqueue and -malign-double don't work
 			CFLAGS_RM+=-malign-double
 			#CFLAGS:=$(filter-out -malign-double, $(CFLAGS))
 		endif
 	endif
 	ifeq ($(NO_SELECT),)
-		DEFS+=-DHAVE_SELECT
+		C_DEFS+=-DHAVE_SELECT
 	endif
 	YACC=yacc
 	LIBS=  
@@ -1584,7 +1587,7 @@ endif
 
 # OS X support, same as freebsd
 ifeq ($(OS), darwin)
-	DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN \
+	C_DEFS+=-DHAVE_SOCKADDR_SA_LEN -DHAVE_GETHOSTBYNAME2 -DHAVE_UNION_SEMUN \
 		-DHAVE_SCHED_YIELD -DHAVE_MSGHDR_MSG_CONTROL \
 		-DUSE_ANON_MMAP \
 		-DNDEBUG -DHAVE_CONNECT_ECONNRESET_BUG -DHAVE_TIMEGM \
@@ -1592,18 +1595,18 @@ ifeq ($(OS), darwin)
 	# -DNDEBUG used to turn off assert (assert wants to call
 	# eprintf which doesn't seem to be defined in any shared lib
 	ifneq ($(found_lock_method), yes)
-		DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
+		C_DEFS+= -DUSE_PTHREAD_MUTEX  # try pthread sems
 		found_lock_method=yes
-		DEFS+= -DUSE_SYSV_SEM  # try sys v sems (pthread don't work for
+		C_DEFS+= -DUSE_SYSV_SEM  # try sys v sems (pthread don't work for
 		                       # processes and unnamed posix sems are not
 		                       # supported)
 	endif
 	LIBS= -lresolv  #dlopen is in libc
 	ifeq ($(NO_KQUEUE),)
-		DEFS+=-DHAVE_KQUEUE
+		C_DEFS+=-DHAVE_KQUEUE
 	endif
 	ifeq ($(NO_SELECT),)
-		DEFS+=-DHAVE_SELECT
+		C_DEFS+=-DHAVE_SELECT
 	endif
 	LDFLAGS=        # darwin doesn't like -O2 or -E
 	# the modules uses symbols from ser => either 
@@ -1621,34 +1624,34 @@ endif
 
 ifneq (,$(findstring cygwin, $(OS)))
 	# cygwin doesn't support IPV6 and doesn't support fd passing so no TCP
-	#DEFS:=$(filter-out -DUSE_IPV6 -DUSE_TCP, $(DEFS))
+	#C_DEFS:=$(filter-out -DUSE_IPV6 -DUSE_TCP, $(C_DEFS))
 	DEFS_RM+=-DUSE_IPV6 -DUSE_TCP
-	DEFS+=-DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD \
+	C_DEFS+=-DHAVE_UNION_SEMUN -DHAVE_SCHED_YIELD \
 			-DHAVE_MSG_NOSIGNAL -DHAVE_MSGHDR_MSG_CONTROL -DHAVE_ALLOCA_H \
 			-DHAVE_TIMEGM -DHAVE_SCHED_SETSCHEDULER
 	ifneq ($(found_lock_method), yes)
-		DEFS+= -DUSE_POSIX_SEM
-		#DEFS+= -DUSE_SYSV_SEM  # try posix sems
+		C_DEFS+= -DUSE_POSIX_SEM
+		#C_DEFS+= -DUSE_SYSV_SEM  # try posix sems
 		# PTHREAD_MUTEX do not work for processes (try test/pthread_test.c)
 		#LIBS+= -lpthread
 		found_lock_method=yes
 	else
-		ifneq (,$(findstring -DUSE_POSIX_SEM, $(DEFS)))
+		ifneq (,$(findstring -DUSE_POSIX_SEM, $(C_DEFS)))
 			#LIBS+=-lpthread
 		endif
-		ifneq (,$(findstring -DUSE_PTHREAD_MUTEX, $(DEFS)))
+		ifneq (,$(findstring -DUSE_PTHREAD_MUTEX, $(C_DEFS)))
 $(error PTHREAD_MUTEX do not work for processes on Windows/CYGWIN)
 		endif
 	endif
 	# check for >= 2.5.70
 	ifeq ($(NO_SELECT),)
-		DEFS+=-DHAVE_SELECT
+		C_DEFS+=-DHAVE_SELECT
 	endif
 endif
 
 #add libssl if needed
 ifeq ($(CORE_TLS), 1)
-DEFS+= -I$(LOCALBASE)/ssl/include
+C_DEFS+= -I$(LOCALBASE)/ssl/include
 LIBS+= -L$(LOCALBASE)/lib -L$(LOCALBASE)/ssl/lib -lssl -lcrypto \
 		$(TLS_EXTRA_LIBS)
 # NOTE: depending on the way in which libssl was compiled you might
@@ -1657,13 +1660,13 @@ LIBS+= -L$(LOCALBASE)/lib -L$(LOCALBASE)/ssl/lib -lssl -lcrypto \
 endif
 
 ifneq ($(STUN),)
-DEFS+= -I$(LOCALBASE)/ssl/include
+C_DEFS+= -I$(LOCALBASE)/ssl/include
 LIBS+= -L$(LOCALBASE)/lib -L$(LOCALBASE)/ssl/lib -lcrypto
 endif
 
 ifneq ($(found_lock_method), yes)
 $(warning	No locking method found so far, trying SYS V sems)
-		DEFS+= -DUSE_SYSV_SEM  # try sys v sems
+		C_DEFS+= -DUSE_SYSV_SEM  # try sys v sems
 		found_lock_method=yes
 endif
 
@@ -1685,7 +1688,7 @@ export exported_vars
 #  is run)
 saved_fixed_vars:=	MAIN_NAME \
 		RELEASE OS ARCH \
-		DEFS DEFS_RM PROFILE CC LD MKDEP MKTAGS LDFLAGS INCLUDES \
+		C_DEFS DEFS_RM PROFILE CC LD MKDEP MKTAGS LDFLAGS C_INCLUDES \
 		MOD_LDFLAGS LIB_LDFLAGS LIB_SONAME LD_RPATH \
 		LIB_SUFFIX LIB_PREFIX \
 		LIBS \

+ 2 - 3
Makefile.libs

@@ -20,7 +20,7 @@ endif
 
 ifneq	(,$(filter install% %install install, $(MAKECMDGOALS)))
 compile_for_install:=yes
-$(info install mode => compile_for_install=$(compile_for_install))
+$(info install mode)
 endif
 
 ifeq ($(NAME),)
@@ -157,8 +157,7 @@ endif
 .PHONY:install-if-newer
 install-if-newer: $(lib_prefix)/$(lib_dir)/$(LIB_RUNTIME_NAME) 
 
-$(lib_prefix)/$(lib_dir)/$(LIB_RUNTIME_NAME): $(LIB_NAME) $(LIBINAME_F)
-	@$(MAKE) install
+$(lib_prefix)/$(lib_dir)/$(LIB_RUNTIME_NAME): $(LIB_NAME) $(LIBINAME_F) install
 
 
 ifneq ($(strip $(LIBINAME_F)),)

+ 5 - 1
Makefile.modules

@@ -11,6 +11,9 @@
 #               installed if needed (andrei)
 #  2008-06-23  added the README & man targets (andrei)
 #  2008-06-27  make cfg / config.mak support (andrei)
+#  2009-03-10  replaced DEFS with C_DEFS and INCLUDES with C_INCLUDES (DEFS
+#              and INCLUDES are now used only for "temporary" defines/includes
+#              inside modules or libs) (andrei)
 #
 
 MOD_NAME=$(NAME:.so=)
@@ -26,9 +29,10 @@ override modules=
 override static_modules=
 override static_modules_path=
 
-# should be set in Makefile of apart module
+# should be set in the Makefile of each module
 # INCLUDES += -I$(COREPATH)
 
+# temporary def (visible only in the module, not exported)
 DEFS += -DMOD_NAME='"$(MOD_NAME)"'
 
 ifneq ($(makefile_defs_included),1)

+ 1 - 1
Makefile.radius

@@ -19,7 +19,7 @@
 # Radiusclient-ng is often installed from tarballs so we
 # need to look int /usr/local/lib as well
 #
-DEFS+=-I$(LOCALBASE)/include
+INCLUDES+=-I$(LOCALBASE)/include
 
 ifneq ($(radiusclient_ng), 4)
 

+ 19 - 13
Makefile.rules

@@ -6,7 +6,8 @@
 #
 
 #
-# Uses: NAME, ALLDEP, CC, CFLAGS, DEFS, INCLUDES, LIBS, MKDEP, auto_gen, 
+# Uses: NAME, ALLDEP, CC, CFLAGS, C_DEFS, DEFS, C_INCLUDES, INCLUDES, LIBS, 
+#       MKDEP, auto_gen, 
 # auto_gen_others, depends, objs, extra_objs, static_modules, 
 # static_modules_path, LD_RPATH
 # (all this must  be defined previously!,  see Makefile.defs & Makefile)
@@ -20,7 +21,10 @@
 #              automatically build listed SER_LIBS if needed (andrei)
 #  2008-06-23  automatically rebuild if make time defines or includes
 #              changed (via makecfg.lst)
-#
+#  2009-03-10  support for C_DEFS and C_INCLUDES (DEFS and INCLUDES are now
+#              used only for "temporary" defines/includes inside modules or
+#              libs, C_DEFS and C_INCLUDES are used for the common stuff)
+#              (andrei)
 
 
 # check if the saved cfg corresponds with the current one
@@ -30,17 +34,18 @@ ifeq (,$(filter $(nodep_targets),$(MAKECMDGOALS)))
 # if trying  to build a lib automatically and the lib is already compiled,
 # don't rebuild it if the only differences in DEFS or INCLUDES are covered
 # by LIB_NOREBUILD_DEFS/LIB_NOREBUILD_INCLUDES
-LIB_NOREBUILD_DEFS+= -DMOD_NAME% -D%_MOD_INTERFACE -DMOD_INTERFACE_% -DSR_%
+LIB_NOREBUILD_DEFS=
 
 # don't rebuild if the differences are covered by NOREBUILD_DEFS or 
 # NOREBUILD_INCLUDES
-ifneq ($(filter-out $(NOREBUILD_DEFS),$(strip $(DEFS))), $(strip $(CFG_DEFS)))
+ifneq ($(strip $(filter-out $(NOREBUILD_DEFS),\
+		$(C_DEFS) $(DEFS))),$(strip $(CFG_DEFS)))
 #$(warning different defs: <$(strip $(DEFS))> != )
 #$(warning               : <$(strip $(CFG_DEFS))>)
 $(shell rm -f makecfg.lst)
 endif
-ifneq ($(filter-out $(NOREBUILD_INCLUDES), $(strip $(INCLUDES))),\
-		$(strip $(CFG_INCLUDES)))
+ifneq ($(strip $(filter-out $(NOREBUILD_INCLUDES),\
+			$(C_INCLUDES) $(INCLUDES))),$(strip $(CFG_INCLUDES)))
 $(shell rm -f makecfg.lst)
 endif
 endif
@@ -49,10 +54,10 @@ ALLDEP+=makecfg.lst
 
 #implicit rules
 %.o:%.c  $(ALLDEP)
-	$(CC) $(CFLAGS) $(INCLUDES) $(DEFS) -c $< -o $@
+	$(CC) $(CFLAGS) $(C_INCLUDES) $(INCLUDES) $(C_DEFS) $(DEFS) -c $< -o $@
 
 %.d: %.c $(ALLDEP)
-	@set -e; $(MKDEP) $(CFLAGS) $(INCLUDES) $(DEFS) $< \
+	@set -e; $(MKDEP) $(CFLAGS) $(C_INCLUDES) $(INCLUDES) $(C_DEFS) $(DEFS) $<\
 	    |  sed 's#\(\($(*D)/\)\{0,1\}$(*F)\)\.o[ :]*#$*.o $@ : #g' > $@; \
 	    test -s $@ || ( rm -f $@; false )
 
@@ -66,7 +71,7 @@ ifneq	(,$(filter install install% %install, $(MAKECMDGOALS)))
 lib_compile_for_install=yes
 expected_lib_ipath=$(lib_target)
 else
-lib_compile_for_install=no
+lib_compile_for_install=$(compile_for_install)
 # function: expected_lib_ipath ser_lib_dir
 expected_lib_ipath=$(1)
 endif
@@ -144,10 +149,11 @@ librpath.lst: $(ALLDEP)
 	@echo LIB_RPATH_LST:=$(SER_RPATH_LST) >librpath.lst
 
 makecfg.lst:
-	@echo CFG_DEFS:=$(subst ',\', $(subst ",\", \
-		$(filter-out $(NOREBUILD_DEFS), $(strip $(DEFS))))) >>$@
-	@echo CFG_INCLUDES:=$(subst ',\', $(subst ",\", \
-		$(filter-out $(NOREBUILD_INCLUDES), $(strip $(INCLUDES))))) >>$@
+	@echo CFG_DEFS:=$(subst ',\', $(subst ",\",$(strip \
+			$(filter-out $(NOREBUILD_DEFS), $(C_DEFS) $(DEFS))))) >>$@
+	@echo CFG_INCLUDES:=$(subst ',\', $(subst ",\",$(strip \
+			$(filter-out $(NOREBUILD_INCLUDES),\
+				$(C_INCLUDES) $(INCLUDES))))) >>$@
 .PHONY: all
 all: $(NAME) modules
 

+ 14 - 0
NEWS

@@ -256,6 +256,20 @@ core:
                between the short name and long name in cache as CNAME record
 
 new config variables:
+  tcp_rd_buf_size = buffer size used for tcp reads.
+                    A high buffer size increases performance on server with few
+                    connections and lot of traffic on them, but also increases
+                     memory consumption (so for lots of connection is better 
+                    to use a low value). Note also that this value limits the
+                    maximum datagram size that can be received over tcp.
+                    Default: 4096, can be changed at runtime.
+  tcp_wq_blk_size = block size used for tcp async writes. It should be big
+                    enough to hold a few datagrams. If it's smaller then a
+                    datagram (in fact a tcp write()) size, it will be rounded
+                    up. It has no influenced on the number of datagrams 
+                    queued (for that see tcp_conn_wq_max or tcp_wq_max).
+                    It has mostly debugging and testing value (can be ignored).
+                    Default: 2100 (~ 2 INVITEs), can be changed at runtime.
   tcp_no_connect = yes/no - disable connects, ser will only accept new 
                      connections, it will never try to open new ones.
                      Default: no, can be changed at runtime.

+ 115 - 15
action.c

@@ -122,7 +122,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 	struct rvalue* rv1;
 	struct rval_cache c1;
 	str s;
-
+	int orig_p2t;
 
 	/* reset the value of error to E_UNSPEC so avoid unknowledgable
 	   functions to return with error (status<0) and not setting it
@@ -498,18 +498,22 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 		case PREFIX_T:
 		case STRIP_T:
 		case STRIP_TAIL_T:
+		case SET_USERPHONE_T:
 				user=0;
 				if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
 					if (a->val[0].type!=NUMBER_ST) {
 						LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
 							a->val[0].type);
+						ret=E_BUG;
 						break;
 					}
-				} else if (a->val[0].type!=STRING_ST){
-					LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
+				} else if (a->type!=SET_USERPHONE_T) {
+					if (a->val[0].type!=STRING_ST) {
+						LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
 							a->val[0].type);
-					ret=E_BUG;
-					break;
+						ret=E_BUG;
+						break;
+					}
 				}
 				if (a->type==SET_URI_T){
 					if (msg->new_uri.s) {
@@ -532,7 +536,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 					ret=1;
 					break;
 				}
-				if (msg->parsed_uri_ok==0) {
+				if ((msg->parsed_uri_ok==0) || ((uri.flags & URI_SIP_USER_PHONE)!=0)) {
 					if (msg->new_uri.s) {
 						tmp=msg->new_uri.s;
 						len=msg->new_uri.len;
@@ -540,16 +544,41 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 						tmp=msg->first_line.u.request.uri.s;
 						len=msg->first_line.u.request.uri.len;
 					}
+					/* don't convert sip:user=phone to tel, otherwise we loose parameters */
+					orig_p2t=phone2tel;
+					phone2tel=0;
+					msg->parsed_uri_ok=0;
 					if (parse_uri(tmp, len, &uri)<0){
+						phone2tel=orig_p2t;
 						LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
 									" packet\n", tmp);
 						ret=E_UNSPEC;
 						break;
 					}
+					phone2tel=orig_p2t;
 				} else {
 					uri=msg->parsed_uri;
 				}
 
+				/* skip SET_USERPHONE_T action if the URI is already
+				 * a tel: or tels: URI, or contains the user=phone param */
+				if ((a->type==SET_USERPHONE_T) 
+					&& ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T)
+						|| ((uri.user_param_val.len==5) && (memcmp(uri.user_param_val.s, "phone", 5)==0)))
+				) {
+					ret=1;
+					break;
+				}
+				/* SET_PORT_T does not work with tel: URIs */
+				if ((a->type==SET_PORT_T)
+					&& ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
+					&& ((uri.flags & URI_SIP_USER_PHONE)==0)
+				) {
+					LOG(L_ERR, "ERROR: do_action: port number of a tel: URI cannot be set\n");
+					ret=E_UNSPEC;
+					break;
+				}
+
 				new_uri=pkg_malloc(MAX_URI_SIZE);
 				if (new_uri==0){
 					LOG(L_ERR, "ERROR: do_action: memory allocation "
@@ -560,8 +589,57 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 				end=new_uri+MAX_URI_SIZE;
 				crt=new_uri;
 				/* begin copying */
-				len=strlen("sip:"); if(crt+len>end) goto error_uri;
-				memcpy(crt,"sip:",len);crt+=len;
+				/* Preserve the URI scheme unless the host part needs
+				 * to be rewritten, and the shceme is tel: or tels: */
+				switch (uri.type) {
+				case SIP_URI_T:
+					len=s_sip.len;
+					tmp=s_sip.s;
+					break;
+
+				case SIPS_URI_T:
+					len=s_sips.len;
+					tmp=s_sips.s;
+					break;
+
+				case TEL_URI_T:
+					if ((uri.flags & URI_SIP_USER_PHONE)
+						|| (a->type==SET_HOST_T)
+						|| (a->type==SET_HOSTPORT_T)
+						|| (a->type==SET_HOSTPORTTRANS_T)
+					) {
+						len=s_sip.len;
+						tmp=s_sip.s;
+						break;
+					}
+					len=s_tel.len;
+					tmp=s_tel.s;
+					break;
+
+				case TELS_URI_T:
+					if ((uri.flags & URI_SIP_USER_PHONE)
+						|| (a->type==SET_HOST_T)
+						|| (a->type==SET_HOSTPORT_T)
+						|| (a->type==SET_HOSTPORTTRANS_T)
+					) {
+						len=s_sips.len;
+						tmp=s_sips.s;
+						break;
+					}
+					len=s_tels.len;
+					tmp=s_tels.s;
+					break;
+
+				default:
+					LOG(L_ERR, "ERROR: Unsupported URI scheme (%d), "
+						"reverted to sip:\n",
+						uri.type);
+					len=s_sip.len;
+					tmp=s_sip.s;
+				}
+				if(crt+len+1 /* colon */ >end) goto error_uri;
+				memcpy(crt,tmp,len);crt+=len;
+				*crt=':'; crt++;
 
 				/* user */
 
@@ -622,22 +700,28 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 					memcpy(crt,tmp,len);crt+=len;
 				}
 				/* host */
-				if (user || tmp){ /* add @ */
-					if(crt+1>end) goto error_uri;
-					*crt='@'; crt++;
-				}
 				if ((a->type==SET_HOST_T)
 						|| (a->type==SET_HOSTPORT_T)
 						|| (a->type==SET_HOSTALL_T)
-						|| (a->type==SET_HOSTPORTTRANS_T)) {
+						|| (a->type==SET_HOSTPORTTRANS_T)
+				) {
 					tmp=a->val[0].u.string;
 					if (tmp) len = strlen(tmp);
 					else len=0;
-				} else {
+				} else if ((uri.type==SIP_URI_T)
+					|| (uri.type==SIPS_URI_T)
+					|| (uri.flags & URI_SIP_USER_PHONE)
+				) {
 					tmp=uri.host.s;
-					len = uri.host.len;
+					len=uri.host.len;
+				} else {
+					tmp=0;
 				}
 				if (tmp){
+					if (user) { /* add @ */
+						if(crt+1>end) goto error_uri;
+						*crt='@'; crt++;
+					}
 					if(crt+len>end) goto error_uri;
 					memcpy(crt,tmp,len);crt+=len;
 				}
@@ -687,6 +771,22 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
 						memcpy(crt,tmp,len);crt+=len;
 					}
 				}
+				/* Add the user=phone param if a tel: or tels:
+				 * URI was converted to sip: or sips:.
+				 * (host part of a tel/tels URI was set.)
+				 * Or in case of sip: URI and SET_USERPHONE_T action */
+				if (((((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
+					&& ((uri.flags & URI_SIP_USER_PHONE)==0))
+					&& ((a->type==SET_HOST_T)
+						|| (a->type==SET_HOSTPORT_T)
+						|| (a->type==SET_HOSTPORTTRANS_T)))
+					|| (a->type==SET_USERPHONE_T)
+				) {
+					tmp=";user=phone";
+					len=strlen(tmp);
+					if(crt+len>end) goto error_uri;
+					memcpy(crt,tmp,len);crt+=len;
+				}
 				/* headers */
 				tmp=uri.headers.s;
 				if (tmp){

+ 10 - 0
cfg.lex

@@ -77,6 +77,7 @@
  *  2008-01-24  added CFG_DESCRIPTION used by cfg_var (Miklos)
  *  2008-11-28  added support for kamailio pvars and avp/pvar guessing (andrei)
  *  2008-12-11  added support for "string1" "string2" (andrei)
+ *  2009-03-10  added SET_USERPHONE action (Miklos)
 */
 
 
@@ -183,6 +184,7 @@ REVERT_URI		"revert_uri"
 PREFIX			"prefix"
 STRIP			"strip"
 STRIP_TAIL		"strip_tail"
+SET_USERPHONE		"userphone"
 APPEND_BRANCH	"append_branch"
 IF				"if"
 ELSE			"else"
@@ -332,6 +334,8 @@ TCP_OPT_FD_CACHE	"tcp_fd_cache"
 TCP_OPT_BUF_WRITE	"tcp_buf_write"|"tcp_async"
 TCP_OPT_CONN_WQ_MAX	"tcp_conn_wq_max"
 TCP_OPT_WQ_MAX		"tcp_wq_max"
+TCP_OPT_RD_BUF		"tcp_rd_buf_size"
+TCP_OPT_WQ_BLK		"tcp_wq_blk_size"
 TCP_OPT_DEFER_ACCEPT "tcp_defer_accept"
 TCP_OPT_DELAYED_ACK	"tcp_delayed_ack"
 TCP_OPT_SYNCNT		"tcp_syncnt"
@@ -491,6 +495,8 @@ EAT_ABLE	[\ \t\b\r]
 <INITIAL>{STRIP_TAIL}	{ count(); yylval.strval=yytext; return STRIP_TAIL; }
 <INITIAL>{APPEND_BRANCH}	{ count(); yylval.strval=yytext;
 								return APPEND_BRANCH; }
+<INITIAL>{SET_USERPHONE}	{ count(); yylval.strval=yytext;
+								return SET_USERPHONE; }
 <INITIAL>{FORCE_RPORT}	{ count(); yylval.strval=yytext; return FORCE_RPORT; }
 <INITIAL>{FORCE_TCP_ALIAS}	{ count(); yylval.strval=yytext;
 								return FORCE_TCP_ALIAS; }
@@ -637,6 +643,10 @@ EAT_ABLE	[\ \t\b\r]
 									return TCP_OPT_CONN_WQ_MAX; }
 <INITIAL>{TCP_OPT_WQ_MAX}	{ count(); yylval.strval=yytext;
 									return TCP_OPT_WQ_MAX; }
+<INITIAL>{TCP_OPT_RD_BUF}	{ count(); yylval.strval=yytext;
+									return TCP_OPT_RD_BUF; }
+<INITIAL>{TCP_OPT_WQ_BLK}	{ count(); yylval.strval=yytext;
+									return TCP_OPT_WQ_BLK; }
 <INITIAL>{TCP_OPT_BUF_WRITE}	{ count(); yylval.strval=yytext;
 									return TCP_OPT_BUF_WRITE; }
 <INITIAL>{TCP_OPT_DEFER_ACCEPT}	{ count(); yylval.strval=yytext;

+ 31 - 5
cfg.y

@@ -94,6 +94,7 @@
  * 2007-12-06  expression are now evaluated in terms of rvalues;
  *             NUMBER is now always positive; cleanup (andrei)
  * 2009-01-26  case/switch() support (andrei)
+ * 2009-03-10  added SET_USERPHONE action (Miklos)
 */
 
 %{
@@ -137,6 +138,7 @@
 #ifdef CORE_TLS
 #include "tls/tls_config.h"
 #endif
+#include "timer_ticks.h"
 
 #ifdef DEBUG_DMALLOC
 #include <dmalloc.h>
@@ -271,6 +273,7 @@ static int case_check_default(struct case_stms* stms);
 %token PREFIX
 %token STRIP
 %token STRIP_TAIL
+%token SET_USERPHONE
 %token APPEND_BRANCH
 %token SET_USER
 %token SET_USERPASS
@@ -396,6 +399,8 @@ static int case_check_default(struct case_stms* stms);
 %token TCP_OPT_BUF_WRITE
 %token TCP_OPT_CONN_WQ_MAX
 %token TCP_OPT_WQ_MAX
+%token TCP_OPT_RD_BUF
+%token TCP_OPT_WQ_BLK
 %token TCP_OPT_DEFER_ACCEPT
 %token TCP_OPT_DELAYED_ACK
 %token TCP_OPT_SYNCNT
@@ -839,7 +844,7 @@ assign_stm:
 	| TCP_CONNECT_TIMEOUT EQUAL error { yyerror("number expected"); }
 	| TCP_SEND_TIMEOUT EQUAL intno {
 		#ifdef USE_TCP
-			tcp_default_cfg.send_timeout_s=$3;
+			tcp_default_cfg.send_timeout=S_TO_TICKS($3);
 		#else
 			warn("tcp support not compiled in");
 		#endif
@@ -847,7 +852,10 @@ assign_stm:
 	| TCP_SEND_TIMEOUT EQUAL error { yyerror("number expected"); }
 	| TCP_CON_LIFETIME EQUAL intno {
 		#ifdef USE_TCP
-			tcp_default_cfg.con_lifetime_s=$3;
+			if ($3<0)
+				tcp_default_cfg.con_lifetime=-1;
+			else
+				tcp_default_cfg.con_lifetime=S_TO_TICKS($3);
 		#else
 			warn("tcp support not compiled in");
 		#endif
@@ -953,7 +961,23 @@ assign_stm:
 			warn("tcp support not compiled in");
 		#endif
 	}
-	| TCP_OPT_WQ_MAX error { yyerror("boolean value expected"); }
+	| TCP_OPT_WQ_MAX error { yyerror("number expected"); }
+	| TCP_OPT_RD_BUF EQUAL NUMBER {
+		#ifdef USE_TCP
+			tcp_default_cfg.rd_buf_size=$3;
+		#else
+			warn("tcp support not compiled in");
+		#endif
+	}
+	| TCP_OPT_RD_BUF error { yyerror("number expected"); }
+	| TCP_OPT_WQ_BLK EQUAL NUMBER {
+		#ifdef USE_TCP
+			tcp_default_cfg.wq_blk_size=$3;
+		#else
+			warn("tcp support not compiled in");
+		#endif
+	}
+	| TCP_OPT_WQ_BLK error { yyerror("number expected"); }
 	| TCP_OPT_DEFER_ACCEPT EQUAL NUMBER {
 		#ifdef USE_TCP
 			tcp_default_cfg.defer_accept=$3;
@@ -1315,10 +1339,10 @@ assign_stm:
 	| UDP_MTU EQUAL NUMBER { default_core_cfg.udp_mtu=$3; }
 	| UDP_MTU EQUAL error { yyerror("number expected"); }
 	| FORCE_RPORT EQUAL NUMBER 
-		{ default_core_cfg.force_rport=$3; fix_global_req_flags(0); }
+		{ default_core_cfg.force_rport=$3; fix_global_req_flags(0, 0); }
 	| FORCE_RPORT EQUAL error { yyerror("boolean value expected"); }
 	| UDP_MTU_TRY_PROTO EQUAL proto
-		{ default_core_cfg.udp_mtu_try_proto=$3; fix_global_req_flags(0); }
+		{ default_core_cfg.udp_mtu_try_proto=$3; fix_global_req_flags(0, 0); }
 	| UDP_MTU_TRY_PROTO EQUAL error
 		{ yyerror("TCP, TLS, SCTP or UDP expected"); }
 	| cfg_var
@@ -2546,6 +2570,8 @@ cmd:
 	| STRIP LPAREN NUMBER RPAREN { $$=mk_action(STRIP_T, 1, NUMBER_ST, (void*) $3); }
 	| STRIP error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| STRIP LPAREN error RPAREN { $$=0; yyerror("bad argument, number expected"); }
+	| SET_USERPHONE LPAREN RPAREN { $$=mk_action(SET_USERPHONE_T, 0); }
+	| SET_USERPHONE error { $$=0; yyerror("missing '(' or ')' ?"); }
 	| APPEND_BRANCH LPAREN STRING COMMA STRING RPAREN {
 		qvalue_t q;
 		if (str2q(&q, $5, strlen($5)) < 0) {

+ 2 - 2
cfg/cfg.h

@@ -56,8 +56,8 @@
 /* variable is read-only */
 #define CFG_READONLY		(1U<<(2*CFG_INPUT_SHIFT+1))
 
-typedef int (*cfg_on_change)(void *, str *, void **);
-typedef void (*cfg_on_set_child)(str *);
+typedef int (*cfg_on_change)(void *, str *, str *, void **);
+typedef void (*cfg_on_set_child)(str *, str *);
 
 /* strutrure to be used by the module interface */
 typedef struct _cfg_def {

+ 14 - 8
cfg/cfg_ctx.c

@@ -258,7 +258,7 @@ int cfg_set_now(cfg_ctx_t *ctx, str *group_name, str *var_name,
 	cfg_mapping_t	*var;
 	void		*p, *v;
 	cfg_block_t	*block = NULL;
-	str		s;
+	str		s, s2;
 	char		*old_string = NULL;
 	char		**replaced = NULL;
 	cfg_child_cb_t	*child_cb = NULL;
@@ -300,6 +300,7 @@ int cfg_set_now(cfg_ctx_t *ctx, str *group_name, str *var_name,
 		There is no need to set a temporary cfg handle,
 		becaue a single variable is changed */
 		if (var->def->on_change_cb(*(group->handle),
+						group_name,
 						var_name,
 						&v) < 0) {
 			LOG(L_ERR, "ERROR: cfg_set_now(): fixup failed\n");
@@ -311,9 +312,11 @@ int cfg_set_now(cfg_ctx_t *ctx, str *group_name, str *var_name,
 	if (var->def->on_set_child_cb) {
 		/* get the name of the variable from the internal struct,
 		because var_name may be freed before the callback needs it */
-		s.s = var->def->name;
-		s.len = var->name_len;
-		child_cb = cfg_child_cb_new(&s,
+		s.s = group->name;
+		s.len = group->name_len;
+		s2.s = var->def->name;
+		s2.len = var->name_len;
+		child_cb = cfg_child_cb_new(&s, &s2,
 					var->def->on_set_child_cb);
 		if (!child_cb) {
 			LOG(L_ERR, "ERROR: cfg_set_now(): not enough shm memory\n");
@@ -579,6 +582,7 @@ int cfg_set_delayed(cfg_ctx_t *ctx, str *group_name, str *var_name,
 		}
 			
 		if (var->def->on_change_cb(temp_handle,
+						group_name,
 						var_name,
 						&v) < 0) {
 			LOG(L_ERR, "ERROR: cfg_set_delayed(): fixup failed\n");
@@ -711,7 +715,7 @@ int cfg_commit(cfg_ctx_t *ctx)
 	cfg_child_cb_t	*child_cb_last = NULL;
 	int	size;
 	void	*p;
-	str	s;
+	str	s, s2;
 
 	if (!ctx) {
 		LOG(L_ERR, "ERROR: cfg_commit(): context is undefined\n");
@@ -740,9 +744,11 @@ int cfg_commit(cfg_ctx_t *ctx)
 
 
 		if (changed->var->def->on_set_child_cb) {
-			s.s = changed->var->def->name;
-			s.len = changed->var->name_len;
-			child_cb = cfg_child_cb_new(&s,
+			s.s = changed->group->name;
+			s.len = changed->group->name_len;
+			s2.s = changed->var->def->name;
+			s2.len = changed->var->name_len;
+			child_cb = cfg_child_cb_new(&s, &s2,
 					changed->var->def->on_set_child_cb);
 			if (!child_cb) goto error0;
 

+ 6 - 2
cfg/cfg_struct.c

@@ -317,7 +317,7 @@ int cfg_init(void)
 	This stucture will be the entry point for the child processes, and
 	will be freed later, when none of the processes refers to it */
 	*cfg_child_cb_first = *cfg_child_cb_last =
-		cfg_child_cb_new(NULL, NULL);
+		cfg_child_cb_new(NULL, NULL, NULL);
 
 	if (!*cfg_child_cb_first) goto error;
 
@@ -552,7 +552,7 @@ void cfg_install_global(cfg_block_t *block, char **replaced,
 }
 
 /* creates a structure for a per-child process callback */
-cfg_child_cb_t *cfg_child_cb_new(str *name, cfg_on_set_child cb)
+cfg_child_cb_t *cfg_child_cb_new(str *gname, str *name, cfg_on_set_child cb)
 {
 	cfg_child_cb_t	*cb_struct;
 
@@ -562,6 +562,10 @@ cfg_child_cb_t *cfg_child_cb_new(str *name, cfg_on_set_child cb)
 		return NULL;
 	}
 	memset(cb_struct, 0, sizeof(cfg_child_cb_t));
+	if (gname) {
+		cb_struct->gname.s = gname->s;
+		cb_struct->gname.len = gname->len;
+	}
 	if (name) {
 		cb_struct->name.s = name->s;
 		cb_struct->name.len = name->len;

+ 3 - 3
cfg/cfg_struct.h

@@ -98,7 +98,7 @@ typedef struct _cfg_block {
 typedef struct _cfg_child_cb {
 	atomic_t		refcnt; /* number of child processes
 					referring to the element */
-	str			name;	/* name of the variable that has changed */
+	str			gname, name;	/* name of the variable that has changed */
 	cfg_on_set_child	cb;	/* callback function that has to be called */
 
 	struct _cfg_child_cb	*next;
@@ -232,7 +232,7 @@ static inline void cfg_update_local(void)
 			}
 		}
 		/* execute the callback */
-		cfg_child_cb->cb(&cfg_child_cb->name);
+		cfg_child_cb->cb(&cfg_child_cb->gname, &cfg_child_cb->name);
 	}
 }
 
@@ -280,7 +280,7 @@ void cfg_install_global(cfg_block_t *block, char **replaced,
 			cfg_child_cb_t *cb_first, cfg_child_cb_t *cb_last);
 
 /* creates a structure for a per-child process callback */
-cfg_child_cb_t *cfg_child_cb_new(str *name, cfg_on_set_child cb);
+cfg_child_cb_t *cfg_child_cb_new(str *gname, str *name, cfg_on_set_child cb);
 
 /* free the memory allocated for a child cb list */
 void cfg_child_cb_free(cfg_child_cb_t *child_cb_first);

+ 3 - 4
core_cmd.c

@@ -567,10 +567,10 @@ static void core_tcp_options(rpc_t* rpc, void* c)
 	if (!tcp_disable){
 		tcp_options_get(&t);
 		rpc->add(c, "{", &handle);
-		rpc->struct_add(handle, "ddddddddddddddddddddddd",
+		rpc->struct_add(handle, "dddddddddddddddddddddd",
 			"connect_timeout", t.connect_timeout_s,
-			"send_timeout",  t.send_timeout_s,
-			"connection_lifetime",  t.con_lifetime_s,
+			"send_timeout",  TICKS_TO_S(t.send_timeout),
+			"connection_lifetime",  TICKS_TO_S(t.con_lifetime),
 			"max_connections(soft)", t.max_connections,
 			"no_connect",	t.no_connect,
 			"fd_cache",		t.fd_cache,
@@ -578,7 +578,6 @@ static void core_tcp_options(rpc_t* rpc, void* c)
 			"connect_wait",	t.tcp_connect_wait,
 			"conn_wq_max",	t.tcpconn_wq_max,
 			"wq_max",		t.tcp_wq_max,
-			"wq_timeout",	TICKS_TO_S(t.tcp_wq_timeout),
 			"defer_accept",	t.defer_accept,
 			"delayed_ack",	t.delayed_ack,
 			"syncnt",		t.syncnt,

+ 5 - 5
dns_cache.c

@@ -265,7 +265,7 @@ void destroy_dns_cache()
 }
 
 /* set the value of dns_flags */
-void fix_dns_flags(str *name)
+void fix_dns_flags(str *gname, str *name)
 {
 	/* restore the original value of dns_cache_flags first
 	 * (DNS_IPV4_ONLY may have been set only because dns_try_ipv6
@@ -300,7 +300,7 @@ void fix_dns_flags(str *name)
 /* fixup function for use_dns_failover
  * verifies that use_dns_cache is set to 1
  */
-int use_dns_failover_fixup(void *handle, str *name, void **val)
+int use_dns_failover_fixup(void *handle, str *gname, str *name, void **val)
 {
 	if ((int)(long)(*val) && !cfg_get(core, handle, use_dns_cache)) {
 		LOG(L_ERR, "ERROR: use_dns_failover_fixup(): "
@@ -314,7 +314,7 @@ int use_dns_failover_fixup(void *handle, str *name, void **val)
 /* fixup function for use_dns_cache
  * verifies that dns_cache_init is set to 1
  */
-int use_dns_cache_fixup(void *handle, str *name, void **val)
+int use_dns_cache_fixup(void *handle, str *gname, str *name, void **val)
 {
 	if ((int)(long)(*val) && !dns_cache_init) {
 		LOG(L_ERR, "ERROR: use_dns_cache_fixup(): "
@@ -332,7 +332,7 @@ int use_dns_cache_fixup(void *handle, str *name, void **val)
 }
 
 /* KByte to Byte conversion */
-int dns_cache_max_mem_fixup(void *handle, str *name, void **val)
+int dns_cache_max_mem_fixup(void *handle, str *gname, str *name, void **val)
 {
 	unsigned int    u;
 
@@ -407,7 +407,7 @@ int init_dns_cache()
 	if (default_core_cfg.use_dns_cache==0)
 		default_core_cfg.use_dns_failover=0; /* cannot work w/o dns_cache support */
 	/* fix flags */
-	fix_dns_flags(NULL);
+	fix_dns_flags(NULL, NULL);
 
 	dns_timer_h=timer_alloc();
 	if (dns_timer_h==0){

+ 4 - 4
dns_cache.h

@@ -178,10 +178,10 @@ struct dns_srv_handle{
 
 const char* dns_strerror(int err);
 
-void fix_dns_flags(str *name);
-int use_dns_failover_fixup(void *handle, str *name, void **val);
-int use_dns_cache_fixup(void *handle, str *name, void **val);
-int dns_cache_max_mem_fixup(void *handle, str *name, void **val);
+void fix_dns_flags(str *gname, str *name);
+int use_dns_failover_fixup(void *handle, str *gname, str *name, void **val);
+int use_dns_cache_fixup(void *handle, str *gname, str *name, void **val);
+int dns_cache_max_mem_fixup(void *handle, str *gname, str *name, void **val);
 int init_dns_cache();
 #ifdef USE_DNS_CACHE_STATS
 int init_dns_cache_stats(int iproc_num);

+ 2 - 2
doc/cfg.txt

@@ -129,7 +129,7 @@ Each row consists of the following items:
   handle within the fixup function. String and str values are cloned to
   shm memory by the framework. The callback type is:
 
-  typedef int (*cfg_on_change)(void *temp_handle, str *var_name, void **value);
+  typedef int (*cfg_on_change)(void *temp_handle, str *group_name, str *var_name, void **value);
 
 - per-child process callback function (optional) that is called by each child
   process separately, after the new values have been committed, and the
@@ -137,7 +137,7 @@ Each row consists of the following items:
   longer be used by the process. (Useful for fix-ups that cannot be done
   in shm memory, for example regexp compilation.)
 
-  typedef void (*cfg_on_set_child)(str *var_name);
+  typedef void (*cfg_on_set_child)(str *group_name, str *var_name);
 
 - description of the variable
 

+ 1 - 1
dprint.c

@@ -84,7 +84,7 @@ int str2facility(char *s)
 }
 
 /* fixup function for log_facility cfg parameter */
-int log_facility_fixup(void *handle, str *name, void **val)
+int log_facility_fixup(void *handle, str *gname, str *name, void **val)
 {
 	int	i;
 

+ 1 - 1
dprint.h

@@ -115,7 +115,7 @@ extern volatile int dprint_crit;
 #endif
 
 int str2facility(char *s);
-int log_facility_fixup(void *handle, str *name, void **val);
+int log_facility_fixup(void *handle, str *gname, str *name, void **val);
 
 
 /*

+ 2 - 2
dst_blacklist.c

@@ -1176,7 +1176,7 @@ void dst_blst_add(rpc_t* rpc, void* ctx)
 /* fixup function for use_dst_blacklist
  * verifies that dst_blacklist_init is set to 1
  */
-int use_dst_blacklist_fixup(void *handle, str *name, void **val)
+int use_dst_blacklist_fixup(void *handle, str *gname, str *name, void **val)
 {
 	if ((int)(long)(*val) && !dst_blacklist_init) {
 		LOG(L_ERR, "ERROR: use_dst_blacklist_fixup(): "
@@ -1188,7 +1188,7 @@ int use_dst_blacklist_fixup(void *handle, str *name, void **val)
 }
 
 /* KByte to Byte conversion */
-int blst_max_mem_fixup(void *handle, str *name, void **val)
+int blst_max_mem_fixup(void *handle, str *gname, str *name, void **val)
 {
 	unsigned int	u;
 

+ 2 - 2
dst_blacklist.h

@@ -116,8 +116,8 @@ int dst_blacklist_del(struct dest_info* si, struct sip_msg* msg);
  */
 void dst_blst_flush(void);
 
-int use_dst_blacklist_fixup(void *handle, str *name, void **val);
+int use_dst_blacklist_fixup(void *handle, str *gname, str *name, void **val);
 /* KByte to Byte conversion */
-int blst_max_mem_fixup(void *handle, str *name, void **val);
+int blst_max_mem_fixup(void *handle, str *gname, str *name, void **val);
 
 #endif

+ 1 - 1
modules/tm/t_cancel.c

@@ -392,7 +392,7 @@ int cancel_b_flags_get(unsigned int* f, int m)
 
 /* fixup function for the default cancel branch method/flags
  * (called by the configuration framework) */
-int cancel_b_flags_fixup(void* handle, str* name, void** val)
+int cancel_b_flags_fixup(void* handle, str* gname, str* name, void** val)
 {
 	unsigned int m,f;
 	int ret;

+ 1 - 1
modules/tm/t_cancel.h

@@ -115,7 +115,7 @@ inline short static should_cancel_branch( struct cell *t, int b, int noreply )
 
 const char* rpc_cancel_doc[2];
 void rpc_cancel(rpc_t* rpc, void* c);
-int cancel_b_flags_fixup(void* handle, str* name, void** val);
+int cancel_b_flags_fixup(void* handle, str* gname, str* name, void** val);
 int cancel_b_flags_get(unsigned int* f, int m);
 
 #endif

+ 1 - 1
modules/tm/t_fwd.c

@@ -1299,7 +1299,7 @@ int t_replicate(struct sip_msg *p_msg,  struct proxy_l *proxy, int proto )
 }
 
 /* fixup function for reparse_on_dns_failover modparam */
-int reparse_on_dns_failover_fixup(void *handle, str *name, void **val)
+int reparse_on_dns_failover_fixup(void *handle, str *gname, str *name, void **val)
 {
 #ifdef USE_DNS_FAILOVER
 	if ((int)(long)(*val) && mhomed) {

+ 1 - 1
modules/tm/t_fwd.h

@@ -76,7 +76,7 @@ int t_send_branch( struct cell *t, int branch, struct sip_msg* p_msg ,
 					struct proxy_l * proxy, int lock_replies);
 int t_relay_cancel(struct sip_msg* p_msg);
 
-int reparse_on_dns_failover_fixup(void *handle, str *name, void **val);
+int reparse_on_dns_failover_fixup(void *handle, str *gname, str *name, void **val);
 
 #endif
 

+ 1 - 1
modules/tm/timer.c

@@ -233,7 +233,7 @@ error:
 /* fixup function for the timer values
  * (called by the configuration framework)
  */
-int timer_fixup(void *handle, str *name, void **val)
+int timer_fixup(void *handle, str *gname, str *name, void **val)
 {
 	ticks_t	t;
 

+ 1 - 1
modules/tm/timer.h

@@ -79,7 +79,7 @@ extern struct msgid_var user_noninv_max_lifetime;
 
 
 extern int tm_init_timers();
-int timer_fixup(void *handle, str *name, void **val);
+int timer_fixup(void *handle, str *gname, str *name, void **val);
 
 ticks_t wait_handler(ticks_t t, struct timer_ln *tl, void* data);
 ticks_t retr_buf_handler(ticks_t t, struct timer_ln *tl, void* data);

+ 42 - 12
msg_translator.c

@@ -163,7 +163,7 @@ static unsigned int global_req_flags=0;
 /** per process fixup function for global_req_flags.
   * It should be called from the configuration framework.
   */
-void fix_global_req_flags( str* name)
+void fix_global_req_flags(str* gname, str* name)
 {
 	global_req_flags=0;
 	switch(cfg_get(core, core_cfg, udp_mtu_try_proto)){
@@ -1359,6 +1359,10 @@ static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
 	struct lump* anchor;
 	char* clen_buf;
 	int clen_len, body_only;
+#ifdef USE_TCP
+	char* body;
+	int comp_clen;
+#endif /* USE_TCP */
 
 	/* Calculate message length difference caused by lumps modifying message
 	 * body, from this point on the message body must not be modified. Zero
@@ -1380,7 +1384,7 @@ static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
 			LOG(L_ERR, "adjust_clen: error parsing content-length\n");
 			goto error;
 		}
-		if (msg->content_length==0){
+		if (unlikely(msg->content_length==0)){
 			/* not present, we need to add it */
 			/* msg->unparsed should point just before the final crlf
 			 * - whole message was parsed by the above parse_headers
@@ -1392,12 +1396,37 @@ static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
 				goto error;
 			}
 			body_only=0;
+		}else{
+			/* compute current content length and compare it with the
+			   one in the message */
+			body=get_body(msg);
+			if (unlikely(body==0)){
+				ser_error=E_BAD_REQ;
+				LOG(L_ERR, "adjust_clen: no message body found"
+						" (missing crlf?)");
+				goto error;
+			}
+			comp_clen=msg->len-(int)(body-msg->buf)+body_delta;
+			if (comp_clen!=(int)(long)msg->content_length->parsed){
+				/* note: we don't distinguish here between received with
+				   wrong content-length and content-length changed, we just
+				   fix it automatically in both cases (the reason being
+				   that an error message telling we have received a msg-
+				   with wrong content-length is of very little use) */
+				anchor = del_lump(msg, msg->content_length->body.s-msg->buf,
+									msg->content_length->body.len,
+									HDR_CONTENTLENGTH_T);
+				if (anchor==0) {
+					LOG(L_ERR, "adjust_clen: Can't remove original"
+								" Content-Length\n");
+					goto error;
+				}
+				body_only=1;
+			}
 		}
-	}
-#endif
-
-
-	if ((anchor==0) && body_delta){
+	}else
+#endif /* USE_TCP */
+	if (body_delta){
 		if (parse_headers(msg, HDR_CONTENTLENGTH_F, 0) == -1) {
 			LOG(L_ERR, "adjust_clen: Error parsing Content-Length\n");
 			goto error;
@@ -1421,13 +1450,14 @@ static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
 					goto error;
 				}
 				body_only=0;
-			}else{
-				DBG("adjust_clen: UDP packet with no clen => not adding one \n");
-			}
+			} /* else
+				DBG("adjust_clen: UDP packet with no clen => "
+						"not adding one \n"); */
 		}else{
 			/* Content-Length has been found, remove it */
 			anchor = del_lump(	msg, msg->content_length->body.s - msg->buf,
-								msg->content_length->body.len, HDR_CONTENTLENGTH_T);
+								msg->content_length->body.len,
+								HDR_CONTENTLENGTH_T);
 			if (anchor==0) {
 				LOG(L_ERR, "adjust_clen: Can't remove original"
 							" Content-Length\n");
@@ -1443,7 +1473,7 @@ static inline int adjust_clen(struct sip_msg* msg, int body_delta, int proto)
 					HDR_CONTENTLENGTH_T) == 0)
 			goto error;
 	}
-
+	
 	return 0;
 error:
 	if (clen_buf) pkg_free(clen_buf);

+ 1 - 1
msg_translator.h

@@ -150,6 +150,6 @@ char * build_all( struct sip_msg* msg, int adjust_clen,
 			struct dest_info* send_info);
 
 /** cfg framework fixup */
-void fix_global_req_flags( str* name);
+void fix_global_req_flags(str* gname, str* name);
 
 #endif

+ 2 - 2
parser/contact/contact.c

@@ -246,7 +246,7 @@ int parse_contacts(str* _s, contact_t** _c)
 			c->q = hooks.contact.q;
 			c->expires = hooks.contact.expires;
 			c->received = hooks.contact.received;
-			c->method = hooks.contact.method;
+			c->methods = hooks.contact.methods;
 			c->instance = hooks.contact.instance;
 
 			if (_s->len == 0) goto ok;
@@ -315,7 +315,7 @@ void print_contacts(FILE* _o, contact_t* _c)
 		fprintf(_o, "q       : %p\n", ptr->q);
 		fprintf(_o, "expires : %p\n", ptr->expires);
 		fprintf(_o, "received: %p\n", ptr->received);
-		fprintf(_o, "method  : %p\n", ptr->method);
+		fprintf(_o, "methods  : %p\n", ptr->methods);
 		fprintf(_o, "instance: %p\n", ptr->instance);
 		fprintf(_o, "len     : %d\n", ptr->len);
 		if (ptr->params) {

+ 1 - 1
parser/contact/contact.h

@@ -48,7 +48,7 @@ typedef struct contact {
 	str uri;                /* contact uri */
 	param_t* q;             /* q parameter hook */
 	param_t* expires;       /* expires parameter hook */
-	param_t* method;        /* method parameter hook */
+	param_t* methods;       /* methods parameter hook */
 	param_t* received;      /* received parameter hook */
 	param_t* instance;      /* sip.instance parameter hook */
 	param_t* params;        /* List of all parameters */

+ 6 - 6
parser/parse_param.c

@@ -105,7 +105,7 @@ static inline void parse_event_dialog_class(param_hooks_t* h, param_t* p)
 
 /*
  * Try to find out parameter name, recognized parameters
- * are q, expires and method
+ * are q, expires and methods
  */
 static inline void parse_contact_class(param_hooks_t* _h, param_t* _p)
 {
@@ -138,10 +138,10 @@ static inline void parse_contact_class(param_hooks_t* _h, param_t* _p)
 		
 	case 'm':
 	case 'M':
-		if ((_p->name.len == 6) &&
-		    (!strncasecmp(_p->name.s + 1, "ethod", 5))) {
-			_p->type = P_METHOD;
-			_h->contact.method = _p;
+		if ((_p->name.len == 7) &&
+		    (!strncasecmp(_p->name.s + 1, "ethods", 6))) {
+			_p->type = P_METHODS;
+			_h->contact.methods = _p;
 		}
 		break;
 		
@@ -595,7 +595,7 @@ static inline void print_param(FILE* _o, param_t* _p)
 	case P_OTHER:     type = "P_OTHER";     break;
 	case P_Q:         type = "P_Q";         break;
 	case P_EXPIRES:   type = "P_EXPIRES";   break;
-	case P_METHOD:    type = "P_METHOD";    break;
+	case P_METHODS:   type = "P_METHODS";   break;
 	case P_TRANSPORT: type = "P_TRANSPORT"; break;
 	case P_LR:        type = "P_LR";        break;
 	case P_R2:        type = "P_R2";        break;

+ 2 - 2
parser/parse_param.h

@@ -46,7 +46,7 @@ typedef enum ptype {
 	P_OTHER = 0, /* Unknown parameter */
 	P_Q,         /* Contact: q parameter */
 	P_EXPIRES,   /* Contact: expires parameter */
-	P_METHOD,    /* Contact: method parameter */
+	P_METHODS,   /* Contact: methods parameter */
 	P_RECEIVED,  /* Contact: received parameter */
 	P_TRANSPORT, /* URI: transport parameter */
 	P_LR,        /* URI: lr parameter */
@@ -94,7 +94,7 @@ typedef struct param {
 struct contact_hooks {
 	struct param* expires;  /* expires parameter */
 	struct param* q;        /* q parameter */
-	struct param* method;   /* method parameter */
+	struct param* methods;  /* methods parameter */
 	struct param* received; /* received parameter */
 	struct param* instance; /* sip.instance parameter */
 };

+ 4 - 4
parser/parse_uri.c

@@ -1431,10 +1431,10 @@ inline int normalize_tel_user(char* res, str* src) {
 }
 
 
-static str	s_sip  = STR_STATIC_INIT("sip");
-static str	s_sips = STR_STATIC_INIT("sips");
-static str	s_tel  = STR_STATIC_INIT("tel");
-static str	s_tels = STR_STATIC_INIT("tels");
+str	s_sip  = STR_STATIC_INIT("sip");
+str	s_sips = STR_STATIC_INIT("sips");
+str	s_tel  = STR_STATIC_INIT("tel");
+str	s_tels = STR_STATIC_INIT("tels");
 static str	s_null = STR_STATIC_INIT("");
 
 inline void uri_type_to_str(uri_type type, str *s) {

+ 1 - 0
parser/parse_uri.h

@@ -38,6 +38,7 @@
 #include "../parser/msg_parser.h"
 
 
+extern str	s_sip, s_sips, s_tel, s_tels;
 
 /* buf= pointer to begining of uri (sip:[email protected]:5060;a=b?h=i)
  * len= len of uri

+ 1 - 3
pkg/debian/rules

@@ -207,9 +207,7 @@ install: build
 	# install the *.sql files for ser_mysql.sh script
 	cp -f scripts/mysql/*.sql $(CURDIR)/debian/ser/usr/lib/ser/
 	# and fix path to the *.sql files in ser_mysql.sh script
-	sed -i 's#CREATE_SCRIPT=`dirname $$0`"/"$$DEFAULT_CREATE_SCRIPT#CREATE_SCRIPT="/usr/lib/ser/"\$$DEFAULT_CREATE_SCRIPT#' $(CURDIR)/debian/ser/usr/sbin/ser_mysql.sh
-	sed -i 's#DATA_SCRIPT=`dirname $$0`"/"$$DEFAULT_DATA_SCRIPT#DATA_SCRIPT="/usr/lib/ser/"$$DEFAULT_DATA_SCRIPT#' $(CURDIR)/debian/ser/usr/sbin/ser_mysql.sh
-	sed -i 's#DROP_SCRIPT=`dirname $$0`"/"$$DEFAULT_DROP_SCRIPT#DROP_SCRIPT="/usr/lib/ser/"$$DEFAULT_DROP_SCRIPT#' $(CURDIR)/debian/ser/usr/sbin/ser_mysql.sh
+	sed -i 's#DEFAULT_SCRIPT_DIR=.*#DEFAULT_SCRIPT_DIR="/usr/lib/ser/"#' $(CURDIR)/debian/ser/usr/sbin/ser_mysql.sh
 	# install advanced ser config file for ser-oob package
 	mkdir -p $(CURDIR)/debian/ser-oob/etc/ser
 	cp -f etc/ser-oob.cfg $(CURDIR)/debian/ser-oob/etc/ser/

+ 2 - 2
pt.c

@@ -522,7 +522,7 @@ end:
  * Per-child process callback that is called
  * when mem_dump_pkg cfg var is changed.
  */
-void mem_dump_pkg_cb(str *name)
+void mem_dump_pkg_cb(str *gname, str *name)
 {
 	int	old_memlog;
 
@@ -545,7 +545,7 @@ void mem_dump_pkg_cb(str *name)
  * fixup function that is called
  * when mem_dump_shm cfg var is set.
  */
-int mem_dump_shm_fixup(void *handle, str *name, void **val)
+int mem_dump_shm_fixup(void *handle, str *gname, str *name, void **val)
 {
 	int	old_memlog;
 

+ 2 - 2
pt.h

@@ -101,11 +101,11 @@ int fork_tcp_process(int child_id,char *desc,int r,int *reader_fd_1);
 #endif
 
 #ifdef PKG_MALLOC
-void mem_dump_pkg_cb(str *name);
+void mem_dump_pkg_cb(str *gname, str *name);
 #endif
 
 #ifdef SHM_MEM
-int mem_dump_shm_fixup(void *handle, str *name, void **val);
+int mem_dump_shm_fixup(void *handle, str *gname, str *name, void **val);
 #endif
 
 #endif

+ 1 - 1
receive.c

@@ -127,7 +127,7 @@ int receive_msg(char* buf, unsigned int len, struct receive_info* rcv_info)
 
 	if (msg->first_line.type==SIP_REQUEST){
 		if (!IS_SIP(msg)){
-			if (nonsip_msg_run_hooks(msg)!=NONSIP_MSG_ACCEPT);
+			if (nonsip_msg_run_hooks(msg)!=NONSIP_MSG_ACCEPT)
 				goto end; /* drop the message */
 		}
 		/* sanity checks */

+ 4 - 4
resolve.c

@@ -159,7 +159,7 @@ int resolv_init()
  * This function must be called by each child process whenever
  * a resolver option changes
  */
-void resolv_reinit(str *name)
+void resolv_reinit(str *gname, str *name)
 {
 	_resolv_init();
 
@@ -173,14 +173,14 @@ void resolv_reinit(str *name)
 /* fixup function for dns_reinit variable
  * (resets the variable to 0)
  */
-int dns_reinit_fixup(void *handle, str *name, void **val)
+int dns_reinit_fixup(void *handle, str *gname, str *name, void **val)
 {
 	*val = (void *)(long)0;
 	return 0;
 }
 
 /* wrapper function to recalculate the naptr protocol preferences */
-void reinit_naptr_proto_prefs(str *name)
+void reinit_naptr_proto_prefs(str *gname, str *name)
 {
 #ifdef USE_NAPTR
 	init_naptr_proto_prefs();
@@ -190,7 +190,7 @@ void reinit_naptr_proto_prefs(str *name)
 /* fixup function for dns_try_ipv6
  * verifies that SER really listens on an ipv6 interface
  */
-int dns_try_ipv6_fixup(void *handle, str *name, void **val)
+int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val)
 {
 	if ((int)(long)(*val) && !(socket_types & SOCKET_T_IPV6)) {
 		LOG(L_ERR, "ERROR: dns_try_ipv6_fixup(): "

+ 4 - 4
resolve.h

@@ -408,10 +408,10 @@ skip_ipv4:
 int resolv_init();
 
 /* callback/fixup functions executed by the configuration framework */
-void resolv_reinit(str *name);
-int dns_reinit_fixup(void *handle, str *name, void **val);
-int dns_try_ipv6_fixup(void *handle, str *name, void **val);
-void reinit_naptr_proto_prefs(str *name);
+void resolv_reinit(str *gname, str *name);
+int dns_reinit_fixup(void *handle, str *gname, str *name, void **val);
+int dns_try_ipv6_fixup(void *handle, str *gname, str *name, void **val);
+void reinit_naptr_proto_prefs(str *gname, str *name);
 
 #ifdef DNS_WATCHDOG_SUPPORT
 /* callback function that is called by the child processes

+ 1 - 0
route_struct.h

@@ -71,6 +71,7 @@ enum { METHOD_O=1, URI_O, FROM_URI_O, TO_URI_O, SRCIP_O, SRCPORT_O,
 enum { FORWARD_T=1, SEND_T, DROP_T, LOG_T, ERROR_T, ROUTE_T, EXEC_T,
 		SET_HOST_T, SET_HOSTPORT_T, SET_USER_T, SET_USERPASS_T,
 		SET_PORT_T, SET_URI_T, SET_HOSTPORTTRANS_T, SET_HOSTALL_T,
+		SET_USERPHONE_T,
 		IF_T, SWITCH_T /* only until fixup*/,
 		BLOCK_T, EVAL_T, SWITCH_JT_T, SWITCH_COND_T, MATCH_COND_T, WHILE_T,
 		MODULE_T, MODULE3_T, MODULE4_T, MODULE5_T, MODULE6_T, MODULEX_T,

+ 1 - 1
scripts/mysql/ser_mysql.sh

@@ -317,7 +317,7 @@ if [ -z "$SQLUSER" ] ; then SQLUSER="$DEFAULT_SQLUSER"; fi;
 if [ -z "$MYSQL" ] ; then MYSQL="$DEFAULT_MYSQL"; fi
 if [ -z "$MYSQLDUMP" ] ; then MYSQLDUMP="$DEFAULT_MYSQLDUMP"; fi
 if [ -z "$DUMP_OPTS" ] ; then DUMP_OPTS="$DEFAULT_DUMP_OPTS"; fi 
-if [ -z "SCRIPT_DIR" ] ; then SCRIPT_DIR="$DEFAULT_SCRIPT_DIR"; fi
+if [ -z "$SCRIPT_DIR" ] ; then SCRIPT_DIR="$DEFAULT_SCRIPT_DIR"; fi
 if [ -z "$CREATE_SCRIPT" ] ; then CREATE_SCRIPT="$DEFAULT_CREATE_SCRIPT"; fi
 if [ -z "$DATA_SCRIPT" ] ; then DATA_SCRIPT="$DEFAULT_DATA_SCRIPT"; fi
 if [ -z "$DROP_SCRIPT" ] ; then DROP_SCRIPT="$DEFAULT_DROP_SCRIPT"; fi

+ 2 - 2
select_core.c

@@ -236,8 +236,8 @@ int select_contact_params_spec(str* res, select_t* s, struct sip_msg* msg)
 		TEST_RET_res_body(c->q);
 	case SEL_PARAM_EXPIRES:
 		TEST_RET_res_body(c->expires);
-	case SEL_PARAM_METHOD:
-		TEST_RET_res_body(c->method);
+	case SEL_PARAM_METHODS:
+		TEST_RET_res_body(c->methods);
 	case SEL_PARAM_RECEIVED:
 		TEST_RET_res_body(c->received);
 	case SEL_PARAM_INSTANCE:

+ 2 - 2
select_core.h

@@ -41,7 +41,7 @@
 
 enum {
 	SEL_PARAM_TAG, 
-	SEL_PARAM_Q, SEL_PARAM_EXPIRES, SEL_PARAM_METHOD, SEL_PARAM_RECEIVED, SEL_PARAM_INSTANCE, 
+	SEL_PARAM_Q, SEL_PARAM_EXPIRES, SEL_PARAM_METHODS, SEL_PARAM_RECEIVED, SEL_PARAM_INSTANCE, 
 	SEL_PARAM_BRANCH, SEL_PARAM_RPORT, SEL_PARAM_I, SEL_PARAM_ALIAS
        };
 
@@ -251,7 +251,7 @@ static select_row_t select_core[] = {
 	{ select_contact, SEL_PARAM_STR, STR_STATIC_INIT("name"), select_contact_name, 0}, 
 	{ select_contact, SEL_PARAM_STR, STR_STATIC_INIT("q"), select_contact_params_spec, DIVERSION | SEL_PARAM_Q}, 
 	{ select_contact, SEL_PARAM_STR, STR_STATIC_INIT("expires"), select_contact_params_spec, DIVERSION | SEL_PARAM_EXPIRES}, 
-	{ select_contact, SEL_PARAM_STR, STR_STATIC_INIT("method"), select_contact_params_spec, DIVERSION | SEL_PARAM_METHOD}, 
+	{ select_contact, SEL_PARAM_STR, STR_STATIC_INIT("methods"), select_contact_params_spec, DIVERSION | SEL_PARAM_METHODS}, 
 	{ select_contact, SEL_PARAM_STR, STR_STATIC_INIT("received"), select_contact_params_spec, DIVERSION | SEL_PARAM_RECEIVED}, 
 	{ select_contact, SEL_PARAM_STR, STR_STATIC_INIT("instance"), select_contact_params_spec, DIVERSION | SEL_PARAM_INSTANCE}, 	
 	{ select_contact, SEL_PARAM_STR, STR_STATIC_INIT("params"), select_contact_params, CONSUME_NEXT_STR},

+ 18 - 8
tcp_conn.h

@@ -54,7 +54,6 @@
 /* maximum number of port aliases x search wildcard possibilities */
 #define TCP_CON_MAX_ALIASES (4*3) 
 
-#define TCP_BUF_SIZE	4096 
 #define TCP_CHILD_TIMEOUT 5 /* after 5 seconds, the child "returns" 
 							 the connection to the tcp master process */
 #define TCP_MAIN_SELECT_TIMEOUT 5 /* how often "tcp main" checks for timeout*/
@@ -89,9 +88,12 @@ enum tcp_req_states {	H_SKIP_EMPTY, H_SKIP_EMPTY_CR_FOUND, H_SKIP_EMPTY_CRLF_FOU
 		H_STUN_MSG, H_STUN_READ_BODY, H_STUN_FP, H_STUN_END, H_PING_CRLF
 	};
 
-enum tcp_conn_states { S_CONN_ERROR=-2, S_CONN_BAD=-1, S_CONN_OK=0, 
-						S_CONN_INIT, S_CONN_EOF, 
-						S_CONN_ACCEPT, S_CONN_CONNECT, S_CONN_PENDING };
+enum tcp_conn_states { S_CONN_ERROR=-2, S_CONN_BAD=-1,
+						S_CONN_OK=0, /* established (write or read) */
+						S_CONN_INIT, /* initial state (invalid) */
+						S_CONN_EOF,
+						S_CONN_ACCEPT, S_CONN_CONNECT
+					};
 
 
 /* fd communication commands */
@@ -104,20 +106,26 @@ enum conn_cmds { CONN_DESTROY=-3, CONN_ERROR=-2, CONN_EOF=-1, CONN_RELEASE,
 struct tcp_req{
 	struct tcp_req* next;
 	/* sockaddr ? */
-	char buf[TCP_BUF_SIZE+1]; /* bytes read so far (+0-terminator)*/
+	char* buf; /* bytes read so far (+0-terminator)*/
 	char* start; /* where the message starts, after all the empty lines are
 					skipped*/
 	char* pos; /* current position in buf */
 	char* parsed; /* last parsed position */
 	char* body; /* body position */
+	unsigned int b_size; /* buffer size-1 (extra space for 0-term)*/
 	int content_len;
-	int has_content_len; /* 1 if content_length was parsed ok*/
-	int complete; /* 1 if one req has been fully read, 0 otherwise*/
+	unsigned short flags; /* F_TCP_REQ_HAS_CLEN | F_TCP_REQ_COMPLETE */
 	int bytes_to_go; /* how many bytes we have still to read from the body*/
 	enum tcp_req_errors error;
 	enum tcp_req_states state;
 };
 
+/* tcp_req flags */
+#define F_TCP_REQ_HAS_CLEN 1
+#define F_TCP_REQ_COMPLETE 2
+
+#define TCP_REQ_HAS_CLEN(tr)  ((tr)->flags & F_TCP_REQ_HAS_CLEN)
+#define TCP_REQ_COMPLETE(tr)  ((tr)->flags & F_TCP_REQ_COMPLETE)
 
 
 struct tcp_connection;
@@ -187,9 +195,11 @@ struct tcp_connection{
 #define tcpconn_put(c) atomic_dec_and_test(&((c)->refcnt))
 
 
-#define init_tcp_req( r) \
+#define init_tcp_req( r, rd_buf, rd_buf_size) \
 	do{ \
 		memset( (r), 0, sizeof(struct tcp_req)); \
+		(r)->buf=(rd_buf) ;\
+		(r)->b_size=(rd_buf_size)-1; /* space for 0 term. */ \
 		(r)->parsed=(r)->pos=(r)->start=(r)->buf; \
 		(r)->error=TCP_REQ_OK;\
 		(r)->state=H_SKIP_EMPTY; \

+ 4 - 0
tcp_init.h

@@ -39,6 +39,10 @@
 										  time, timeout */
 #define DEFAULT_TCP_MAX_CONNECTIONS 2048 /* maximum connections */
 
+#define DEFAULT_TCP_BUF_SIZE	4096  /* buffer size used for reads */
+
+#define DEFAULT_TCP_WBUF_SIZE	2100 /*  after debugging switch to 4-16k */
+
 struct tcp_child{
 	pid_t pid;
 	int proc_no; /* ser proc_no, for debugging */

+ 45 - 36
tcp_main.c

@@ -98,6 +98,8 @@
  *              on write error check if there's still data in the socket 
  *               read buffer and process it first (andrei)
  *  2009-02-26  direct blacklist support (andrei)
+ *  2009-03-20  s/wq_timeout/send_timeout ; send_timeout is now in ticks
+ *              (andrei)
  */
 
 
@@ -208,7 +210,6 @@
 #define TCPCONN_WAIT_TIMEOUT 1 /* 1 tick */
 
 #ifdef TCP_ASYNC
-#define TCP_WBUF_SIZE	1024 /* FIXME: after debugging switch to 16-32k */
 static unsigned int* tcp_total_wq=0;
 #endif
 
@@ -628,7 +629,7 @@ inline static int _wbufq_add(struct  tcp_connection* c, char* data,
 					" (%d, total %d, last write %d s ago)\n",
 					size, q->queued, *tcp_total_wq,
 					TICKS_TO_S(t-q->wr_timeout-
-						cfg_get(tcp, tcp_cfg, tcp_wq_timeout)));
+						cfg_get(tcp, tcp_cfg, send_timeout)));
 #ifdef USE_DST_BLACKLIST
 		if (q->first && TICKS_LT(q->wr_timeout, t) &&
 				cfg_get(core, core_cfg, use_dst_blacklist)){
@@ -642,7 +643,7 @@ inline static int _wbufq_add(struct  tcp_connection* c, char* data,
 	}
 	
 	if (unlikely(q->last==0)){
-		wb_size=MAX_unsigned(TCP_WBUF_SIZE, size);
+		wb_size=MAX_unsigned(cfg_get(tcp, tcp_cfg, wq_blk_size), size);
 		wb=shm_malloc(sizeof(*wb)+wb_size-1);
 		if (unlikely(wb==0))
 			goto error;
@@ -652,7 +653,10 @@ inline static int _wbufq_add(struct  tcp_connection* c, char* data,
 		q->first=wb;
 		q->last_used=0;
 		q->offset=0;
-		q->wr_timeout=get_ticks_raw()+cfg_get(tcp, tcp_cfg, tcp_wq_timeout);
+		q->wr_timeout=get_ticks_raw()+
+			((c->state==S_CONN_CONNECT)?
+					S_TO_TICKS(cfg_get(tcp, tcp_cfg, connect_timeout_s)):
+					cfg_get(tcp, tcp_cfg, send_timeout));
 	}else{
 		wb=q->last;
 	}
@@ -660,7 +664,7 @@ inline static int _wbufq_add(struct  tcp_connection* c, char* data,
 	while(size){
 		last_free=wb->b_size-q->last_used;
 		if (last_free==0){
-			wb_size=MAX_unsigned(TCP_WBUF_SIZE, size);
+			wb_size=MAX_unsigned(cfg_get(tcp, tcp_cfg, wq_blk_size), size);
 			wb=shm_malloc(sizeof(*wb)+wb_size-1);
 			if (unlikely(wb==0))
 				goto error;
@@ -705,7 +709,7 @@ inline static int _wbufq_insert(struct  tcp_connection* c, char* data,
 					" (%d, total %d, last write %d s ago)\n",
 					size, q->queued, *tcp_total_wq,
 					TICKS_TO_S(get_ticks_raw()-q->wr_timeout-
-									cfg_get(tcp, tcp_cfg, tcp_wq_timeout)));
+									cfg_get(tcp, tcp_cfg, send_timeout)));
 		goto error;
 	}
 	if (unlikely(q->offset)){
@@ -774,12 +778,10 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
 	int n;
 	int ret;
 	int block_size;
-	ticks_t t;
 	char* buf;
 	
 	*empty=0;
 	ret=0;
-	t=get_ticks_raw();
 	lock_get(&c->write_lock);
 	q=&c->wbuf_q;
 	while(q->first){
@@ -802,7 +804,6 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
 				atomic_add_int((int*)tcp_total_wq, -n);
 				break;
 			}
-			q->wr_timeout=t+cfg_get(tcp, tcp_cfg, tcp_wq_timeout);
 		}else{
 			if (n<0){
 				/* EINTR is handled inside _tcpconn_write_nb */
@@ -835,9 +836,12 @@ inline static int wbufq_run(int fd, struct tcp_connection* c, int* empty)
 		q->offset=0;
 		*empty=1;
 	}
-	if (unlikely(c->state==S_CONN_CONNECT && (ret>0)))
-			c->state=S_CONN_OK;
 	lock_release(&c->write_lock);
+	if (likely(ret>0)){
+		q->wr_timeout=get_ticks_raw()+cfg_get(tcp, tcp_cfg, send_timeout);
+		if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT))
+			c->state=S_CONN_OK;
+	}
 	return ret;
 }
 
@@ -923,13 +927,15 @@ struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
 									int state)
 {
 	struct tcp_connection *c;
+	int rd_b_size;
 	
-	c=(struct tcp_connection*)shm_malloc(sizeof(struct tcp_connection));
+	rd_b_size=cfg_get(tcp, tcp_cfg, rd_buf_size);
+	c=shm_malloc(sizeof(struct tcp_connection) + rd_b_size);
 	if (c==0){
 		LOG(L_ERR, "ERROR: tcpconn_new: mem. allocation failure\n");
 		goto error;
 	}
-	memset(c, 0, sizeof(struct tcp_connection)); /* zero init */
+	memset(c, 0, sizeof(struct tcp_connection)); /* zero init (skip rd buf)*/
 	c->s=sock;
 	c->fd=-1; /* not initialized */
 	if (lock_init(&c->write_lock)==0){
@@ -953,7 +959,7 @@ struct tcp_connection* tcpconn_new(int sock, union sockaddr_union* su,
 	}
 	print_ip("tcpconn_new: new tcp connection: ", &c->rcv.src_ip, "\n");
 	DBG(     "tcpconn_new: on port %d, type %d\n", c->rcv.src_port, type);
-	init_tcp_req(&c->req);
+	init_tcp_req(&c->req, (char*)c+sizeof(struct tcp_connection), rd_b_size);
 	c->id=(*connection_id)++;
 	c->rcv.proto_reserved1=0; /* this will be filled before receive_message*/
 	c->rcv.proto_reserved2=0;
@@ -1021,10 +1027,10 @@ inline static int tcp_do_connect(	union sockaddr_union* server,
 	if (likely(cfg_get(tcp, tcp_cfg, async))){
 again:
 		n=connect(s, &server->s, sockaddru_len(*server));
-		if (unlikely(n==-1)){
-			if (errno==EINTR) goto again;
+		if (likely(n==-1)){ /*non-blocking => most probable EINPROGRESS*/
 			if (likely(errno==EINPROGRESS))
 				*state=S_CONN_CONNECT;
+			else if (errno==EINTR) goto again;
 			else if (errno!=EALREADY){
 #ifdef USE_DST_BLACKLIST
 				if (cfg_get(core, core_cfg, use_dst_blacklist))
@@ -1693,7 +1699,7 @@ no_id:
 					return -1;
 				}
 				c=tcpconn_new(-1, &dst->to, from, 0, dst->proto,
-								S_CONN_PENDING);
+								S_CONN_CONNECT);
 				if (unlikely(c==0)){
 					LOG(L_ERR, "ERROR: tcp_send %s: could not create new"
 							" connection\n",
@@ -1738,6 +1744,9 @@ no_id:
 						DBG("tcp_send: pending write on new connection %p "
 								" (%d/%d bytes written)\n", c, n, len);
 						if (n<0) n=0;
+						else 
+							c->state=S_CONN_OK; /* partial write => connect()
+													ended */
 						/* add to the write queue */
 						lock_get(&c->write_lock);
 							if (unlikely(_wbufq_insert(c, buf+n, len-n)<0)){
@@ -1785,6 +1794,7 @@ no_id:
 					goto conn_wait_error;
 				}
 				LOG(L_INFO, "tcp_send: quick connect for %p\n", c);
+				c->state=S_CONN_OK;
 				/* send to tcp_main */
 				response[0]=(long)c;
 				response[1]=CONN_NEW_COMPLETE;
@@ -1832,13 +1842,13 @@ get_fd:
 		if (unlikely(cfg_get(tcp, tcp_cfg, async) &&
 						(_wbufq_non_empty(c)
 #ifdef TCP_CONNECT_WAIT
-												|| (c->state==S_CONN_PENDING)
+											|| (c->flags&F_CONN_PENDING)
 #endif /* TCP_CONNECT_WAIT */
 						) )){
 			lock_get(&c->write_lock);
 				if (likely(_wbufq_non_empty(c)
 #ifdef TCP_CONNECT_WAIT
-							|| (c->state==S_CONN_PENDING)
+							|| (c->flags&F_CONN_PENDING)
 #endif /* TCP_CONNECT_WAIT */
 
 							)){
@@ -1916,7 +1926,7 @@ send_it:
 	if (likely(cfg_get(tcp, tcp_cfg, async))){
 		if (_wbufq_non_empty(c)
 #ifdef TCP_CONNECT_WAIT
-			|| (c->state==S_CONN_PENDING) 
+			|| (c->flags&F_CONN_PENDING) 
 #endif /* TCP_CONNECT_WAIT */
 			){
 			if (unlikely(_wbufq_add(c, buf, len)<0)){
@@ -1938,7 +1948,8 @@ send_it:
 #endif
 		/* n=tcp_blocking_write(c, fd, buf, len); */
 		n=tsend_stream(fd, buf, len,
-							cfg_get(tcp, tcp_cfg, send_timeout_s)*1000);
+						TICKS_TO_S(cfg_get(tcp, tcp_cfg, send_timeout)) *
+						1000);
 #ifdef TCP_ASYNC
 	}
 #else /* ! TCP_ASYNC */
@@ -1953,6 +1964,9 @@ send_it:
 				((n>=0) || errno==EAGAIN || errno==EWOULDBLOCK)){
 			enable_write_watch=_wbufq_empty(c);
 			if (n<0) n=0;
+			else if (unlikely(c->state==S_CONN_CONNECT ||
+						c->state==S_CONN_ACCEPT))
+				c->state=S_CONN_OK; /* something was written */
 			if (unlikely(_wbufq_add(c, buf+n, len-n)<0)){
 				lock_release(&c->write_lock);
 				n=-1;
@@ -2026,11 +2040,10 @@ error:
 	
 #ifdef TCP_ASYNC
 	lock_release(&c->write_lock);
-	if (likely(cfg_get(tcp, tcp_cfg, async))){
-		if (unlikely(c->state==S_CONN_CONNECT))
-			c->state=S_CONN_OK;
-	}
 #endif /* TCP_ASYNC */
+	/* in non-async mode here we're either in S_CONN_OK or S_CONN_ACCEPT*/
+	if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT))
+			c->state=S_CONN_OK;
 end:
 #ifdef TCP_FD_CACHE
 	if (unlikely((fd_cache_e==0) && use_fd_cache)){
@@ -2249,9 +2262,10 @@ inline static int tcpconn_chld_put(struct tcp_connection* tcpconn)
 				tcpconn->s, tcpconn->flags);
 		/* sanity checks */
 		membar_read_atomic_op(); /* make sure we see the current flags */
-		if (unlikely(!(tcpconn->flags & F_CONN_FD_CLOSED) || 
-			(tcpconn->flags & 
-				(F_CONN_HASHED|F_CONN_MAIN_TIMER|F_CONN_READ_W|F_CONN_WRITE_W)) )){
+		if (unlikely(!(tcpconn->flags & F_CONN_FD_CLOSED) ||
+			(tcpconn->flags &
+				(F_CONN_HASHED|F_CONN_MAIN_TIMER|
+				 F_CONN_READ_W|F_CONN_WRITE_W)) )){
 			LOG(L_CRIT, "BUG: tcpconn_chld_put: %p bad flags = %0x\n",
 					tcpconn, tcpconn->flags);
 			abort();
@@ -2712,7 +2726,7 @@ inline static int handle_tcp_child(struct tcp_child* tcp_c, int fd_i)
 					tcpconn->flags&=~F_CONN_WRITE_W;
 				}
 #endif /* TCP_ASYNC */
-				if (tcpconn_try_unhash(tcpconn));
+				if (tcpconn_try_unhash(tcpconn))
 					tcpconn_put_destroy(tcpconn);
 				break;
 			}
@@ -2978,8 +2992,8 @@ inline static int handle_ser_child(struct process_table* p, int fd_i)
 		case CONN_NEW_PENDING_WRITE:
 				/* received when a pending connect completes in the same
 				 * tcp_send() that initiated it
-				 * the connection is already in the hash with S_CONN_PENDING
-				 * state (added by tcp_send()) and refcnt at least 1 (for the
+				 * the connection is already in the hash with F_CONN_PENDING
+				 * flag (added by tcp_send()) and refcnt at least 1 (for the
 				 *  hash)*/
 			tcpconn->flags&=~(F_CONN_PENDING|F_CONN_FD_CLOSED);
 			if (unlikely((tcpconn->state==S_CONN_BAD) || (fd==-1))){
@@ -3003,7 +3017,6 @@ inline static int handle_ser_child(struct process_table* p, int fd_i)
 			tcpconn->timeout=t+con_lifetime;
 			nxt_timeout=con_lifetime;
 			if (unlikely(cmd==CONN_NEW_COMPLETE)){
-				tcpconn->state=S_CONN_OK;
 				/* check if needs to be watched for write */
 				lock_get(&tcpconn->write_lock);
 					/* if queue non empty watch it for write */
@@ -3023,10 +3036,6 @@ inline static int handle_ser_child(struct process_table* p, int fd_i)
 								F_CONN_WANTS_RD;
 			}else{
 				/* CONN_NEW_PENDING_WRITE */
-				/* we don't know if we successfully sent anything, but
-				   for sure we haven't sent all what we wanted, so consider
-				   the connection in "connecting" state */
-				tcpconn->state=S_CONN_CONNECT;
 				/* no need to check, we have something queued for write */
 				flags=POLLOUT;
 				if (TICKS_LT(tcpconn->wbuf_q.wr_timeout, tcpconn->timeout)

+ 65 - 70
tcp_options.c

@@ -37,38 +37,13 @@
    NOTE: all the options are initialized in init_tcp_options()
    depending on compile time defines */
 struct cfg_group_tcp tcp_default_cfg;
-#if 0
-{
-	1, /* fd_cache, default on */
-	/* tcp async options */
-	0, /* async / tcp_async, default off */
-	1, /* tcp_connect_wait - depends on tcp_async */
-	32*1024, /* tcpconn_wq_max - max. write queue len per connection (32k) */
-	10*1024*1024, /* tcp_wq_max - max.  overall queued bytes  (10MB)*/
-	S_TO_TICKS(tcp_send_timeout), /* tcp_wq_timeout - timeout for queued 
-									 writes, depends on tcp_send_timeout */
-	/* tcp socket options */
-	0, /* defer_accept - on/off*/
-	1, /* delayed_ack - delay ack on connect (on/off)*/
-	0, /* syncnt - numbers of SYNs retrs. before giving up (0 = OS default) */
-	0, /* linger2 - lifetime of orphaned FIN_WAIT2 sockets (0 = OS default)*/
-	1, /* keepalive - on/off */
-	0, /* keepidle - idle time (s) before tcp starts sending keepalives */
-	0, /* keepintvl - interval between keep alives (0 = OS default) */
-	0, /* keepcnt - maximum no. of keepalives (0 = OS default)*/
-	
-	/* other options */
-	1 /* crlf_ping - respond to double CRLF ping/keepalive (on/off) */
-	
-};
-#endif
 
 
 
-static int fix_connect_to(void* cfg_h, str* name, void** val);
-static int fix_send_to(void* cfg_h, str* name, void** val);
-static int fix_con_lt(void* cfg_h, str* name, void** val);
-static int fix_max_conns(void* cfg_h, str* name, void** val);
+static int fix_connect_to(void* cfg_h, str* gname, str* name, void** val);
+static int fix_send_to(void* cfg_h, str* gname, str* name, void** val);
+static int fix_con_lt(void* cfg_h, str* gname, str* name, void** val);
+static int fix_max_conns(void* cfg_h, str* gname, str* name, void** val);
 
 
 
@@ -80,10 +55,10 @@ static cfg_def_t tcp_cfg_def[] = {
 						TICKS_TO_S(MAX_TCP_CON_LIFETIME),  fix_connect_to,   0,
 		"used only in non-async mode, in seconds"},
 	{ "send_timeout", CFG_VAR_INT | CFG_ATOMIC,   -1,
-						TICKS_TO_S(MAX_TCP_CON_LIFETIME),   fix_send_to,     0,
+						MAX_TCP_CON_LIFETIME,               fix_send_to,     0,
 		"in seconds"},
 	{ "connection_lifetime", CFG_VAR_INT | CFG_ATOMIC,   -1,
-						TICKS_TO_S(MAX_TCP_CON_LIFETIME),   fix_con_lt,      0,
+						MAX_TCP_CON_LIFETIME,               fix_con_lt,      0,
 		"connection lifetime (in seconds)"},
 	{ "max_connections", CFG_VAR_INT | CFG_ATOMIC, 0, (1U<<31)-1,
 													       fix_max_conns,    0,
@@ -101,7 +76,7 @@ static cfg_def_t tcp_cfg_def[] = {
 		"maximum bytes queued for write per connection (depends on async)"},
 	{ "wq_max",       CFG_VAR_INT | CFG_ATOMIC,      0,  1<<30,    0,        0,
 		"maximum bytes queued for write allowed globally (depends on async)"},
-	/* see also wq_timeout below */
+	/* see also send_timeout above */
 	/* tcp socket options */
 	{ "defer_accept", CFG_VAR_INT | CFG_READONLY,    0,   3600,   0,         0,
 		"0/1 on linux, seconds on freebsd (see docs)"},
@@ -130,12 +105,10 @@ static cfg_def_t tcp_cfg_def[] = {
 		"flags for the def. aliases for a new conn. (FORCE_ADD:1, REPLACE:2 "},
 	/* internal and/or "fixed" versions of some vars
 	   (not supposed to be writeable, read will provide only debugging value*/
-	{ "wq_timeout_ticks",   CFG_VAR_INT | CFG_READONLY, 0,
-									MAX_TCP_CON_LIFETIME,         0,         0,
-		"internal send_timeout value in ticks, used in async. mode"},
-	{ "con_lifetime_ticks", CFG_VAR_INT | CFG_READONLY, 0,
-									MAX_TCP_CON_LIFETIME,         0,         0,
-		"internal connection_lifetime value, converted to ticks"},
+	{ "rd_buf_size", CFG_VAR_INT | CFG_ATOMIC,    512,    65536,  0,         0,
+		"internal read buffer size (should be > max. expected datagram)"},
+	{ "wq_blk_size", CFG_VAR_INT | CFG_ATOMIC,    1,    65535,  0,         0,
+		"internal async write block size (debugging use only for now)"},
 	{0, 0, 0, 0, 0, 0, 0}
 };
 
@@ -146,14 +119,13 @@ void* tcp_cfg; /* tcp config handle */
 void init_tcp_options()
 {
 	tcp_default_cfg.connect_timeout_s=DEFAULT_TCP_CONNECT_TIMEOUT;
-	tcp_default_cfg.send_timeout_s=DEFAULT_TCP_SEND_TIMEOUT;
-	tcp_default_cfg.con_lifetime_s=DEFAULT_TCP_CONNECTION_LIFETIME_S;
+	tcp_default_cfg.send_timeout=S_TO_TICKS(DEFAULT_TCP_SEND_TIMEOUT);
+	tcp_default_cfg.con_lifetime=S_TO_TICKS(DEFAULT_TCP_CONNECTION_LIFETIME_S);
 	tcp_default_cfg.max_connections=tcp_max_connections;
 #ifdef TCP_ASYNC
 	tcp_default_cfg.async=1;
 	tcp_default_cfg.tcpconn_wq_max=32*1024; /* 32 k */
 	tcp_default_cfg.tcp_wq_max=10*1024*1024; /* 10 MB */
-	tcp_default_cfg.tcp_wq_timeout=S_TO_TICKS(tcp_default_cfg.send_timeout_s);
 #ifdef TCP_CONNECT_WAIT
 	tcp_default_cfg.tcp_connect_wait=1;
 #endif /* TCP_CONNECT_WAIT */
@@ -178,6 +150,8 @@ void init_tcp_options()
 	tcp_default_cfg.alias_flags=TCP_ALIAS_FORCE_ADD;
 	/* flags used for adding the default aliases of a new tcp connection */
 	tcp_default_cfg.new_conn_alias_flags=TCP_ALIAS_REPLACE;
+	tcp_default_cfg.rd_buf_size=DEFAULT_TCP_BUF_SIZE;
+	tcp_default_cfg.wq_blk_size=DEFAULT_TCP_WBUF_SIZE;
 }
 
 
@@ -213,7 +187,7 @@ static void fix_timeout(char* name, int* to, int default_val, unsigned max_val)
 
 
 
-static int fix_connect_to(void* cfg_h, str* name, void** val)
+static int fix_connect_to(void* cfg_h, str* gname, str* name, void** val)
 {
 	int v;
 	v=(int)(long)*val;
@@ -224,36 +198,29 @@ static int fix_connect_to(void* cfg_h, str* name, void** val)
 }
 
 
-static int fix_send_to(void* cfg_h, str* name, void** val)
+static int fix_send_to(void* cfg_h, str* gname, str* name, void** val)
 {
 	int v;
-	v=(int)(long)*val;
-	fix_timeout("tcp_send_timeout", &v, DEFAULT_TCP_SEND_TIMEOUT,
-						TICKS_TO_S(MAX_TCP_CON_LIFETIME));
+	v=S_TO_TICKS((int)(long)*val);
+	fix_timeout("tcp_send_timeout", &v, S_TO_TICKS(DEFAULT_TCP_SEND_TIMEOUT),
+						MAX_TCP_CON_LIFETIME);
 	*val=(void*)(long)v;
-#ifdef TCP_ASYNC
-	((struct cfg_group_tcp*)cfg_h)->tcp_wq_timeout=S_TO_TICKS(v);
-#endif /* TCP_ASYNC */
 	return 0;
 }
 
 
-static int fix_con_lt(void* cfg_h, str* name, void** val)
+static int fix_con_lt(void* cfg_h, str* gname, str* name, void** val)
 {
 	int v;
-	v=(int)(long)*val;
-	fix_timeout("tcp_connection_lifetime", &v,
-						TICKS_TO_S(MAX_TCP_CON_LIFETIME),
-						TICKS_TO_S(MAX_TCP_CON_LIFETIME));
+	v=S_TO_TICKS((int)(long)*val);
+	fix_timeout("tcp_connection_lifetime", &v, 
+					MAX_TCP_CON_LIFETIME, MAX_TCP_CON_LIFETIME);
 	*val=(void*)(long)v;
-#ifdef TCP_ASYNC
-	((struct cfg_group_tcp*)cfg_h)->con_lifetime=S_TO_TICKS(v);
-#endif /* TCP_ASYNC */
 	return 0;
 }
 
 
-static int fix_max_conns(void* cfg_h, str* name, void** val)
+static int fix_max_conns(void* cfg_h, str* gname, str* name, void** val)
 {
 	int v;
 	v=(int)(long)*val;
@@ -268,6 +235,39 @@ static int fix_max_conns(void* cfg_h, str* name, void** val)
 
 
 
+/** fix *val according to the cfg entry "name".
+ * (*val must be integer)
+ * 1. check if *val is between name min..max and if not change it to
+ *    the corresp. value
+ * 2. call fixup callback if defined in the cfg
+ * @return 0 on success
+ */
+static int tcp_cfg_def_fix(char* name, int* val)
+{
+	cfg_def_t* c;
+	str s;
+	
+	for (c=&tcp_cfg_def[0]; c->name; c++){
+		if (strcmp(name, c->name)==0){
+			/* found */
+			if ((c->type & CFG_VAR_INT)  && (c->min || c->max)){
+				if (*val < c->min) *val=c->min;
+				else if (*val > c->max) *val=c->max;
+				if (c->on_change_cb){
+					s.s=c->name;
+					s.len=strlen(s.s);
+					return c->on_change_cb(&tcp_default_cfg, NULL, &s, (void*)val);
+				}
+			}
+			return 0;
+		}
+	}
+	WARN("tcp config option \"%s\" not found\n", name);
+	return -1; /* not found */
+}
+
+
+
 /* checks & warns if some tcp_option cannot be enabled */
 void tcp_options_check()
 {
@@ -279,7 +279,6 @@ void tcp_options_check()
 	W_OPT_NC(async);
 	W_OPT_NC(tcpconn_wq_max);
 	W_OPT_NC(tcp_wq_max);
-	W_OPT_NC(tcp_wq_timeout);
 #endif /* TCP_ASYNC */
 #ifndef TCP_CONNECT_WAIT
 	W_OPT_NC(tcp_connect_wait);
@@ -321,18 +320,14 @@ void tcp_options_check()
 	fix_timeout("tcp_connect_timeout", &tcp_default_cfg.connect_timeout_s,
 						DEFAULT_TCP_CONNECT_TIMEOUT,
 						TICKS_TO_S(MAX_TCP_CON_LIFETIME));
-	fix_timeout("tcp_send_timeout", &tcp_default_cfg.send_timeout_s,
-						DEFAULT_TCP_SEND_TIMEOUT,
-						TICKS_TO_S(MAX_TCP_CON_LIFETIME));
-	fix_timeout("tcp_connection_lifetime", &tcp_default_cfg.con_lifetime_s,
-						TICKS_TO_S(MAX_TCP_CON_LIFETIME),
-						TICKS_TO_S(MAX_TCP_CON_LIFETIME));
-	/* compute timeout in ticks */
-#ifdef TCP_ASYNC
-	tcp_default_cfg.tcp_wq_timeout=S_TO_TICKS(tcp_default_cfg.send_timeout_s);
-#endif /* TCP_ASYNC */
-	tcp_default_cfg.con_lifetime=S_TO_TICKS(tcp_default_cfg.con_lifetime_s);
+	fix_timeout("tcp_send_timeout", &tcp_default_cfg.send_timeout,
+						S_TO_TICKS(DEFAULT_TCP_SEND_TIMEOUT),
+						MAX_TCP_CON_LIFETIME);
+	fix_timeout("tcp_connection_lifetime", &tcp_default_cfg.con_lifetime,
+						MAX_TCP_CON_LIFETIME, MAX_TCP_CON_LIFETIME);
 	tcp_default_cfg.max_connections=tcp_max_connections;
+	tcp_cfg_def_fix("rd_buf_size", (int*)&tcp_default_cfg.rd_buf_size);
+	tcp_cfg_def_fix("wq_blk_size", (int*)&tcp_default_cfg.wq_blk_size);
 }
 
 

+ 5 - 5
tcp_options.h

@@ -111,9 +111,9 @@
 
 struct cfg_group_tcp{
 	/* ser tcp options, low level */
-	int connect_timeout_s; /* in s, used only in non-async mode */
-	int send_timeout_s; /* in s */
-	int con_lifetime_s; /* in s */
+	int connect_timeout_s; /* in s */
+	int send_timeout; /* in ticks (s fixed to ticks) */
+	int con_lifetime; /* in ticks (s fixed to ticks) */
 	int max_connections;
 	int no_connect; /* do not open any new tcp connection (but accept them) */
 	int fd_cache; /* on /off */
@@ -139,8 +139,8 @@ struct cfg_group_tcp{
 	int alias_flags;
 	int new_conn_alias_flags;
 	/* internal, "fixed" vars */
-	unsigned int tcp_wq_timeout; /* in ticks, timeout for queued writes */
-	unsigned int con_lifetime; /* in ticks, see con_lifetime_s */
+	unsigned int rd_buf_size; /* read buffer size (should be > max. datagram)*/
+	unsigned int wq_blk_size; /* async write block size (debugging use) */
 };
 
 extern struct cfg_group_tcp tcp_default_cfg;

+ 29 - 26
tcp_read.c

@@ -130,7 +130,7 @@ int tcp_read(struct tcp_connection *c, int* flags)
 
 	r=&c->req;
 	fd=c->fd;
-	bytes_free=TCP_BUF_SIZE- (int)(r->pos - r->buf);
+	bytes_free=r->b_size- (int)(r->pos - r->buf);
 	
 	if (bytes_free==0){
 		LOG(L_ERR, "ERROR: tcp_read: buffer overrun, dropping\n");
@@ -170,13 +170,13 @@ again:
 			*flags|=RD_CONN_EOF;
 			DBG("tcp_read: EOF on %p, FD %d\n", c, fd);
 		}else{
-			if (unlikely(c->state==S_CONN_CONNECT))
+			if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT))
 				c->state=S_CONN_OK;
 		}
 		/* short read */
 		*flags|=RD_CONN_SHORT_READ;
 	}else{ /* else normal full read */
-		if (unlikely(c->state==S_CONN_CONNECT))
+		if (unlikely(c->state==S_CONN_CONNECT || c->state==S_CONN_ACCEPT))
 			c->state=S_CONN_OK;
 	}
 #ifdef EXTRA_DEBUG
@@ -218,19 +218,19 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
 	#define content_len_beg_case \
 					case ' ': \
 					case '\t': \
-						if (!r->has_content_len) r->state=H_STARTWS; \
+						if (!TCP_REQ_HAS_CLEN(r)) r->state=H_STARTWS; \
 						else r->state=H_SKIP; \
 							/* not interested if we already found one */ \
 						break; \
 					case 'C': \
 					case 'c': \
-						if(!r->has_content_len) r->state=H_CONT_LEN1; \
+						if(!TCP_REQ_HAS_CLEN(r)) r->state=H_CONT_LEN1; \
 						else r->state=H_SKIP; \
 						break; \
 					case 'l': \
 					case 'L': \
 						/* short form for Content-Length */ \
-						if (!r->has_content_len) r->state=H_L_COLON; \
+						if (!TCP_REQ_HAS_CLEN(r)) r->state=H_L_COLON; \
 						else r->state=H_SKIP; \
 						break
 						
@@ -272,7 +272,7 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
 				r->bytes_to_go-=remaining;
 				p+=remaining;
 				if (r->bytes_to_go==0){
-					r->complete=1;
+					r->flags|=F_TCP_REQ_COMPLETE;
 					goto skip;
 				}
 				break;
@@ -298,11 +298,11 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
 					case '\n':
 						/* found LF LF */
 						r->state=H_BODY;
-						if (r->has_content_len){
+						if (TCP_REQ_HAS_CLEN(r)){
 							r->body=p+1;
 							r->bytes_to_go=r->content_len;
 							if (r->bytes_to_go==0){
-								r->complete=1;
+								r->flags|=F_TCP_REQ_COMPLETE;
 								p++;
 								goto skip;
 							}
@@ -322,11 +322,11 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
 				if (*p=='\n'){
 					/* found LF CR LF */
 					r->state=H_BODY;
-					if (r->has_content_len){
+					if (TCP_REQ_HAS_CLEN(r)){
 						r->body=p+1;
 						r->bytes_to_go=r->content_len;
 						if (r->bytes_to_go==0){
-							r->complete=1;
+							r->flags|=F_TCP_REQ_COMPLETE;
 							p++;
 							goto skip;
 						}
@@ -410,8 +410,8 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
 			case H_SKIP_EMPTY_CRLFCR_FOUND:
 				if (*p=='\n'){
 					r->state = H_PING_CRLF;
-					r->complete = 1;
-					r->has_content_len = 1; /* hack to avoid error check */
+					r->flags |= F_TCP_REQ_HAS_CLEN |
+							F_TCP_REQ_COMPLETE; /* hack to avoid error check */
 					p++;
 					goto skip;
 				}else{
@@ -437,7 +437,7 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
 					/* using has_content_len as a flag if there should be
 					 * fingerprint or no
 					 */
-					r->has_content_len = (mc == MAGIC_COOKIE) ? 1 : 0;
+					r->flags |= (mc == MAGIC_COOKIE) ? F_TCP_REQ_HAS_CLEN : 0;
 					
 					r->body += sizeof(struct stun_hdr);
 					p = r->body; 
@@ -485,8 +485,8 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
 					r->body += body_len;
 					p = r->body;
 					r->state = H_STUN_END;
-					r->complete = 1;
-					r->has_content_len = 1; /* hack to avoid error check */
+					r->flags |= F_TCP_REQ_COMPLETE |
+						F_TCP_REQ_HAS_CLEN; /* hack to avoid error check */
 					goto skip;
 				}
 				else {
@@ -563,12 +563,12 @@ int tcp_read_headers(struct tcp_connection *c, int* read_flags)
 					case ' ':
 					case '\t': /* FIXME: check if line contains only WS */
 						r->state=H_SKIP;
-						r->has_content_len=1;
+						r->flags|=F_TCP_REQ_HAS_CLEN;
 						break;
 					case '\n':
 						/* end of line, parse successful */
 						r->state=H_LF;
-						r->has_content_len=1;
+						r->flags|=F_TCP_REQ_HAS_CLEN;
 						break;
 					default:
 						LOG(L_ERR, "ERROR: tcp_read_headers: bad "
@@ -615,7 +615,8 @@ int tcp_read_req(struct tcp_connection* con, int* bytes_read, int* read_flags)
 				resp=CONN_ERROR;
 				goto end_req;
 			}
-			if(con->state!=S_CONN_OK) goto end_req; /* not enough data */
+			if (unlikely(con->state!=S_CONN_OK && con->state!=S_CONN_ACCEPT))
+				goto end_req; /* not enough data */
 		}
 #endif
 
@@ -642,7 +643,8 @@ again:
 			 * if req. is complete we might have a second unparsed
 			 * request after it, so postpone release_with_eof
 			 */
-			if (unlikely((con->state==S_CONN_EOF) && (req->complete==0))) {
+			if (unlikely((con->state==S_CONN_EOF) && 
+						(! TCP_REQ_COMPLETE(req)))) {
 				DBG( "tcp_read_req: EOF\n");
 				resp=CONN_EOF;
 				goto end_req;
@@ -659,7 +661,7 @@ again:
 			resp=CONN_ERROR;
 			goto end_req;
 		}
-		if (likely(req->complete)){
+		if (likely(TCP_REQ_COMPLETE(req))){
 #ifdef EXTRA_DEBUG
 			DBG("tcp_read_req: end of header part\n");
 			DBG("- received from: port %d\n", con->rcv.src_port);
@@ -667,7 +669,7 @@ again:
 			DBG("tcp_read_req: headers:\n%.*s.\n",
 					(int)(req->body-req->start), req->start);
 #endif
-			if (likely(req->has_content_len)){
+			if (likely(TCP_REQ_HAS_CLEN(req))){
 				DBG("tcp_read_req: content-length= %d\n", req->content_len);
 #ifdef EXTRA_DEBUG
 				DBG("tcp_read_req: body:\n%.*s\n", req->content_len,req->body);
@@ -732,7 +734,8 @@ again:
 			req->body=0;
 			req->error=TCP_REQ_OK;
 			req->state=H_SKIP_EMPTY;
-			req->complete=req->content_len=req->has_content_len=0;
+			req->flags=0;
+			req->content_len=0;
 			req->bytes_to_go=0;
 			req->pos=req->buf+size;
 			
@@ -1084,15 +1087,15 @@ error:
 #ifdef USE_STUN
 int is_msg_complete(struct tcp_req* r)
 {
-	if (r->has_content_len == 1) {
+	if (TCP_REQ_HAS_CLEN(r)) {
 		r->state = H_STUN_FP;
 		return 0;
 	}
 	else {
 		/* STUN message is complete */
 		r->state = H_STUN_END;
-		r->complete = 1;
-		r->has_content_len = 1; /* hack to avoid error check */
+		r->flags |= F_TCP_REQ_COMPLETE |
+					F_TCP_REQ_HAS_CLEN; /* hack to avoid error check */
 		return 1;
 	}
 }

+ 2 - 1
utils/sercmd/Makefile

@@ -20,7 +20,8 @@ endif
 endif #ifneq (,$(MAKECMDGOALS))
 
 
-
+# erase common DEFS (not needed)
+C_DEFS:=
 DEFS:= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' \
 		$(filter -D%HAVE -DARCH% -DOS% -D__CPU% -D__OS%, $(DEFS))
 LIBS:=$(filter-out -lfl  -ldl -lpthread -lssl -lcrypto, $(LIBS))