Browse code

Merge branch 'ser_core_cvs'

* ser_core_cvs:
tcp: fix compilation problem on solaris (FIONREAD)
core: fix bad level name in new LOG()
t_check_status() checks also the blind UACs if t_pick_branch()
Documenting t_lookup_cancel() script function.
Removing set_t() from t_lookup_cancel() function, and introducing
updated udp_mtu handling code - fixes SER-433
documenting t_is_expired() function
t_is_expired() script function is introduced.
* logging API updated (see doc/logging-api.txt for details)
- AS support disabled by default.
When building the route set of ACKs for local UACs, only the reply is now
In case the AVP is a regexp, an allocation is required to build an AVP
Currently, SER matches E2E ACKs only if there is an equality between From HF
The calculate_routeset_length() produces an invalid result in the case
'memapp' and 'append_mem_block' are now both only used in source
"Route :" prefix (and separator) is used some more time across the
script: udp_mtu fallback script config & commands
core: forward: tcp fallback for big udp packets

Conflicts:
action.c
cfg.y
cfg_core.c
cfg_core.h
dprint.h - updated to the new logging api from ser, while
keeping the kamailio compatibility macros and
CRIT().
usr_avp.h

Andrei Pelinescu-Onciul authored on 20/02/2009 16:22:16
Showing 39 changed files
... ...
@@ -456,6 +456,8 @@ endif
456 456
 #		core that the DNS servers are down. No DNS query is performed
457 457
 #		when the servers are unreachable, and even expired resource
458 458
 #		records are used from the cache. (requires external watchdog)
459
+# -DWITH_AS_SUPPORT
460
+#		adds support for Application Server interface
459 461
 # Sometimes is needes correct non-quoted $OS. HACK: gcc translates known OS to number ('linux'), so there is added underscore
460 462
 
461 463
 DEFS= $(extra_defs) \
... ...
@@ -1438,6 +1440,16 @@ ifeq  ($(OS), solaris)
1438 1438
 	ifeq ($(NO_SELECT),)
1439 1439
 		DEFS+=-DHAVE_SELECT
1440 1440
 	endif
1441
+	# check for filio.h
1442
+	filio_h_locations= /usr/include/sys/filio.h \
1443
+						$(LOCALBASE)/include/sys/filio.h
1444
+	has_filio_h=$(shell for r in $(filio_h_locations); do \
1445
+						if  [ -r "$$r" ] ; then echo yes; exit; fi \
1446
+						done;\
1447
+				)
1448
+	ifeq ($(has_filio_h), yes)
1449
+		DEFS+=-DHAVE_FILIO_H
1450
+	endif
1441 1451
 	ifeq ($(mode), release)
1442 1452
 		#use these only if you're using gcc with Solaris ld
1443 1453
 		#LDFLAGS=-O2 $(PROFILE)
... ...
@@ -29,6 +29,8 @@ override static_modules_path=
29 29
 # should be set in Makefile of apart module
30 30
 # INCLUDES += -I$(COREPATH)
31 31
 
32
+DEFS += -DMOD_NAME='"$(MOD_NAME)"'
33
+
32 34
 ifneq ($(makefile_defs_included),1)
33 35
 $(error "the local makefile does not include Makefile.defs!")
34 36
 endif
... ...
@@ -97,7 +97,16 @@ modules:
97 97
  - blst      - new module containing script blacklist manipulations functions
98 98
                (the source of a message can be blacklisted, removed from the
99 99
                 blacklist or checked for presence in the blacklist).
100
- - tm        - added t_reset_fr(), t_reset_retr(), t_reset_max_lifetime()
100
+ - tm        - added API function t_get_canceled_ident(): returns the hash 
101
+               coordinates (bucket/index) of the transaction the currently 
102
+               processed CANCEL is targeting. Requires AS support enabled.
103
+             - added API function ack_local_uac(): allow generating the ACKs 
104
+               for 2xx'ed locally originated INVITEs - new headers and body can
105
+               now also be appended to it. Requires AS support enabled.
106
+             - matching of E2E ACKs no longer requires full From HF identity,
107
+               but rather only tag equality (this behaviour can be changed by
108
+               defining TM_E2E_ACK_CHECK_FROM_URI)
109
+             - added t_reset_fr(), t_reset_retr(), t_reset_max_lifetime()
101 110
              - t_relay_to renamed to t_relay_to_avp (undocumented function)
102 111
              - t_relay() can now also take host and port parameters (e.g.
103 112
                t_relay(host, port)), behaving like a statefull 
... ...
@@ -220,6 +229,10 @@ modules:
220 220
                         - t_set_retr(t1, t2) - changes the retransmissions
221 221
                            intervals on the fly, on a per transaction basis.
222 222
 core:
223
+             - fallback to tcp or other congestion controlled transport 
224
+               protocol if a forwarded udp sip request is greater then 
225
+               udp_mtu (config). Default off. See udp_mtu and 
226
+               udp_mtu_try_proto.
223 227
              - sctp support (one-to-many, work in progress, for now linux
224 228
                only with no fallback to one-to-one on full send buffers)
225 229
              - partial cygwin (windows) support revived: core+static modules, 
... ...
@@ -240,6 +253,17 @@ core:
240 240
                between the short name and long name in cache as CNAME record
241 241
 
242 242
 new config variables:
243
+  udp_mtu = number - fallback to another protocol (udp_mtu_try_proto must be
244
+                     set also either globally or per packet) if the constructed
245
+                     request size is greater then udp_mtu.
246
+                     Recommended size: 1300. Default: 0 (off).
247
+  udp_mtu_try_proto = TCP|TLS|SCTP|UDP - if udp_mtu !=0 and udp forwarded
248
+                     request size (after adding all the "local" headers) >
249
+                     udp_mtu, use this protocol instead of udp. Only the
250
+                     Via header will be updated (e.g. The Record-Route
251
+                     will be the one built for udp).
252
+                     Default: UDP (off). Recommended: TCP.
253
+  force_rport =yes/no - like force_rport(), but works globally.
243 254
   disable_sctp = yes/no - disable sctp support (default auto, see enable_sctp)
244 255
   enable_sctp = 0/1/2  - disable (0)/enable (1)/auto (2) sctp support, 
245 256
                          default auto (2)
... ...
@@ -260,8 +284,8 @@ new config variables:
260 260
                       hosts (default: 0).
261 261
   server_id = number - A configurable unique server id that can be used to
262 262
                        discriminate server instances within a cluster of
263
-                       servers when all other information, such as IP adddresses
264
-                       are same.
263
+                       servers when all other information, such as IP addresses
264
+                       are the same.
265 265
   loadpath = <modules path> - directory where to load the modules from (-L
266 266
      equivalent); modules can be loaded simply by specifying their name
267 267
      (loadmodule "maxfwd")
... ...
@@ -356,6 +380,11 @@ new config variables:
356 356
     is not initialized at startup and cannot be enabled runtime,
357 357
     that saves some memory.
358 358
 
359
+new script commands:
360
+  udp_mtu_try_proto(TCP|TLS|SCTP|UDP) - same as udp_mtu_try_proto=... (see
361
+    above), but works per packet and not globally.
362
+
363
+
359 364
 build system:
360 365
  - check defines and includes used at compile time and if different 
361 366
    force rebuilding everything in the current dir (creates a new file: 
... ...
@@ -44,10 +44,11 @@
44 44
  *  2006-07-27  dns cache and dns based send address failover support (andrei)
45 45
  *  2006-12-06  on popular request last_retcode set also by module functions
46 46
  *              (andrei)
47
- *  2007-06-14  run_actions & do_action need a ctx or handle now, no more 
47
+ *  2007-06-14  run_actions & do_action need a ctx or handle now, no more
48 48
  *               static vars (andrei)
49 49
  *  2008-11-18  support for variable parameter module functions (andrei)
50 50
  *  2008-12-03  use lvalues/rvalues for assignments (andrei)
51
+ *  2008-12-17  added UDP_MTU_TRY_PROTO_T (andrei)
51 52
  */
52 53
 
53 54
 
... ...
@@ -228,7 +229,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
228 228
 #endif
229 229
 				}
230 230
 
231
-#ifdef HONOR_MADDR				
231
+#ifdef HONOR_MADDR
232 232
 				if (u->maddr_val.s && u->maddr_val.len)
233 233
 					dst_host=&u->maddr_val;
234 234
 				else
... ...
@@ -310,7 +311,7 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
310 310
 				ret=E_BUG;
311 311
 				break;
312 312
 			}
313
-			LOG(a->val[0].u.number, "%s", a->val[1].u.string);
313
+			LOG_(a->val[0].u.number, "<script>: ", "%s", a->val[1].u.string);
314 314
 			ret=1;
315 315
 			break;
316 316
 
... ...
@@ -715,11 +716,11 @@ int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
715 715
 					ret=1;  /*default is continue */
716 716
 					if (v>0) {
717 717
 						if ((a->val[1].type==ACTIONS_ST)&&a->val[1].u.data){
718
-							ret=run_actions(h, 
718
+							ret=run_actions(h,
719 719
 										(struct action*)a->val[1].u.data, msg);
720 720
 						}
721 721
 					}else if ((a->val[2].type==ACTIONS_ST)&&a->val[2].u.data){
722
-							ret=run_actions(h, 
722
+							ret=run_actions(h,
723 723
 										(struct action*)a->val[2].u.data, msg);
724 724
 					}
725 725
 				}
... ...
@@ -935,6 +936,10 @@ sw_jt_def:
935 935
 			msg->msg_flags|=FL_FORCE_RPORT;
936 936
 			ret=1; /* continue processing */
937 937
 			break;
938
+		case UDP_MTU_TRY_PROTO_T:
939
+			msg->msg_flags|= (unsigned int)a->val[0].u.number & FL_MTU_FB_MASK;
940
+			ret=1; /* continue processing */
941
+			break;
938 942
 		case SET_ADV_ADDR_T:
939 943
 			if (a->val[0].type!=STR_ST){
940 944
 				LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "
... ...
@@ -993,11 +998,11 @@ sw_jt_def:
993 993
 			ret=1; /* continue processing */
994 994
 			break;
995 995
 
996
-	 case ADD_T:
997
-	case ASSIGN_T:
996
+		case ADD_T:
997
+		case ASSIGN_T:
998 998
 			v=lval_assign(h, msg, (struct lvalue*)a->val[0].u.data,
999 999
 								  (struct rval_expr*)a->val[1].u.data);
1000
-			if (likely(v>=0)) 
1000
+			if (likely(v>=0))
1001 1001
 				ret = 1;
1002 1002
 			else if (unlikely (v == EXPR_DROP)) /* hack to quit on DROP*/
1003 1003
 				ret=0;
... ...
@@ -1090,6 +1095,3 @@ error:
1090 1090
 	h->rec_lev--;
1091 1091
 	return ret;
1092 1092
 }
1093
-
1094
-
1095
-
... ...
@@ -162,6 +162,8 @@ ROUTE_SEND onsend_route
162 162
 EXEC	exec
163 163
 FORCE_RPORT		"force_rport"|"add_rport"
164 164
 FORCE_TCP_ALIAS		"force_tcp_alias"|"add_tcp_alias"
165
+UDP_MTU		"udp_mtu"
166
+UDP_MTU_TRY_PROTO	"udp_mtu_try_proto"
165 167
 SETFLAG		setflag
166 168
 RESETFLAG	resetflag
167 169
 ISFLAGSET	isflagset
... ...
@@ -491,6 +493,9 @@ EAT_ABLE	[\ \t\b\r]
491 491
 <INITIAL>{FORCE_RPORT}	{ count(); yylval.strval=yytext; return FORCE_RPORT; }
492 492
 <INITIAL>{FORCE_TCP_ALIAS}	{ count(); yylval.strval=yytext;
493 493
 								return FORCE_TCP_ALIAS; }
494
+<INITIAL>{UDP_MTU}	{ count(); yylval.strval=yytext; return UDP_MTU; }
495
+<INITIAL>{UDP_MTU_TRY_PROTO}	{ count(); yylval.strval=yytext;
496
+									return UDP_MTU_TRY_PROTO; }
494 497
 <INITIAL>{IF}	{ count(); yylval.strval=yytext; return IF; }
495 498
 <INITIAL>{ELSE}	{ count(); yylval.strval=yytext; return ELSE; }
496 499
 
... ...
@@ -129,6 +129,7 @@
129 129
 #include "lvalue.h"
130 130
 #include "rvalue.h"
131 131
 #include "sr_compat.h"
132
+#include "msg_translator.h"
132 133
 
133 134
 #include "config.h"
134 135
 #include "cfg_core.h"
... ...
@@ -274,6 +275,8 @@ static struct case_stms* mk_case_stm(struct rval_expr* ct, struct action* a);
274 274
 %token REVERT_URI
275 275
 %token FORCE_RPORT
276 276
 %token FORCE_TCP_ALIAS
277
+%token UDP_MTU
278
+%token UDP_MTU_TRY_PROTO
277 279
 %token IF
278 280
 %token ELSE
279 281
 %token SET_ADV_ADDRESS
... ...
@@ -1296,6 +1299,15 @@ assign_stm:
1296 1296
 	| STUN_ALLOW_FP EQUAL NUMBER { IF_STUN(stun_allow_fp=$3) ; }
1297 1297
 	| STUN_ALLOW_FP EQUAL error{ yyerror("number expected"); }
1298 1298
     | SERVER_ID EQUAL NUMBER { server_id=$3; }
1299
+	| UDP_MTU EQUAL NUMBER { default_core_cfg.udp_mtu=$3; }
1300
+	| UDP_MTU EQUAL error { yyerror("number expected"); }
1301
+	| FORCE_RPORT EQUAL NUMBER 
1302
+		{ default_core_cfg.force_rport=$3; fix_global_req_flags(0); }
1303
+	| FORCE_RPORT EQUAL error { yyerror("boolean value expected"); }
1304
+	| UDP_MTU_TRY_PROTO EQUAL proto
1305
+		{ default_core_cfg.udp_mtu_try_proto=$3; fix_global_req_flags(0); }
1306
+	| UDP_MTU_TRY_PROTO EQUAL error
1307
+		{ yyerror("TCP, TLS, SCTP or UDP expected"); }
1299 1308
 	| cfg_var
1300 1309
 	| error EQUAL { yyerror("unknown config variable"); }
1301 1310
 	;
... ...
@@ -2556,6 +2568,10 @@ cmd:
2556 2556
 		#endif
2557 2557
 	}
2558 2558
 	| FORCE_TCP_ALIAS LPAREN error RPAREN	{$$=0; yyerror("bad argument, number expected"); }
2559
+	| UDP_MTU_TRY_PROTO LPAREN proto RPAREN
2560
+		{ $$=mk_action(UDP_MTU_TRY_PROTO_T, 1, NUMBER_ST, $3); }
2561
+	| UDP_MTU_TRY_PROTO LPAREN error RPAREN
2562
+		{ $$=0; yyerror("bad argument, UDP, TCP, TLS or SCTP expected"); }
2559 2563
 	| SET_ADV_ADDRESS LPAREN listen_id RPAREN {
2560 2564
 		$$=0;
2561 2565
 		if ((str_tmp=pkg_malloc(sizeof(str)))==0) {
... ...
@@ -41,11 +41,12 @@
41 41
 #if defined PKG_MALLOC || defined SHM_MEM
42 42
 #include "pt.h"
43 43
 #endif
44
+#include "msg_translator.h" /* fix_global_req_flags() */
44 45
 #include "cfg/cfg.h"
45 46
 #include "cfg_core.h"
46 47
 
47 48
 struct cfg_group_core default_core_cfg = {
48
-	L_DEFAULT, /*  print only msg. < L_WARN */
49
+	L_WARN, 	/*  print only msg. < L_WARN */
49 50
 	LOG_DAEMON,	/* log_facility -- see syslog(3) */
50 51
 #ifdef USE_DST_BLACKLIST
51 52
 	/* blacklist */
... ...
@@ -89,6 +90,9 @@ struct cfg_group_core default_core_cfg = {
89 89
 	0, /* mem_dump_shm */
90 90
 #endif
91 91
 	DEFAULT_MAX_WHILE_LOOPS, /* max_while_loops */
92
+	0, /* udp_mtu (disabled by default) */
93
+	0, /* udp_mtu_try_proto -> default disabled */
94
+	0  /* force_rport */ 
92 95
 };
93 96
 
94 97
 void	*core_cfg = &default_core_cfg;
... ...
@@ -180,5 +184,12 @@ cfg_def_t core_cfg_def[] = {
180 180
 #endif
181 181
 	{"max_while_loops",	CFG_VAR_INT|CFG_ATOMIC,	0, 0, 0, 0,
182 182
 		"maximum iterations allowed for a while loop" },
183
+	{"udp_mtu",	CFG_VAR_INT|CFG_ATOMIC,	0, 65535, 0, 0,
184
+		"fallback to a congestion controlled protocol if send size"
185
+			" exceeds udp_mtu"},
186
+	{"udp_mtu_try_proto", CFG_VAR_INT, 1, 4, 0, fix_global_req_flags,
187
+		"if send size > udp_mtu use proto (1 udp, 2 tcp, 3 tls, 4 sctp)"},
188
+	{"force_rport",     CFG_VAR_INT, 0, 1,  0, fix_global_req_flags,
189
+		"force rport for all the received messages" },
183 190
 	{0, 0, 0, 0, 0, 0}
184 191
 };
... ...
@@ -86,6 +86,9 @@ struct cfg_group_core {
86 86
 	int mem_dump_shm;
87 87
 #endif
88 88
 	int max_while_loops;
89
+	int udp_mtu; /**< maximum send size for udp, if > try another protocol*/
90
+	int udp_mtu_try_proto; /**< if packet> udp_mtu, try proto (e.g. TCP) */
91
+	int force_rport; /**< if set rport will always be forced*/
89 92
 };
90 93
 
91 94
 extern struct cfg_group_core default_core_cfg;
... ...
@@ -73,6 +73,12 @@
73 73
 #define MY_VIA "Via: SIP/2.0/UDP "
74 74
 #define MY_VIA_LEN (sizeof(MY_VIA) - 1)
75 75
 
76
+#define ROUTE_PREFIX "Route: "
77
+#define ROUTE_PREFIX_LEN (sizeof(ROUTE_PREFIX) - 1)
78
+
79
+#define ROUTE_SEPARATOR ", "
80
+#define ROUTE_SEPARATOR_LEN (sizeof(ROUTE_SEPARATOR) - 1)
81
+
76 82
 #define CONTENT_LENGTH "Content-Length: "
77 83
 #define CONTENT_LENGTH_LEN (sizeof(CONTENT_LENGTH)-1)
78 84
 
... ...
@@ -284,13 +284,13 @@ void fix_dns_flags(str *name)
284 284
 #ifdef DNS_SRV_LB
285 285
 		dns_flags|=DNS_SRV_RR_LB;
286 286
 #else
287
-		LOG(L_WARN, "WARING: fix_dns_flags: SRV loadbalaning is set, but"
287
+		LOG(L_WARN, "WARNING: fix_dns_flags: SRV loadbalaning is set, but"
288 288
 					" support for it is not compiled -- ignoring\n");
289 289
 #endif
290 290
 	}
291 291
 	if (cfg_get(core, core_cfg, dns_try_naptr)) {
292 292
 #ifndef USE_NAPTR
293
-	LOG(L_WARN, "WARING: fix_dns_flags: NAPTR support is enabled, but"
293
+	LOG(L_WARN, "WARNING: fix_dns_flags: NAPTR support is enabled, but"
294 294
 				" support for it is not compiled -- ignoring\n");
295 295
 #endif
296 296
 		dns_flags|=DNS_TRY_NAPTR;
297 297
new file mode 100644
... ...
@@ -0,0 +1,134 @@
0
+  _                      _                  _    ____ ___ 
1
+ | |    ___   __ _  __ _(_)_ __   __ _     / \  |  _ \_ _|
2
+ | |   / _ \ / _` |/ _` | | '_ \ / _` |   / _ \ | |_) | | 
3
+ | |__| (_) | (_| | (_| | | | | | (_| |  / ___ \|  __/| | 
4
+ |_____\___/ \__, |\__, |_|_| |_|\__, | /_/   \_\_|  |___|
5
+            |___/ |___/         |___/                    
6
+                         Ondrej Martinek <ondra@iptel.org>
7
+                                              January 2009
8
+
9
+This document contains the short description of the logging API in SER
10
+for developers.
11
+
12
+Source files:
13
+    dprint.h
14
+    dprint.c
15
+
16
+ Compile-time control macros
17
+=============================
18
+
19
+    NO_LOG
20
+	If defined, logging is completely disabled in SER and no messages
21
+        are produced at all
22
+	       
23
+    NO_DEBUG
24
+	If defined, logging messages do not include the source filename and
25
+	line location info
26
+
27
+ Logging levels
28
+================
29
+
30
+    L_DBG   ... Debugging message (the lowest level)
31
+    L_INFO  ... Info message
32
+    L_WARN  ... Warning message
33
+    L_ERR   ... Error message
34
+    L_CRIT  ... Critical message
35
+    L_ALERT ... Alert message (the highest level)
36
+
37
+    The levels are implemented as integer macros.
38
+
39
+ Related variables
40
+===================
41
+
42
+    debug
43
+	The config.framework setting that contains the current logging level.
44
+	The initial value can be specified by "debug" parameter in ser.cfg or
45
+	by -d options on the command-line.  The default value is L_WARN.
46
+
47
+    log_stderror
48
+	The global variable which specifies whether the log messages should be
49
+	send to the standard error output or syslog (equals to zero).
50
+	Its value can be specified by "log_stderr" parameter in ser.cfg or
51
+	-E option on the command-line.
52
+	
53
+    log_facility
54
+	The config.framework setting that contains the current facility for
55
+	logging to syslog.
56
+	The initial value can be specified by "log_facility" parameter in
57
+	ser.cfg.  The default value is LOG_DAEMON.
58
+
59
+ Macro functions
60
+=================
61
+
62
+    * short macro aliases:
63
+	DBG(FMT, ARGS...)   alias for LOG(L_DBG, FMT, ARGS...)
64
+        INFO(FMT, ARGS...)  alias for LOG(L_INFO, FMT, ARGS...)
65
+        WARN(FMT, ARGS...)  alias for LOG(L_WARN, FMT, ARGS...)
66
+        ERR(FMT, ARGS...)   alias for LOG(L_ERR, FMT, ARGS...)
67
+        BUG(FMT, ARGS...)   alias for LOG(L_CRIT, FMT, ARGS...)
68
+        ALERT(FMT, ARGS...) alias for LOG(L_ALERT, FMT, ARGS...)
69
+
70
+    * LOG(LEVEL, FMT, ARGS...) macro
71
+	Prints the log message on stderr or syslog if the current debug level
72
+	is greater or equal to LEVEL.  The message has the following format:
73
+
74
+          - for messages by core:
75
+              PROC(PID) LEVEL: <core> [FILE:LINE]: MESSAGE
76
+
77
+          - for messages by modules:
78
+              PROC(PID) LEVEL: MODULE [FILE:LINE]: MESSAGE
79
+	      
80
+          - for messages by log(), xlog(), xdbg() script funcitons:
81
+              PROC(PID) LEVEL: <script>: MESSAGE
82
+
83
+	PROC is the SER process number and PID is the linux process ID.
84
+        LEVEL is one of "DEBUG", "INFO", "NOTICE", "WARNING", "ERROR",
85
+	"ALERT" and "BUG" strings.  MESSAGE is constructed from printf-like
86
+	arguments FMT and ARGS.
87
+
88
+        [FILE:LINE] location info is not present if NO_DEBUG macro is defined.
89
+  
90
+	Use of shorter aliases is preferred if LEVEL is a preprocess-time
91
+	constant.
92
+	
93
+    * LOG_(LEVEL, PREFIX, FMT, ARGS...) macro
94
+	Prints the log message on stderr or syslog if the current debug level
95
+	is greater or equal to LEVEL.  The message has the following format:
96
+	
97
+              PROC(PID) LEVEL: PREFIXMESSAGE
98
+
99
+	This is an internal macro try to avoid using it.
100
+
101
+
102
+--------------------------------------------------------------------------------
103
+
104
+ APPENDIX: Summary of the changes to the original API
105
+======================================================
106
+
107
+  - LOG(LEVEL, FMT, ARGS...) and the short macro corresponding to LEVEL level
108
+    made eqvivalent (eg. LOG(L_DBG, FMT, ARGS...) and DBG(FMT, ARGS...) prints
109
+    always the same message)
110
+
111
+  - changed the format of log messages produced by the macros to include
112
+    the log level, module name, filename, line (if applicable)
113
+     
114
+  - added new, internal LOG_(LEVEL, PREFIX, FORMAT, ARGS...) macro
115
+
116
+  - removed DPrint() and DEBUG() macros, L_DEFAULT log level and dprint()
117
+    function
118
+
119
+!!!
120
+!!! IMPORTANT! READ ME!
121
+!!!
122
+!!!  These changes (mainly the first two) require reformating of the most log
123
+!!!  messages in SER core and module source files.  This step can be done
124
+!!!  automatically by running "scripts/logging/fix-logs-all" script BUT it
125
+!!!  was NOT originally performed because it would have generated too many
126
+!!!  changes in CVS which was discouraged by Andrei.  Instead, the developers
127
+!!!  are expected to run it when ready.
128
+!!!
129
+!!! IMPORTANT! READ ME!
130
+!!!  
131
+
132
+--
133
+$Id$
... ...
@@ -29,48 +29,48 @@
29 29
  */
30 30
 
31 31
  
32
-#include "dprint.h"
33 32
 #include "globals.h"
34
-#include "pt.h"
33
+#include "dprint.h"
35 34
  
36 35
 #include <stdarg.h>
37 36
 #include <stdio.h>
38 37
 #include <strings.h>
39 38
 
40
-volatile int dprint_crit=0; /* signal protection: !=0 when dprint/LOG/DBG are
41
-								printing */
39
+#ifndef NO_SIG_DEBUG
40
+/* signal protection: !=0 when LOG/DBG/... are printing */
41
+volatile int dprint_crit = 0; 
42
+#endif
42 43
 
43 44
 static char* str_fac[]={"LOG_AUTH","LOG_CRON","LOG_DAEMON",
44
-					"LOG_KERN","LOG_LOCAL0","LOG_LOCAL1",
45
-					"LOG_LOCAL2","LOG_LOCAL3","LOG_LOCAL4","LOG_LOCAL5",
46
-					"LOG_LOCAL6","LOG_LOCAL7","LOG_LPR","LOG_MAIL",
47
-					"LOG_NEWS","LOG_USER","LOG_UUCP",
45
+			"LOG_KERN","LOG_LOCAL0","LOG_LOCAL1",
46
+			"LOG_LOCAL2","LOG_LOCAL3","LOG_LOCAL4","LOG_LOCAL5",
47
+			"LOG_LOCAL6","LOG_LOCAL7","LOG_LPR","LOG_MAIL",
48
+			"LOG_NEWS","LOG_USER","LOG_UUCP",
48 49
 #ifndef __OS_solaris
49
-					"LOG_AUTHPRIV","LOG_FTP","LOG_SYSLOG",
50
+			"LOG_AUTHPRIV","LOG_FTP","LOG_SYSLOG",
50 51
 #endif
51
-					0};
52
+			0};
53
+			
52 54
 static int int_fac[]={LOG_AUTH ,  LOG_CRON , LOG_DAEMON ,
53
-					LOG_KERN , LOG_LOCAL0 , LOG_LOCAL1 ,
54
-					LOG_LOCAL2 , LOG_LOCAL3 , LOG_LOCAL4 , LOG_LOCAL5 ,
55
-					LOG_LOCAL6 , LOG_LOCAL7 , LOG_LPR , LOG_MAIL ,
56
-					LOG_NEWS , LOG_USER , LOG_UUCP
55
+		      LOG_KERN , LOG_LOCAL0 , LOG_LOCAL1 ,
56
+		      LOG_LOCAL2 , LOG_LOCAL3 , LOG_LOCAL4 , LOG_LOCAL5 ,
57
+		      LOG_LOCAL6 , LOG_LOCAL7 , LOG_LPR , LOG_MAIL ,
58
+		      LOG_NEWS , LOG_USER , LOG_UUCP,
57 59
 #ifndef __OS_solaris
58
-					,LOG_AUTHPRIV,LOG_FTP,LOG_SYSLOG
60
+		      LOG_AUTHPRIV,LOG_FTP,LOG_SYSLOG,
59 61
 #endif
60
-					};
61
-
62
-
63
-void dprint(char * format, ...)
64
-{
65
-	va_list ap;
66
-
67
-	fprintf(stderr, "%2d(%d) ", process_no, my_pid());
68
-	va_start(ap, format);
69
-	vfprintf(stderr,format,ap);
70
-	fflush(stderr);
71
-	va_end(ap);
72
-}
62
+		      0};
73 63
 
64
+struct log_level_info log_level_info[] = {
65
+	{"ALERT", LOG_ALERT},	  /* L_ALERT */
66
+	{"CRITICAL", LOG_CRIT},   /* L_CRIT2 */
67
+	{"BUG", LOG_CRIT},        /* L_CRIT */
68
+	{"ERROR", LOG_ERR},       /* L_ERR */
69
+	{"WARNING", LOG_WARNING}, /* L_WARN */
70
+	{"NOTICE", LOG_NOTICE},   /* L_NOTICE */
71
+	{"INFO", LOG_INFO},       /* L_INFO */
72
+	{"DEBUG", LOG_DEBUG}	  /* L_DBG */
73
+};
74 74
 
75 75
 int str2facility(char *s)
76 76
 {
... ...
@@ -25,242 +25,215 @@
25 25
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
26 26
  */
27 27
 
28
-
29
-
30 28
 #ifndef dprint_h
31 29
 #define dprint_h
32 30
 
31
+#include <assert.h>
33 32
 #include <syslog.h>
34
-#include "cfg_core.h"
35
-
36
-
37
-#define L_ALERT -3
38
-#define L_CRIT  -2
39
-#define L_ERR   -1
40
-#define L_DEFAULT 0
41
-#define L_WARN   1
42
-#define L_NOTICE 2
43
-#define L_INFO   3
44
-#define L_DBG    4
45
-
46
-/* vars:*/
47
-
48
-extern int log_stderr;
49
-extern volatile int dprint_crit; /* protection against "simultaneous"
50
-									printing from signal handlers */
51
-
52
-#ifdef NO_SIG_DEBUG
53
-#define DPRINT_NON_CRIT		(1)
54
-#define DPRINT_CRIT_ENTER
55
-#define DPRINT_CRIT_EXIT
56
-#else
57
-#define DPRINT_NON_CRIT		(dprint_crit==0)
58
-#define DPRINT_CRIT_ENTER	(dprint_crit++)
59
-#define DPRINT_CRIT_EXIT	(dprint_crit--)
60
-#endif
61
-
62
-#define DPRINT_LEV	1
63
-/* priority at which we log */
64
-#define DPRINT_PRIO LOG_DEBUG
33
+#include <stdio.h> /* stderr, fprintf() */
65 34
 
35
+#include "cfg_core.h"
66 36
 
67
-void dprint (char* format, ...);
68
-
69
-int str2facility(char *s);
70
-int log_facility_fixup(void *handle, str *name, void **val);
71 37
 
72 38
 /* C >= 99 has __func__, older gcc versions have __FUNCTION__ */
73 39
 #if __STDC_VERSION__ < 199901L
74
-# if __GNUC__ >= 2
75
-#  define _FUNC_NAME_ __FUNCTION__
76
-# else
77
-#  define _FUNC_NAME_ ""
78
-# endif
40
+#	if __GNUC__ >= 2
41
+#		define _FUNC_NAME_ __FUNCTION__
42
+#	else
43
+#		define _FUNC_NAME_ ""
44
+#	endif
79 45
 #else
80
-# define _FUNC_NAME_ __func__
46
+#	define _FUNC_NAME_ __func__
81 47
 #endif
82 48
 
49
+#ifdef NO_DEBUG
50
+#	ifdef MOD_NAME
51
+#		define LOC_INFO		MOD_NAME ": "
52
+#	else
53
+#		define LOC_INFO		"<core>: "
54
+#	endif
55
+#else
56
+#	define XCT2STR(i) #i
57
+#	define CT2STR(l)  XCT2STR(l)
58
+#
59
+#	ifdef MOD_NAME
60
+#		define LOC_INFO		MOD_NAME " [" __FILE__ ":" CT2STR(__LINE__) "]: "
61
+#	else
62
+#		define LOC_INFO		"<core> [" __FILE__ ":" CT2STR(__LINE__) "]: "
63
+#	endif
64
+#
65
+#	ifdef NO_LOG
66
+#		undef NO_LOG
67
+#	endif
68
+#endif /* NO_DEBUG */
83 69
 
84
-#define XCT2STR(i) #i
85
-#define CT2STR(l) XCT2STR(l)
86 70
 
87
-#define LOC_INFO	__FILE__ ":" CT2STR(__LINE__) ": "
71
+/*
72
+ * Log levels
73
+ */
74
+#define L_ALERT		-4
75
+#define L_CRIT2		-3  /* like L_CRIT, but not used for BUGs */
76
+#define L_CRIT  	-2  /* used only for BUG */
77
+#define L_ERR   	-1
78
+#define L_WARN   	0
79
+#define L_NOTICE 	1
80
+#define L_INFO   	2
81
+#define L_DBG    	3
82
+
83
+#define LOG_LEVEL2NAME(level)	(log_level_info[(level) - (L_ALERT)].name)
84
+#define LOG2SYSLOG_LEVEL(level) \
85
+	(log_level_info[(level) - (L_ALERT)].syslog_level)
86
+
87
+
88
+/* my_pid(), process_no are from pt.h but we cannot #include it here
89
+   because of circular dependencies */
90
+extern int process_no;
91
+extern int my_pid();
92
+
93
+/* non-zero if logging to stderr instead to the syslog */
94
+extern int log_stderr;
88 95
 
96
+/* maps log levels to their string name and corresponding syslog level */
89 97
 
90
-#define is_printable(level) (cfg_get(core, core_cfg, debug)>=(level))
98
+struct log_level_info {
99
+ 	char *name;
100
+	int syslog_level;
101
+};
91 102
 
92
-#ifdef NO_DEBUG
93
-	#ifdef __SUNPRO_C
94
-		#define DPrint(...)
95
-	#else
96
-		#define DPrint(fmt, args...)
97
-	#endif
98
-#else
99
-	#ifdef __SUNPRO_C
100
-		#define DPrint( ...) \
101
-			do{ \
102
-				if ((cfg_get(core, core_cfg, debug)>=DPRINT_LEV) && DPRINT_NON_CRIT){ \
103
-					DPRINT_CRIT_ENTER; \
104
-					if (log_stderr){ \
105
-						dprint (__VA_ARGS__); \
106
-					}else{ \
107
-						syslog(DPRINT_LEV|cfg_get(core, core_cfg, log_facility), \
108
-							__VA_ARGS__); \
109
-					}\
110
-					DPRINT_CRIT_EXIT; \
111
-				} \
112
-			}while(0)
113
-	#else
114
-			#define DPrint(fmt,args...) \
115
-			do{ \
116
-				if ((cfg_get(core, core_cfg, debug)>=DPRINT_LEV) && DPRINT_NON_CRIT){ \
117
-					DPRINT_CRIT_ENTER; \
118
-					if (log_stderr){ \
119
-						dprint (fmt, ## args); \
120
-					}else{ \
121
-						syslog(DPRINT_LEV|cfg_get(core, core_cfg, log_facility), \
122
-							fmt, ## args); \
123
-					}\
124
-					DPRINT_CRIT_EXIT; \
125
-				} \
126
-			}while(0)
127
-	#endif
103
+#define is_printable(level) (cfg_get(core, core_cfg, debug)>=(level))
104
+extern struct log_level_info log_level_info[];
128 105
 
106
+#ifndef NO_SIG_DEBUG
107
+/* protection against "simultaneous" printing from signal handlers */
108
+extern volatile int dprint_crit; 
129 109
 #endif
130 110
 
131
-#ifndef NO_DEBUG
132
-	#undef NO_LOG
133
-#endif
111
+int str2facility(char *s);
112
+int log_facility_fixup(void *handle, str *name, void **val);
134 113
 
114
+
115
+/*
116
+ * General logging macros
117
+ *
118
+ * LOG_(level, prefix, fmt, ...) prints "printf"-formatted log message to
119
+ * stderr (if `log_stderr' is non-zero) or to syslog.  Note that `fmt' must
120
+ * be constant. `prefix' is added to the beginning of the message.
121
+ *
122
+ * LOG(level, fmt, ...) is same as LOG_() with LOC_INFO prefix.
123
+ */
135 124
 #ifdef NO_LOG
136
-	#ifdef __SUNPRO_C
137
-		#define LOG(lev, ...)
138
-	#else
139
-		#define LOG(lev, fmt, args...)
140
-	#endif
125
+
126
+#	ifdef __SUNPRO_C
127
+#		define LOG_(level, prefix, fmt, ...)
128
+#		define LOG(level, fmt, ...)
129
+#	else
130
+#		define LOG_(level, prefix, fmt, args...)
131
+#		define LOG(level, fmt, args...)
132
+#	endif
133
+
141 134
 #else
142
-	#ifdef __SUNPRO_C
143
-		#define LOG(lev, ...) \
135
+
136
+#	ifdef NO_SIG_DEBUG
137
+#		define DPRINT_NON_CRIT		(1)
138
+#		define DPRINT_CRIT_ENTER
139
+#		define DPRINT_CRIT_EXIT
140
+#	else
141
+#		define DPRINT_NON_CRIT		(dprint_crit==0)
142
+#		define DPRINT_CRIT_ENTER	(dprint_crit++)
143
+#		define DPRINT_CRIT_EXIT		(dprint_crit--)
144
+#	endif
145
+
146
+#	ifdef __SUNPRO_C
147
+#		define LOG_(level, prefix, fmt, ...) \
144 148
 			do { \
145
-				if ((cfg_get(core, core_cfg, debug)>=(lev)) && DPRINT_NON_CRIT){ \
149
+				if (cfg_get(core, core_cfg, debug) >= (level) && \
150
+						DPRINT_NON_CRIT) { \
146 151
 					DPRINT_CRIT_ENTER; \
147
-					if (log_stderr) dprint (__VA_ARGS__); \
148
-					else { \
149
-						switch(lev){ \
150
-							case L_CRIT: \
151
-								syslog(LOG_CRIT|cfg_get(core, core_cfg, log_facility), \
152
-									__VA_ARGS__); \
153
-								break; \
154
-							case L_ALERT: \
155
-								syslog(LOG_ALERT|cfg_get(core, core_cfg, log_facility), \
156
-									__VA_ARGS__); \
157
-								break; \
158
-							case L_ERR: \
159
-								syslog(LOG_ERR|cfg_get(core, core_cfg, log_facility), \
160
-									__VA_ARGS__); \
161
-								break; \
162
-							case L_WARN: \
163
-								syslog(LOG_WARNING|cfg_get(core, core_cfg, log_facility), \
164
-									__VA_ARGS__);\
165
-								break; \
166
-							case L_NOTICE: \
167
-								syslog(LOG_NOTICE|cfg_get(core, core_cfg, log_facility), \
168
-									__VA_ARGS__); \
169
-								break; \
170
-							case L_INFO: \
171
-								syslog(LOG_INFO|cfg_get(core, core_cfg, log_facility), \
172
-									__VA_ARGS__); \
173
-								break; \
174
-							case L_DBG: \
175
-								syslog(LOG_DEBUG|cfg_get(core, core_cfg, log_facility), \
176
-									__VA_ARGS__); \
177
-								break; \
178
-						} \
152
+					assert(((level) >= L_ALERT) && ((level) <= L_DBG)); \
153
+					if (log_stderr) { \
154
+						fprintf(stderr, "%2d(%d) %s: %s" fmt, \
155
+								process_no, my_pid(), LOG_LEVEL2NAME(level),\
156
+								(prefix), __VA_ARGS__); \
157
+					} else { \
158
+						syslog(LOG2SYSLOG_LEVEL(level) | \
159
+									cfg_get(core, core_cfg, log_facility), \
160
+								"%s: %s" fmt, LOG_LEVEL2NAME(level),\
161
+								(prefix), __VA_ARGS__); \
179 162
 					} \
180 163
 					DPRINT_CRIT_EXIT; \
181 164
 				} \
182
-			}while(0)
183
-	#else
184
-		#define LOG(lev, fmt, args...) \
165
+			} while(0)
166
+			
167
+#		define LOG(level, fmt, ...)  LOG_((level), LOC_INFO, fmt, __VA_ARGS__)
168
+
169
+#	else
170
+#		define LOG_(level, prefix, fmt, args...) \
185 171
 			do { \
186
-				if ((cfg_get(core, core_cfg, debug)>=(lev)) && DPRINT_NON_CRIT){ \
172
+				if (cfg_get(core, core_cfg, debug) >= (level) && \
173
+						DPRINT_NON_CRIT) { \
187 174
 					DPRINT_CRIT_ENTER; \
188
-					if (log_stderr) dprint (fmt, ## args); \
189
-					else { \
190
-						switch(lev){ \
191
-							case L_CRIT: \
192
-								syslog(LOG_CRIT|cfg_get(core, core_cfg, log_facility), \
193
-									fmt, ##args); \
194
-								break; \
195
-							case L_ALERT: \
196
-								syslog(LOG_ALERT|cfg_get(core, core_cfg, log_facility), \
197
-									fmt, ##args); \
198
-								break; \
199
-							case L_ERR: \
200
-								syslog(LOG_ERR|cfg_get(core, core_cfg, log_facility), \
201
-									fmt, ##args); \
202
-								break; \
203
-							case L_WARN: \
204
-								syslog(LOG_WARNING|cfg_get(core, core_cfg, log_facility), \
205
-									fmt, ##args);\
206
-								break; \
207
-							case L_NOTICE: \
208
-								syslog(LOG_NOTICE|cfg_get(core, core_cfg, log_facility), \
209
-									fmt, ##args); \
210
-								break; \
211
-							case L_INFO: \
212
-								syslog(LOG_INFO|cfg_get(core, core_cfg, log_facility), \
213
-									fmt, ##args); \
214
-								break; \
215
-							case L_DBG: \
216
-								syslog(LOG_DEBUG|cfg_get(core, core_cfg, log_facility), \
217
-									fmt, ##args); \
218
-								break; \
219
-						} \
175
+					assert(((level) >= L_ALERT) && ((level) <= L_DBG)); \
176
+					if (log_stderr) { \
177
+						fprintf(stderr, "%2d(%d) %s: %s" fmt, \
178
+								process_no, my_pid(), LOG_LEVEL2NAME(level),\
179
+								(prefix), ## args); \
180
+					} else { \
181
+						syslog(LOG2SYSLOG_LEVEL(level) |\
182
+									cfg_get(core, core_cfg, log_facility), \
183
+						 		"%s: %s" fmt, LOG_LEVEL2NAME(level),\
184
+								(prefix), ## args); \
220 185
 					} \
221 186
 					DPRINT_CRIT_EXIT; \
222 187
 				} \
223
-			}while(0)
224
-	#endif /*SUN_PRO_C*/
225
-#endif
226
-
188
+			} while(0)
189
+			
190
+#		define LOG(level, fmt, args...)  LOG_((level), LOC_INFO, fmt, ## args)
191
+		
192
+#	endif /* __SUNPRO_C */
193
+#endif /* NO_LOG */
227 194
 
228
-#ifdef NO_DEBUG
229
-	#ifdef __SUNPRO_C
230
-		#define DBG(...)
231
-	#else
232
-		#define DBG(fmt, args...)
233
-	#endif
234
-#else
235
-	#ifdef __SUNPRO_C
236
-		#define DBG(...) LOG(L_DBG, __VA_ARGS__)
237
-	#else
238
-		#define DBG(fmt, args...) LOG(L_DBG, fmt, ## args)
239
-	#endif
240
-#endif
241 195
 
196
+/*
197
+ * Simplier, prefered logging macros for constant log level
198
+ */
242 199
 #ifdef __SUNPRO_C
243
-		#define DEBUG(...) DBG("DEBUG: "          LOC_INFO __VA_ARGS__)
244
-		#define ERR(...)  LOG(L_ERR, "ERROR: "    LOC_INFO __VA_ARGS__)
245
-		#define WARN(...) LOG(L_WARN, "WARNING: " LOC_INFO __VA_ARGS__)
246
-		#define INFO(...) LOG(L_INFO, "INFO: "    LOC_INFO __VA_ARGS__)
247
-		#define BUG(...) LOG(L_CRIT, "BUG: "      LOC_INFO __VA_ARGS__)
248
-		#define NOTICE(...) LOG(L_NOTICE, "NOTICE: " LOC_INFO __VA_ARGS__)
249
-		#define ALERT(...) LOG(L_ALERT, "ALERT: " LOC_INFO __VA_ARGS__)
250
-		#define CRIT(...) LOG(L_CRIT, "CRITICAL: " LOC_INFO __VA_ARGS__)
251
-#else
252
-		#define DEBUG(fmt, args...) DBG("DEBUG: "       LOC_INFO fmt, ## args)
253
-		#define ERR(fmt, args...) LOG(L_ERR, "ERROR: "  LOC_INFO fmt, ## args)
254
-		#define WARN(fmt, args...) LOG(L_WARN, "WARN: " LOC_INFO fmt, ## args)
255
-		#define INFO(fmt, args...) LOG(L_INFO, "INFO: " LOC_INFO fmt, ## args)
256
-		#define BUG(fmt, args...) LOG(L_CRIT, "BUG: "   LOC_INFO fmt, ## args)
257
-		#define NOTICE(fmt, args...) \
258
-			LOG(L_NOTICE, "NOTICE: " LOC_INFO fmt, ## args)
259
-		#define ALERT(fmt, args...) \
260
-			LOG(L_ALERT, "ALERT: " LOC_INFO fmt, ## args)
261
-		#define CRIT(fmt, args...) \
262
-			LOG(L_CRIT, "CRITICAL: " LOC_INFO fmt, ## args)
263
-#endif
200
+#	define ALERT(...)  LOG(L_ALERT,  __VA_ARGS__)
201
+#	define BUG(...)    LOG(L_CRIT,   __VA_ARGS__)
202
+#	define ERR(...)    LOG(L_ERR,    __VA_ARGS__)
203
+#	define WARN(...)   LOG(L_WARN,   __VA_ARGS__)
204
+#	define NOTICE(...) LOG(L_NOTICE, __VA_ARGS__)
205
+#	define INFO(...)   LOG(L_INFO,   __VA_ARGS__)
206
+#	define CRIT(...)    LOG(L_CRIT2,   __VA_ARGS__)
207
+
208
+#	ifdef NO_DEBUG
209
+#		define DBG(...)
210
+#	else
211
+#		define DBG(...)    LOG(L_DBG, __VA_ARGS__)
212
+#	endif		
213
+
214
+/* obsolete, do not use */
215
+#	define DEBUG(...) DBG(__VA_ARGS__)
216
+
217
+#else /* ! __SUNPRO_C */
218
+#	define ALERT(fmt, args...)  LOG(L_ALERT,  fmt, ## args)
219
+#	define BUG(fmt, args...)    LOG(L_CRIT,   fmt, ## args)
220
+#	define ERR(fmt, args...)    LOG(L_ERR,    fmt, ## args)
221
+#	define WARN(fmt, args...)   LOG(L_WARN,   fmt, ## args)
222
+#	define NOTICE(fmt, args...) LOG(L_NOTICE, fmt, ## args)
223
+#	define INFO(fmt, args...)   LOG(L_INFO,   fmt, ## args)
224
+#	define CRIT(fmt, args...)   LOG(L_CRIT2,   fmt, ## args)
225
+
226
+#	ifdef NO_DEBUG
227
+#		define DBG(fmt, args...)
228
+#	else
229
+#		define DBG(fmt, args...)    LOG(L_DBG, fmt, ## args)
230
+#	endif		
231
+
232
+/* obsolete, do not use */
233
+#	define DEBUG(fmt, args...) DBG(fmt, ## args)
234
+		
235
+#endif /* __SUNPRO_C */
236
+
264 237
 
265 238
 /* kamailio/openser compatibility */
266 239
 
... ...
@@ -274,5 +247,4 @@ int log_facility_fixup(void *handle, str *name, void **val);
274 274
 #define LM_INFO INFO
275 275
 #define LM_DBG DEBUG
276 276
 
277
-
278
-#endif /* ifndef dprint_h */
277
+#endif /* !dprint_h */
... ...
@@ -342,6 +342,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
342 342
 	struct socket_info* orig_send_sock; /* initial send_sock */
343 343
 	int ret;
344 344
 	struct ip_addr ip; /* debugging only */
345
+	char proto;
345 346
 #ifdef USE_DNS_FAILOVER
346 347
 	struct socket_info* prev_send_sock;
347 348
 	int err;
... ...
@@ -354,6 +355,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
354 354
 	
355 355
 	buf=0;
356 356
 	orig_send_sock=send_info->send_sock;
357
+	proto=send_info->proto;
357 358
 	ret=0;
358 359
 
359 360
 	if(dst){
... ...
@@ -361,7 +363,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
361 361
 		if (cfg_get(core, core_cfg, use_dns_failover)){
362 362
 			dns_srv_handle_init(&dns_srv_h);
363 363
 			err=dns_sip_resolve2su(&dns_srv_h, &send_info->to, dst, port,
364
-									&send_info->proto, dns_flags);
364
+									&proto, dns_flags);
365 365
 			if (err!=0){
366 366
 				LOG(L_ERR, "ERROR: forward_request: resolving \"%.*s\""
367 367
 						" failed: %s [%d]\n", dst->len, ZSW(dst->s),
... ...
@@ -371,7 +373,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
371 371
 			}
372 372
 		}else
373 373
 #endif
374
-		if (sip_hostport2su(&send_info->to, dst, port, &send_info->proto)<0){
374
+		if (sip_hostport2su(&send_info->to, dst, port, &proto)<0){
375 375
 			LOG(L_ERR, "ERROR: forward_request: bad host name %.*s,"
376 376
 						" dropping packet\n", dst->len, ZSW(dst->s));
377 377
 			ret=E_BAD_ADDRESS;
... ...
@@ -410,12 +412,11 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
410 410
 	do{
411 411
 #endif
412 412
 		if (orig_send_sock==0) /* no forced send_sock => find it **/
413
-			send_info->send_sock=get_send_socket(msg, &send_info->to,
414
-												send_info->proto);
413
+			send_info->send_sock=get_send_socket(msg, &send_info->to, proto);
415 414
 		if (send_info->send_sock==0){
416 415
 			LOG(L_ERR, "forward_req: ERROR: cannot forward to af %d, proto %d "
417 416
 						"no corresponding listening socket\n",
418
-						send_info->to.s.sa_family, send_info->proto);
417
+						send_info->to.s.sa_family, proto);
419 418
 			ret=ser_error=E_NO_SOCKET;
420 419
 #ifdef USE_DNS_FAILOVER
421 420
 			/* continue, maybe we find a socket for some other ip */
... ...
@@ -431,6 +432,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
431 431
 			prev_send_sock=send_info->send_sock;
432 432
 #endif
433 433
 			if (buf) pkg_free(buf);
434
+			send_info->proto=proto;
434 435
 			buf = build_req_buf_from_sip_req(msg, &len, send_info);
435 436
 			if (!buf){
436 437
 				LOG(L_ERR, "ERROR: forward_request: building failed\n");
... ...
@@ -496,7 +498,7 @@ int forward_request(struct sip_msg* msg, str* dst, unsigned short port,
496 496
 	}while(dst && cfg_get(core, core_cfg, use_dns_failover) &&
497 497
 			dns_srv_handle_next(&dns_srv_h, err) && 
498 498
 			((err=dns_sip_resolve2su(&dns_srv_h, &send_info->to, dst, port,
499
-								  &send_info->proto, dns_flags))==0));
499
+										&proto, dns_flags))==0));
500 500
 	if ((err!=0) && (err!=-E_DNS_EOR)){
501 501
 		LOG(L_ERR, "ERROR:  resolving %.*s host name in uri"
502 502
 							" failed: %s [%d] (dropping packet)\n",
... ...
@@ -642,7 +642,7 @@ void handle_sigs()
642 642
 				DBG("SIGTERM received, program terminates\n");
643 643
 			/* shutdown/kill all the children */
644 644
 			shutdown_children(SIGTERM, 1);
645
-			dprint("Thank you for flying " NAME "\n");
645
+			LOG(L_NOTICE, "Thank you for flying " NAME "\n");
646 646
 			exit(0);
647 647
 			break;
648 648
 
... ...
@@ -768,32 +768,32 @@ int install_sigs()
768 768
 {
769 769
 	/* added by jku: add exit handler */
770 770
 	if (set_sig_h(SIGINT, sig_usr) == SIG_ERR ) {
771
-		DPrint("ERROR: no SIGINT signal handler can be installed\n");
771
+		ERR("no SIGINT signal handler can be installed\n");
772 772
 		goto error;
773 773
 	}
774 774
 	/* if we debug and write to a pipe, we want to exit nicely too */
775 775
 	if (set_sig_h(SIGPIPE, sig_usr) == SIG_ERR ) {
776
-		DPrint("ERROR: no SIGINT signal handler can be installed\n");
776
+		ERR("no SIGINT signal handler can be installed\n");
777 777
 		goto error;
778 778
 	}
779 779
 	if (set_sig_h(SIGUSR1, sig_usr)  == SIG_ERR ) {
780
-		DPrint("ERROR: no SIGUSR1 signal handler can be installed\n");
780
+		ERR("no SIGUSR1 signal handler can be installed\n");
781 781
 		goto error;
782 782
 	}
783 783
 	if (set_sig_h(SIGCHLD , sig_usr)  == SIG_ERR ) {
784
-		DPrint("ERROR: no SIGCHLD signal handler can be installed\n");
784
+		ERR("no SIGCHLD signal handler can be installed\n");
785 785
 		goto error;
786 786
 	}
787 787
 	if (set_sig_h(SIGTERM , sig_usr)  == SIG_ERR ) {
788
-		DPrint("ERROR: no SIGTERM signal handler can be installed\n");
788
+		ERR("no SIGTERM signal handler can be installed\n");
789 789
 		goto error;
790 790
 	}
791 791
 	if (set_sig_h(SIGHUP , sig_usr)  == SIG_ERR ) {
792
-		DPrint("ERROR: no SIGHUP signal handler can be installed\n");
792
+		ERR("no SIGHUP signal handler can be installed\n");
793 793
 		goto error;
794 794
 	}
795 795
 	if (set_sig_h(SIGUSR2 , sig_usr)  == SIG_ERR ) {
796
-		DPrint("ERROR: no SIGUSR2 signal handler can be installed\n");
796
+		ERR("no SIGUSR2 signal handler can be installed\n");
797 797
 		goto error;
798 798
 	}
799 799
 	return 0;
... ...
@@ -74,9 +74,11 @@ Jiri Kuthan
74 74
         1.4.23. t_any_replied() 
75 75
         1.4.24. t_grep_status("code") 
76 76
         1.4.25. t_is_canceled() 
77
-        1.4.26. t_relay_cancel() 
78
-        1.4.27. t_drop_replies() 
79
-        1.4.28. t_save_lumps() 
77
+        1.4.26. t_is_expired() 
78
+        1.4.27. t_relay_cancel() 
79
+        1.4.28. t_lookup_cancel(), t_lookup_cancel(1) 
80
+        1.4.29. t_drop_replies() 
81
+        1.4.30. t_save_lumps() 
80 82
 
81 83
    1.5. TM Module API
82 84
 
... ...
@@ -1154,7 +1156,21 @@ failure_route[0]{
1154 1154
         }
1155 1155
 }
1156 1156
 
1157
-1.4.26.  t_relay_cancel()
1157
+1.4.26.  t_is_expired()
1158
+
1159
+   Returns true if the current transaction has already been expired, i.e.
1160
+   the max_inv_lifetime/max_noninv_lifetime interval has already elapsed.
1161
+
1162
+   Example 50. t_is_expired usage
1163
+...
1164
+failure_route[0]{
1165
+        if (t_is_expired()){
1166
+                log("transaction expired\n");
1167
+                # There is no point in adding a new branch.
1168
+        }
1169
+}
1170
+
1171
+1.4.27.  t_relay_cancel()
1158 1172
 
1159 1173
    Forwards the CANCEL if the corresponding INVITE transaction exists.
1160 1174
    The function is supposed to be used at the very beginning of the
... ...
@@ -1166,7 +1182,7 @@ failure_route[0]{
1166 1166
    CANCELs were successfully sent to the pending branches, true if the
1167 1167
    INVITE was not found, and false in case of any error.
1168 1168
 
1169
-   Example 50. t_relay_cancel usage
1169
+   Example 51. t_relay_cancel usage
1170 1170
 if (method == CANCEL) {
1171 1171
         if (!t_relay_cancel()) {  # implicit drop if relaying was successful,
1172 1172
                                   # nothing to do
... ...
@@ -1179,14 +1195,46 @@ if (method == CANCEL) {
1179 1179
         # do the same as for INVITEs
1180 1180
 }
1181 1181
 
1182
-1.4.27.  t_drop_replies()
1182
+1.4.28.  t_lookup_cancel(), t_lookup_cancel(1)
1183
+
1184
+   Returns true if the corresponding INVITE transaction exists for a
1185
+   CANCEL request. The function can be called at the beginning of the
1186
+   script to check whether or not the CANCEL can be immediately forwarded
1187
+   bypassing the rest of the script. Note however that t_relay_cancel
1188
+   includes t_lookup_cancel as well, therefore it is not needed to
1189
+   explicitly call this function unless something has to be logged for
1190
+   example.
1191
+
1192
+   If the function parameter (optional) is set to 1, the message flags
1193
+   are overwritten with the flags of the INVITE. isflagset() can be used
1194
+   to check the flags of the previously forwarded INVITE in this case.
1195
+
1196
+   Example 52. t_lookup_cancel usage
1197
+if (method == CANCEL) {
1198
+        if (t_lookup_cancel()) {
1199
+                log("INVITE transaction exists");
1200
+                if (!t_relay_cancel()) {  # implicit drop if
1201
+                                          # relaying was successful,
1202
+                                          # nothing to do
1203
+
1204
+                        # corresponding INVITE transaction found
1205
+                        # but error occurred
1206
+                        sl_reply("500", "Internal Server Error");
1207
+                        drop;
1208
+                }
1209
+        }
1210
+        # bad luck, corresponding INVITE transaction is missing,
1211
+        # do the same as for INVITEs
1212
+}
1213
+
1214
+1.4.29.  t_drop_replies()
1183 1215
 
1184 1216
    Drops all the previously received replies in failure_route block to
1185 1217
    make sure that none of them is picked up again. Works only if a new
1186 1218
    branch is added to the transaction, or it is explicitly replied in the
1187 1219
    script!
1188 1220
 
1189
-   Example 51. t_drop_replies() usage
1221
+   Example 53. t_drop_replies() usage
1190 1222
 ...
1191 1223
 failure_route[0]{
1192 1224
         if (t_check_status("5[0-9][0-9]")){
... ...
@@ -1202,7 +1250,7 @@ failure_route[0]{
1202 1202
         }
1203 1203
 }
1204 1204
 
1205
-1.4.28.  t_save_lumps()
1205
+1.4.30.  t_save_lumps()
1206 1206
 
1207 1207
    Forces the modifications of the processed SIP message to be saved in
1208 1208
    shared memory before t_relay() is called. The new branches which are
... ...
@@ -1217,7 +1265,7 @@ failure_route[0]{
1217 1217
    The transaction must be created by t_newtran() before calling
1218 1218
    t_save_lumps().
1219 1219
 
1220
-   Example 52. t_save_lumps() usage
1220
+   Example 54. t_save_lumps() usage
1221 1221
 route {
1222 1222
         ...
1223 1223
         t_newtran();
... ...
@@ -54,12 +54,6 @@
54 54
 #define NORMAL_ORDER 0  /* Create route set in normal order - UAS */
55 55
 #define REVERSE_ORDER 1 /* Create route set in reverse order - UAC */
56 56
 
57
-#define ROUTE_PREFIX "Route: "
58
-#define ROUTE_PREFIX_LEN (sizeof(ROUTE_PREFIX) - 1)
59
-
60
-#define ROUTE_SEPARATOR "," CRLF "       "
61
-#define ROUTE_SEPARATOR_LEN (sizeof(ROUTE_SEPARATOR) - 1)
62
-
63 57
 
64 58
 #ifdef DIALOG_CALLBACKS
65 59
 
... ...
@@ -221,11 +215,17 @@ static inline int str_duplicate(str* _d, str* _s)
221 221
 
222 222
 /*
223 223
  * Calculate dialog hooks
224
+ * @return:
225
+ *  negative : error
226
+ *  0 : no routes present
227
+ *  F_RB_NH_LOOSE : routes present, next hop is loose router
228
+ *  F_RB_NH_STRICT: next hop is strict.
224 229
  */
225 230
 static inline int calculate_hooks(dlg_t* _d)
226 231
 {
227 232
 	str* uri;
228 233
 	struct sip_uri puri;
234
+	int nhop;
229 235
 
230 236
 	/* we might re-calc. some existing hooks =>
231 237
 	 * reset all the hooks to 0 */
... ...
@@ -242,6 +242,7 @@ static inline int calculate_hooks(dlg_t* _d)
242 242
 			else _d->hooks.request_uri = &_d->rem_uri;
243 243
 			_d->hooks.next_hop = &_d->route_set->nameaddr.uri;
244 244
 			_d->hooks.first_route = _d->route_set;
245
+			nhop = F_RB_NH_LOOSE;
245 246
 		} else {
246 247
 			_d->hooks.request_uri = &_d->route_set->nameaddr.uri;
247 248
 			_d->hooks.next_hop = _d->hooks.request_uri;
... ...
@@ -250,6 +251,7 @@ static inline int calculate_hooks(dlg_t* _d)
250 250
 				_d->hooks.last_route = &_d->rem_target;
251 251
 			else 
252 252
 				_d->hooks.last_route = NULL; /* ? */
253
+			nhop = F_RB_NH_STRICT;
253 254
 		}
254 255
 	} else {
255 256
 		if (_d->rem_target.s) _d->hooks.request_uri = &_d->rem_target;
... ...
@@ -258,12 +260,14 @@ static inline int calculate_hooks(dlg_t* _d)
258 258
 		if (_d->dst_uri.s) _d->hooks.next_hop = &_d->dst_uri;
259 259
 		else _d->hooks.next_hop = _d->hooks.request_uri;
260 260
 
261
+		nhop = 0;
261 262
 		/*
262
-		 * the routes in the hooks need to be reset because if the route_set was dropped somewhere else
263
-		 * then these will remain set without the actual routes existing any more
263
+		 * the routes in the hooks need to be reset because if the route_set 
264
+		 * was dropped somewhere else then these will remain set without the
265
+		 * actual routes existing any more
264 266
 		 */
265 267
 		_d->hooks.first_route = 0;
266
-		_d->hooks.last_route = 0; 
268
+		_d->hooks.last_route = 0;
267 269
 	}
268 270
 
269 271
 	if ((_d->hooks.request_uri) && (_d->hooks.request_uri->s) && (_d->hooks.request_uri->len)) {
... ...
@@ -279,7 +283,7 @@ static inline int calculate_hooks(dlg_t* _d)
279 279
 		get_raw_uri(_d->hooks.next_hop);
280 280
 	}
281 281
 
282
-	return 0;
282
+	return nhop;
283 283
 }
284 284
 
285 285
 /*
... ...
@@ -744,7 +748,8 @@ static inline int dlg_confirmed_resp_uac(dlg_t* _d, struct sip_msg* _m,
744 744
 			if (str_duplicate(&_d->rem_target, &contact) < 0) return -4;
745 745
 		}
746 746
 
747
-		calculate_hooks(_d);
747
+		if (calculate_hooks(_d) < 0)
748
+			return -1;
748 749
 	}
749 750
 
750 751
 	return 0;
... ...
@@ -1084,7 +1089,8 @@ int dlg_request_uas(dlg_t* _d, struct sip_msg* _m, target_refresh_t is_target_re
1084 1084
 			if (str_duplicate(&_d->rem_target, &contact) < 0) return -6;
1085 1085
 		}
1086 1086
 
1087
-		calculate_hooks(_d);
1087
+		if (calculate_hooks(_d) < 0)
1088
+			return -1;
1088 1089
 		
1089 1090
 	}
1090 1091
 
... ...
@@ -1098,31 +1104,30 @@ int dlg_request_uas(dlg_t* _d, struct sip_msg* _m, target_refresh_t is_target_re
1098 1098
 int calculate_routeset_length(dlg_t* _d)
1099 1099
 {
1100 1100
 	int len;
1101
-	rr_t* ptr;
1101
+	rr_t *ptr;
1102 1102
 
1103
-	len = 0;
1104
-	ptr = _d->hooks.first_route;
1103
+	if (! _d->route_set)
1104
+		return 0;
1105 1105
 
1106
-	if (ptr) {
1107
-		len = ROUTE_PREFIX_LEN;
1108
-		len += CRLF_LEN;
1109
-	}
1106
+	len = ROUTE_PREFIX_LEN;
1110 1107
 
1111
-	while(ptr) {
1108
+	for (ptr = _d->hooks.first_route; ptr; ptr = ptr->next) {
1112 1109
 		len += ptr->len;
1113
-		ptr = ptr->next;
1114
-		if (ptr) len += ROUTE_SEPARATOR_LEN;
1115
-	} 
1116
-
1110
+		len += ROUTE_SEPARATOR_LEN;
1111
+	}
1117 1112
 	if (_d->hooks.last_route) {
1118
-		len += ROUTE_SEPARATOR_LEN + 2; /* < > */
1119
-		len += _d->hooks.last_route->len;
1113
+		if (_d->hooks.first_route)
1114
+			len += ROUTE_SEPARATOR_LEN;
1115
+		len += _d->hooks.last_route->len + 2; /* < > */
1116
+	} else {
1117
+		len -= ROUTE_SEPARATOR_LEN;
1120 1118
 	}
1121 1119
 
1120
+	len += CRLF_LEN;
1121
+
1122 1122
 	return len;
1123 1123
 }
1124 1124
 
1125
-
1126 1125
 /*
1127 1126
  *
1128 1127
  * Print the route set
... ...
@@ -1255,7 +1260,7 @@ int set_dlg_target(dlg_t* _d, str* _ruri, str* _duri) {
1255 1255
 		if (str_duplicate(&_d->dst_uri, _duri)) return -1;
1256 1256
 	}
1257 1257
 
1258
-	if (calculate_hooks(_d)) {
1258
+	if (calculate_hooks(_d) < 0) {
1259 1259
 		LOG(L_ERR, "set_dlg_target(): Error while calculating hooks\n");
1260 1260
 		return -1;
1261 1261
 	}
... ...
@@ -841,6 +841,29 @@ failure_route[0]{
841 841
 	</example>
842 842
 	</section>
843 843
 
844
+	<section id="t_is_expired">
845
+	<title>
846
+	    <function>t_is_expired()</function>
847
+	</title>
848
+	<para>
849
+		Returns true if the current transaction has already been expired,
850
+		i.e. the max_inv_lifetime/max_noninv_lifetime interval has already
851
+		elapsed.
852
+	</para>
853
+	<example>
854
+	    <title><function>t_is_expired</function> usage</title>
855
+	    <programlisting>
856
+...
857
+failure_route[0]{ 
858
+	if (t_is_expired()){
859
+		log("transaction expired\n");
860
+		# There is no point in adding a new branch.
861
+	}
862
+} 
863
+	    </programlisting>
864
+	</example>
865
+	</section>
866
+
844 867
     <section id="t_relay_cancel">
845 868
 	<title>
846 869
 	    <function>t_relay_cancel()</function>
... ...
@@ -877,6 +900,50 @@ if (method == CANCEL) {
877 877
 	</example>
878 878
     </section>
879 879
 
880
+    <section id="t_lookup_cancel">
881
+	<title>
882
+	    <function>t_lookup_cancel()</function>,
883
+	    <function>t_lookup_cancel(1)</function>
884
+	</title>
885
+	<para>
886
+		Returns true if the corresponding INVITE transaction exists
887
+		for a CANCEL request. The function can be called at the beginning
888
+		of the script to check whether or not the CANCEL can be immediately
889
+		forwarded bypassing the rest of the script. Note however that
890
+		<function>t_relay_cancel</function> includes
891
+		<function>t_lookup_cancel</function> as well, therefore it is not
892
+		needed to explicitly call this function unless something has to be
893
+		logged for example.
894
+	</para>
895
+	<para>
896
+		If the function parameter (optional) is set to 1, the message flags
897
+		are overwritten with the flags of the INVITE. isflagset() can be used
898
+		to check the flags of the previously forwarded INVITE in this case.
899
+	</para>
900
+	<example>
901
+	    <title><function>t_lookup_cancel</function> usage</title>
902
+	    <programlisting>
903
+
904
+if (method == CANCEL) {
905
+	if (t_lookup_cancel()) {
906
+		log("INVITE transaction exists");
907
+		if (!t_relay_cancel()) {  # implicit drop if
908
+                                          # relaying was successful,
909
+                                          # nothing to do
910
+
911
+			# corresponding INVITE transaction found
912
+			# but error occurred
913
+			sl_reply("500", "Internal Server Error");
914
+			drop;
915
+		}
916
+	}
917
+	# bad luck, corresponding INVITE transaction is missing,
918
+	# do the same as for INVITEs
919
+}
920
+	    </programlisting>
921
+	</example>
</