Browse code

TM callbacks, acc, flags

Jiri Kuthan authored on 13/05/2002 01:15:40
Showing 44 changed files
... ...
@@ -8,7 +8,7 @@
8 8
 VERSION = 0
9 9
 PATCHLEVEL = 8
10 10
 SUBLEVEL = 7
11
-EXTRAVERSION = -9
11
+EXTRAVERSION = -7-ipaq-viadbg
12 12
 
13 13
 RELEASE=$(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION)
14 14
 OS = $(shell uname -s)
... ...
@@ -81,15 +81,15 @@ ARCH = $(shell uname -m |sed -e s/i.86/i386/ -e s/sun4u/sparc64/ )
81 81
 DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
82 82
 	 -DOS='"$(OS)"' -DCOMPILER='"$(CC_VER)"'\
83 83
 	 -DDNS_IP_HACK  -DPKG_MALLOC \
84
-	 -DF_MALLOC -DUSE_SYNONIM\
84
+	 -DF_MALLOC \
85 85
 	 -DSHM_MEM  -DSHM_MMAP \
86 86
 	 -DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=1024 \
87 87
 	 -DWAIT -DNEW_HNAME \
88
+	 -DVERY_NOISY_REPLIES\
88 89
 	 #-DSILENT_FR \
89
-	 #-DUSE_SYNONIM\
90 90
 	 #-DNO_DEBUG \
91
+ 	 #-DUSE_SYNONIM\
91 92
 	 #-DNOISY_REPLIES \
92
-	 #-DBOGDAN_TRIFLE \
93 93
 	 #-DADAPTIVE_WAIT -DADAPTIVE_WAIT_LOOPS=0 \
94 94
 	 #-DNOSMP \
95 95
 	 #-DEXTRA_DEBUG 
... ...
@@ -102,8 +102,8 @@ DEFS+= -DNAME='"$(NAME)"' -DVERSION='"$(RELEASE)"' -DARCH='"$(ARCH)"' \
102 102
 
103 103
 
104 104
 #PROFILE=  -pg #set this if you want profiling
105
-#mode = debug
106
-mode = release
105
+mode = debug
106
+#mode = release
107 107
 
108 108
 # platform dependent settings
109 109
 
... ...
@@ -374,7 +374,7 @@ ifeq  ($(OS), SunOS)
374 374
 ifeq ($(CC_NAME), suncc)
375 375
 	LIBS=-lfast
376 376
 endif
377
-	LIBS+=-ldl -L/usr/local/lib -lfl -lxnet -lrt
377
+	LIBS+=-ldl -L/usr/local/lib -L/usr/lib/mysql -lfl -lxnet -lrt
378 378
 	# -lrt needed for sched_yield
379 379
 endif
380 380
 
... ...
@@ -11,7 +11,7 @@
11 11
 # defines: sources, objs, depends
12 12
 #
13 13
 
14
-sources=$(filter-out $(auto_gen), $(wildcard *.c) $(wildcard mem/*.c) ) $(auto_gen)
14
+sources=$(filter-out $(auto_gen), $(wildcard *.c) $(wildcard mem/*.c) $(wildcard parser/*.c) ) $(auto_gen)
15 15
 objs=$(sources:.c=.o)
16 16
 extra_objs=
17 17
 depends=$(sources:.c=.d)
... ...
@@ -12,7 +12,7 @@
12 12
 #include "forward.h"
13 13
 #include "udp_server.h"
14 14
 #include "route.h"
15
-#include "msg_parser.h"
15
+#include "parser/msg_parser.h"
16 16
 #include "ut.h"
17 17
 #include "sr_module.h"
18 18
 #include "mem/mem.h"
... ...
@@ -167,6 +167,54 @@ int do_action(struct action* a, struct sip_msg* msg)
167 167
 			LOG(a->p1.number, a->p2.string);
168 168
 			ret=1;
169 169
 			break;
170
+
171
+		/* jku - begin : flag processing */
172
+
173
+		case SETFLAG_T:
174
+			if (a->p1_type!=NUMBER_ST) {
175
+				LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
176
+					a->p1_type );
177
+				ret=E_BUG;
178
+				break;
179
+			}
180
+			if (!flag_in_range( a->p1.number )) {
181
+				ret=E_CFG;
182
+				break;
183
+			}
184
+			setflag( msg, a->p1.number );
185
+			ret=1;
186
+			break;
187
+
188
+		case RESETFLAG_T:
189
+			if (a->p1_type!=NUMBER_ST) {
190
+				LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
191
+					a->p1_type );
192
+				ret=E_BUG;
193
+				break;
194
+			}
195
+			if (!flag_in_range( a->p1.number )) {
196
+				ret=E_CFG;
197
+				break;
198
+			}
199
+			resetflag( msg, a->p1.number );
200
+			ret=1;
201
+			break;
202
+			
203
+		case ISFLAGSET_T:
204
+			if (a->p1_type!=NUMBER_ST) {
205
+				LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
206
+					a->p1_type );
207
+				ret=E_BUG;
208
+				break;
209
+			}
210
+			if (!flag_in_range( a->p1.number )) {
211
+				ret=E_CFG;
212
+				break;
213
+			}
214
+			ret=isflagset( msg, a->p1.number );
215
+			break;
216
+		/* jku - end : flag processing */
217
+
170 218
 		case ERROR_T:
171 219
 			if ((a->p1_type!=STRING_ST)|(a->p2_type!=STRING_ST)){
172 220
 				LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
... ...
@@ -6,7 +6,7 @@
6 6
 #ifndef action_h
7 7
 #define action_h
8 8
 
9
-#include "msg_parser.h"
9
+#include "parser/msg_parser.h"
10 10
 #include "route_struct.h"
11 11
 
12 12
 int do_action(struct action* a, struct sip_msg* msg);
... ...
@@ -46,6 +46,9 @@ LOG		log
46 46
 ERROR	error
47 47
 ROUTE	route
48 48
 EXEC	exec
49
+SETFLAG		setflag
50
+RESETFLAG	resetflag
51
+ISFLAGSET	isflagset
49 52
 SET_HOST		"rewritehost"|"sethost"|"seth"
50 53
 SET_HOSTPORT	"rewritehostport"|"sethostport"|"sethp"
51 54
 SET_USER		"rewriteuser"|"setuser"|"setu"
... ...
@@ -131,6 +134,9 @@ EAT_ABLE	[\ \t\b\r]
131 131
 <INITIAL>{SEND}	{ count(); yylval.strval=yytext; return SEND; }
132 132
 <INITIAL>{LOG}	{ count(); yylval.strval=yytext; return LOG_TOK; }
133 133
 <INITIAL>{ERROR}	{ count(); yylval.strval=yytext; return ERROR; }
134
+<INITIAL>{SETFLAG}	{ count(); yylval.strval=yytext; return SETFLAG; }
135
+<INITIAL>{RESETFLAG}	{ count(); yylval.strval=yytext; return RESETFLAG; }
136
+<INITIAL>{ISFLAGSET}	{ count(); yylval.strval=yytext; return ISFLAGSET; }
134 137
 <INITIAL>{ROUTE}	{ count(); yylval.strval=yytext; return ROUTE; }
135 138
 <INITIAL>{EXEC}	{ count(); yylval.strval=yytext; return EXEC; }
136 139
 <INITIAL>{SET_HOST}	{ count(); yylval.strval=yytext; return SET_HOST; }
... ...
@@ -62,7 +62,9 @@ void* f_tmp;
62 62
 %token ELSE
63 63
 %token URIHOST
64 64
 %token URIPORT
65
-
65
+%token SETFLAG
66
+%token RESETFLAG
67
+%token ISFLAGSET
66 68
 %token METHOD
67 69
 %token URI
68 70
 %token SRCIP
... ...
@@ -557,13 +559,21 @@ cmd:		FORWARD LPAREN host RPAREN	{ $$=mk_action(	FORWARD_T,
557 557
 		| LOG_TOK error { $$=0; yyerror("missing '(' or ')' ?"); }
558 558
 		| LOG_TOK LPAREN error RPAREN { $$=0; yyerror("bad log"
559 559
 									"argument"); }
560
+		| SETFLAG LPAREN NUMBER RPAREN {$$=mk_action( SETFLAG_T, NUMBER_ST, 0,
561
+													(void *)$3, 0 ); }
562
+		| SETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
563
+		| RESETFLAG LPAREN NUMBER RPAREN {$$=mk_action(	RESETFLAG_T, NUMBER_ST, 0,
564
+													(void *)$3, 0 ); }
565
+		| RESETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
566
+		| ISFLAGSET LPAREN NUMBER RPAREN {$$=mk_action(	ISFLAGSET_T, NUMBER_ST, 0,
567
+													(void *)$3, 0 ); }
568
+		| ISFLAGSET error { $$=0; yyerror("missing '(' or ')'?"); }
560 569
 		| ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T,
561 570
 																STRING_ST, 
562 571
 																STRING_ST,
563 572
 																$3,
564 573
 																$5);
565 574
 												  }
566
-												
567 575
 		| ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
568 576
 		| ERROR LPAREN error RPAREN { $$=0; yyerror("bad error"
569 577
 														"argument"); }
... ...
@@ -6,7 +6,7 @@
6 6
 #ifndef data_lump_rpl_h
7 7
 #define data_lump_rpl_h
8 8
 
9
-#include "msg_parser.h"
9
+#include "parser/msg_parser.h"
10 10
 
11 11
 
12 12
 struct lump_rpl
... ...
@@ -1,17 +1,21 @@
1 1
 #
2
-# iptel.org real world configuration
3
-#
4 2
 # $Id$
5 3
 #
4
+# iptel.org real world configuration
5
+#
6
+
7
+# ----------- global configuration parameters ------------------------
6 8
 
7 9
 debug=3          # debug level (cmd line: -dddddddddd)
8
-fork=yes
9
-log_stderror=no	# (cmd line: -E)
10
-#log_stderror=yes	# (cmd line: -E)
10
+#fork=yes
11
+fork=no
12
+#log_stderror=no	# (cmd line: -E)
13
+log_stderror=yes	# (cmd line: -E)
11 14
 check_via=yes     # (cmd. line: -v)
12 15
 dns=on           # (cmd. line: -r)
13 16
 rev_dns=yes      # (cmd. line: -R)
14
-port=5060
17
+#port=5060
18
+port=8060
15 19
 children=1
16 20
 
17 21
 # advertise IP address in Via (as opposed to advertising DNS name
... ...
@@ -19,9 +23,12 @@ children=1
19 19
 # not handle DNS at all)
20 20
 listen=195.37.77.101
21 21
 
22
+# ------------------ module loading ----------------------------------
23
+
22 24
 loadmodule "../sip_router/modules/sl/sl.so"
23 25
 loadmodule "../sip_router/modules/print/print.so"
24 26
 loadmodule "../sip_router/modules/tm/tm.so"
27
+loadmodule "../sip_router/modules/acc/acc.so"
25 28
 loadmodule "../sip_router/modules/rr/rr.so"
26 29
 loadmodule "../sip_router/modules/maxfwd/maxfwd.so"
27 30
 loadmodule "../sip_router/modules/mysql/mysql.so"
... ...
@@ -29,6 +36,10 @@ loadmodule "../sip_router/modules/usrloc/usrloc.so"
29 29
 loadmodule "../sip_router/modules/auth/auth.so"
30 30
 loadmodule "../sip_router/modules/cpl/cpl.so"
31 31
 
32
+# ----------------- setting module-specific parameters ---------------
33
+
34
+# -- usrloc params --
35
+
32 36
 modparam("usrloc", "use_database",   1)
33 37
 modparam("usrloc", "table",          "location")
34 38
 modparam("usrloc", "user_column",    "user")
... ...
@@ -40,16 +51,51 @@ modparam("usrloc", "cseq_column",    "cseq")
40 40
 modparam("usrloc", "flush_interval", 60)
41 41
 modparam("usrloc", "db_url",         "sql://csps:47csps11@dbhost/csps107")
42 42
 
43
+# -- auth params --
44
+
43 45
 modparam("auth", "db_url",        "sql://csps:47csps11@dbhost/csps107")
44 46
 modparam("auth", "user_column",   "user_id")
47
+# nonce generation secret; particularly useful if multiple servers
48
+# in a proxy farm are configured to authenticate
45 49
 modparam("auth", "secret",        "439tg8h349g8hq349t9384hg")
50
+# calculate_ha1=false means password column includes ha1 strings;
51
+# if it was false, plain-text passwords would be assumed
46 52
 modparam("auth", "calculate_ha1", false)
47 53
 modparam("auth", "nonce_expire",  300)
48 54
 modparam("auth", "retry_count",   5)
55
+# password_column, realm_column, group_table, group_user_column,
56
+#   group_group_column are set to their default values
57
+# password_column_2 allows to deal with clients who put domain name
58
+#   in authentication credentials when calculate_ha1=false (if true,
59
+#   it works); if set to a value and USER_DOMAIN_HACK was enabled
60
+#   in defs.h, authentication will still work
49 61
 
62
+# -- acc params --
63
+# report ACKs too for sake of completeness -- as we account PSTN
64
+# destinations which are RR, ACKs should show up
65
+modparam("acc", "report_ack", 1)
66
+# don't bother me with early media reports (I don't like 183 
67
+# too much anyway...ever thought of timer C hitting after
68
+# listening to music-on-hold for five minutes?)
69
+modparam("acc", "early_media", 0)
70
+modparam("acc", "log_level", 1)
71
+# that is the flag for which we will account -- don't forget to
72
+# set the same one :-)
73
+modparam("acc", "acc_flag", 1 )
74
+# we are interested only in succesful transactions
75
+modparam("acc", "failed_transactions", 0 )
76
+
77
+# -- tm params --
78
+modparam("tm", "fr_timer", 10 )
79
+modparam("tm", "fr_inv_timer", 30 )
80
+
81
+# -------------------------  request routing logic -------------------
82
+
83
+# main routing logic
50 84
 
51 85
 route{
52
-	# filter local stateless ACK generated by authentication and other replies
86
+
87
+	# filter local stateless ACK generated by authentication of mf replies
53 88
 	sl_filter_ACK();
54 89
 
55 90
 	# filter too old messages
... ...
@@ -71,163 +117,215 @@ route{
71 71
 		break;
72 72
 	};
73 73
 
74
+	# if this request is not for our domain, fall over to
75
+	# outbound request processing; include gateway's address
76
+	# in matching too -- we RR requests to it, so that
77
+	# its address may show up in subsequent requests
78
+	# after rewriteFromRoute
79
+	
80
+	if (!(uri=~"[@:]iptel\.org([;:].*)*" 
81
+		| uri=~"[@:]195\.37\.77\.101([;:].*)*" |
82
+		uri=~"@195\.37\.77\.110([;:].*)*" )) {
83
+		route(2);
84
+	};
85
+	# here we continue with requests for our domain...
86
+
74 87
 	# various aliases (might use a database in future)
75
-	if (uri=~"sip:9040@.*") {
76
-		setuser("jiri");
88
+	if (uri=~"sip:9040@") {
89
+		seturi("jiri@iptel.org");
77 90
 	};
78
-	# special measure for our US friends
79 91
 	if (uri=~"sip:17@") {
80 92
 		seturi("sip:henry@siptest.wcom.com");
81 93
 	};
94
+	# check again, if it is still for our domain after aliases
95
+	if ( !(uri=~"[@:]iptel\.org([;:].*)*" | 
96
+		uri=~"[@:]195\.37\.77\.101([;:].*)*" |
97
+		uri=~"@195\.37\.77\.110([;:].*)*" )) {
98
+		route(2);
99
+	};
100
+	log("Request is for iptel.org\n");	
82 101
 
83
-	# process requests for iptel.org (note the wildcard in
84
-	# the regex end -- that captures URIs which have port
85
-	# numbers or parameters in them); also include gateway
86
-	# here too -- we RR to the gateway which means that its
87
-	# address shows up in d-uri of subsequent requests after
88
-	# having called rewriteFromRoute and we want the requests
89
-	# to go through our PSTN authorization code 
90
-	if (uri=~"[@:]iptel\.org([;:].*)*" | uri=~"[@:]195\.37\.77\.101([;:].*)*" |
91
-		uri=~"@195\.37\.77\.110([;:].*)*" ) {
92
-		log("Request is for iptel.org\n");	
93
-
94
-		# registers always MUST be authenticated to
95
-		# avoid stealing incoming calls	
96
-		if (method=="REGISTER") {
97
-			log("Request is REGISTER\n");
98
-			if (!www_authorize("iptel.org", "subscriber")) {
99
-				log("REGISTER has no credentials, sending challenge\n");
100
-				www_challenge("iptel.org", "0");
101
-				break;
102
-			};
103
-			# prohibit attempts to grab someone else's address 
104
-			# using someone else's valid credentials
105
-			if (!check_to()) {
106
-				log("Cheating attempt\n");
107
-				sl_send_reply("403", "What a nasty guy you are");
108
-				break;
109
-			};
110
-				
111
-			# update Contact database
112
-        	log("REGISTER is authorized, saving location\n");
113
-			save_contact("location");
102
+	# registers always MUST be authenticated to
103
+	# avoid stealing incoming calls	
104
+	if (method=="REGISTER") {
105
+		log("Request is REGISTER\n");
106
+		if (!www_authorize(	"iptel.org" /* realm */, 
107
+			 				"subscriber" /* table name */ )) {
108
+			log("REGISTER has no credentials, sending challenge\n");
109
+			www_challenge(	"iptel.org" /* realm */, 
110
+							"0" /* no qop -- M$ can't deal with it */);
111
+			break;
112
+		};
113
+		# prohibit attempts to grab someone else's To address 
114
+		# using  valid credentials
115
+		if (!check_to()) {
116
+			log("To Cheating attempt\n");
117
+			sl_send_reply("403", "That is ugly -- use To=id next time");
114 118
 			break;
115 119
 		};
120
+			
121
+		# update Contact database
122
+       	log("REGISTER is authorized, saving location\n");
123
+		save_contact("location");
124
+		break;
125
+	};
116 126
 
127
+	# now check if it's about PSTN destinations through our gateway;
128
+	# note that 8.... is exempted for numerical destinations
129
+	if (uri=~"sip:[0-79][0-9]*@.*") {
130
+		route(3);
131
+	}; 
117 132
 
118
-		# now it's about PSTN destinations through our gateway;
119
-		# note that 8.... is exempted for numerical destinations
120
-		if (uri=~"sip:[0-79][0-9]*@.*") {
121
-			# free call destinations ... no authentication needed
122
-			if (uri=~"sip:001795061546@.*" | uri=~"sip:0016097265544.*" | uri=~"sip:[79][0-9][0-9][0-9]@.*") {
123
-				log("Free PSTN\n");
124
-			} else {
125
-				# all other PSTN destinations only for authenticated users
126
-				# (Cisco GW, which has no digest support, is authenticated
127
-				# by its IP address -- that's for sure not very strong;
128
-				# wth confirmed that we filter packets coming from outside
129
-				# and bearing SRC IP address of a Fokus network)
130
-				if (!(src_ip==195.37.77.110) & !(proxy_authorize("iptel.org", "subscriber"))) {
131
-					proxy_challenge("iptel.org", "0");
132
-					break;
133
-				};
134
-			
135
-				# authorize only for INVITEs -- RR/Contact may result in weird
136
-				# things showing up in d-uri that would break our logic; our
137
-				# major concern is INVITE which causes PSTN costs anyway
133
+	# ---------- demo - begin --------------
134
+	/* added by Bogdan for cpl demo - Dorgham request*/
135
+	if (uri=~"sip:test@.*" && method=="INVITE")
136
+	{
137
+		log("SER : runing CPL!! :)\n");
138
+		if ( !cpl_run_script() )
139
+		{
140
+   			log("SER : Error during running CPL script!\n");
141
+		}else{
142
+   			if ( cpl_is_response_reject() ) {
143
+				log("SER: reject");
144
+       			sl_send_reply("603","I am not available!");
145
+       			break;
146
+   			}else if ( cpl_is_response_redirect() ) {
147
+       			log("SER : redirect\n");
148
+       			cpl_update_contact();
149
+       			sl_send_reply("302","Moved temporarily");
150
+       			break;
151
+   			};
152
+		};
153
+	};
154
+	# -------------- demo - end -------------
138 155
 
139
-				if (method=="INVITE") {
140
-	
141
-					# does the authenticated user have a permission for local
142
-					# calls? (i.e., is he in the "local" group?)
143
-					if (uri=~"sip:0[1-9][0-9]+@.*") {
144
-						if (!is_in_group("local")) {
145
-							sl_send_reply("403", "Local Toodle Noodle...");
146
-							break;
147
-						};
148
-					# the same for long-distance
149
-					} else if (uri=~"sip:00[1-9][0-9]+@.*") {
150
-						if (uri=~"sip:001[089]" | uri=~"sip:00900.*" ) {
151
-								sl_send_reply("403", "Added Value Destinations not permitted...");
152
-							break;
153
-						};
154
-						if (!is_in_group("ld")) {
155
-							sl_send_reply("403", "LD Toodle Noodle...");
156
-							break;
157
-						};
158
-					# the same for international calls
159
-					} else if (uri=~"sip:000[1-9][0-9]+@.*") {
160
-						if (!is_in_group("int")) {
161
-							sl_send_reply("403", "International Toodle Noodle...");
162
-							break;
163
-						};
164
-					# everything else (e.g., interplanetary calls) is denied
165
-					} else {
166
-						sl_send_reply("403", "interplanetary Toodle Noodle...");
167
-						break;
168
-					};
156
+	# native SIP destinations are handled using our USRLOC DB
157
+	if (!lookup_contact("location")) {
158
+		log("Unable to lookup contact, sending 404\n");
159
+		sl_send_reply("404", "Not Found");
160
+		break;
161
+	};
162
+	# check whether some inventive user has uploaded  gateway 
163
+	# contacts to UsrLoc to bypass our authorization logic
164
+	if (uri=~"@195\.37\.77\.110([;:].*)*" ) {
165
+		log("Weird! Gateway address in UsrLoc!\n");
166
+		route(3);
167
+	};
169 168
 
170
-				};
171
-			};
169
+	# requests from gateway should be RR-ed too
170
+	if (src_ip==195.37.77.110 && method=="INVITE")  {
171
+		addRecordRoute();
172
+	};
172 173
 
173
-			# requests to gateway must be record-route because the GW accepts
174
-			# only reqeusts coming from our proxy
175
-			if (method=="INVITE") addRecordRoute();
176
-			# if you have passed through all the checks, let your call go to GW!
177
-			rewritehostport("195.37.77.110:5060");
178
-		} else {
179
-
180
-			# non-nummerical destnations now
181
-
182
-			# demo stuff *******************************************
183
-			/* added by Bogdan for cpl demo - Dorgham request*/
184
-			if (uri=~"sip:test@.*" && method=="INVITE")
185
-			{
186
-       			log("SER : runing CPL!! :)\n");
187
-       			if ( !cpl_run_script() )
188
-       			{
189
-           			log("SER : Error during running CPL script!\n");
190
-       			}else{
191
-           			if ( cpl_is_response_reject() ) {
192
-						log("SER: reject");
193
-               			sl_send_reply("603","I am not available!");
194
-               			break;
195
-           			}else if ( cpl_is_response_redirect() ) {
196
-               			log("SER : redirect\n");
197
-               			cpl_update_contact();
198
-               			sl_send_reply("302","Moved temporarily");
199
-               			break;
200
-           			};
201
-       			};
202
-			};
203
-			# End of demo stuff *******************************************
174
+	# we now know we may, we know where, let it go out now!
175
+	t_relay();
176
+}
204 177
 
205
-			# native SIP destinations are handled using our USRLOC DB
206
-			if (!lookup_contact("location")) {
207
-				log("Unable to lookup contact, sending 404\n");
208
-				sl_send_reply("404", "Not Found");
209
-				break;
210
-			};
211
-			# requests from gateway should be RR-ed too
212
-			# (numerical destinations are all RR-ed above)
213
-			if (src_ip==195.37.77.110 && method=="INVITE")  {
214
-				addRecordRoute();
215
-			};
178
+# routing logic for outbound requests targeted out of our domain
179
+route[2] {
180
+		# outbound requests are allowed only for our users -- we don't
181
+		# support relaying and don't like strangers bothering us
182
+		# with resolving DNS
183
+		log("that's a request to outside");
184
+		if (!(src_ip==195.37.77.110) & 
185
+			!(proxy_authorize(	"iptel.org" /* realm */,
186
+							"subscriber" /* table name */ ))) {
187
+			# see comments bellow on these ACK/CANCEL exceptions
188
+			if (method=="ACK" ) {
189
+				log("failed outbound authentication for ACK granted");
190
+			} else if (method=="CANCEL") {
191
+				log("failed outbound authentication for ACK granted");
192
+			} else proxy_challenge("iptel.org" /* realm */, "0" /* no-qop */);
193
+			break;
216 194
 		};
217
-       } else {
218
-			# outbound requests are allowed only for our users -- we don't
219
-			# support relaying and don't like strangers bothering us
220
-			# with resolving DNS
221
-			log("that's a request to outside");
222
-			if (!(src_ip==195.37.77.110) & !(proxy_authorize("iptel.org", "subscriber"))) {
223
-				proxy_challenge("iptel.org", "0");
224
-				break;
225
-			};
226
-			# there should be check_from here too -- but I'm to tired
227
-			# to test it tonight
195
+		# to maintain credibility of our proxy, we check From to be
196
+		# equal of credential id -- all outbound request leaving our
197
+		# proxy are guaranteed to be generated by persons in "From"
198
+		if (!check_from()) {
199
+			log("From Cheating attempt\n");
200
+			sl_send_reply("403", "That is ugly -- use From=id next time");
201
+			break;
228 202
 		};
229 203
 
230
-		# we now know we may, we now where, let it go out now!
231 204
 		t_relay();
232 205
 }
233 206
 
207
+# logic for calls through our PSTN gateway
208
+route[3] {
209
+	# free call destinations ... no authentication needed
210
+	if (uri=~"sip:001795061546@.*" | uri=~"sip:0016097265544.*" 
211
+		| uri=~"sip:[79][0-9][0-9][0-9]@.*") {
212
+		log("Free PSTN\n");
213
+	} else {
214
+		# all other PSTN destinations only for authenticated users
215
+		# (Cisco GW, which has no digest support, is authenticated
216
+		# by its IP address -- that's for sure not very strong;
217
+		# wth confirmed that we filter packets coming from outside
218
+		# and bearing SRC IP address of our network)
219
+		if (!(src_ip==195.37.77.110) & 
220
+			!(proxy_authorize(	"iptel.org" /* realm */,
221
+								"subscriber" /* table name */)))  {
222
+			# we are forgiving and ignore improper credentials
223
+			# for ACK/CANCEL as bis-09 is somewhat cryptic about
224
+			# its use and many UACs have not gotten it right
225
+			if (method=="ACK" ) {
226
+				log("failed gw authentication for ACK granted");
227
+			} else if (method=="CANCEL") {
228
+				log("failed gw authentication for ACK granted");
229
+			} else proxy_challenge(	"iptel.org" /* realm */, 
230
+									"0" /* no qop */ );
231
+			break;
232
+		};
233
+		
234
+		# authorize only for INVITEs -- RR/Contact may result in weird
235
+		# things showing up in d-uri that would break our logic; our
236
+		# major concern is INVITE which causes PSTN costs anyway
237
+
238
+		if (method=="INVITE") {
239
+
240
+			# does the authenticated user have a permission for local
241
+			# calls? (i.e., is he in the "local" group?)
242
+			if (uri=~"sip:0[1-9][0-9]+@.*") {
243
+				if (!is_in_group("local")) {
244
+					sl_send_reply("403", "Local Toodle Noodle...");
245
+					break;
246
+				};
247
+			# the same for long-distance
248
+			} else if (uri=~"sip:00[1-9][0-9]+@.*") {
249
+				if (uri=~"sip:001[089]" | uri=~"sip:00900.*" ) {
250
+					sl_send_reply("403", "Added Value Destinations not permitted...");
251
+					break;
252
+				};
253
+				if (!is_in_group("ld")) {
254
+					sl_send_reply("403", "LD Toodle Noodle...");
255
+					break;
256
+				};
257
+			# the same for international calls
258
+			} else if (uri=~"sip:000[1-9][0-9]+@.*") {
259
+				if (!is_in_group("int")) {
260
+					sl_send_reply("403", "International Toodle Noodle...");
261
+					break;
262
+				};
263
+			# everything else (e.g., interplanetary calls) is denied
264
+			} else {
265
+				sl_send_reply("403", "interplanetary Toodle Noodle...");
266
+				break;
267
+			};
268
+
269
+		}; # INVITE to authorized PSTN
270
+
271
+	}; # authorized PSTN
272
+
273
+	# requests to gateway must be record-route because the GW accepts
274
+	# only reqeusts coming from our proxy
275
+	if (method=="INVITE")
276
+		addRecordRoute();
277
+
278
+	# if you have passed through all the checks, let your call go to GW!
279
+	rewritehostport("195.37.77.110:5060");
280
+
281
+	# tag this transaction for accounting
282
+	setflag(1);
283
+
284
+	t_relay();
285
+}
234 286
new file mode 100644
... ...
@@ -0,0 +1,112 @@
0
+/*
1
+ * $Id$
2
+ */
3
+
4
+#include <limits.h>
5
+#include "sr_module.h"
6
+#include "dprint.h"
7
+#include "parser/msg_parser.h"
8
+#include "flags.h"
9
+#include "error.h"
10
+#include "stdlib.h"
11
+
12
+int setflag( struct sip_msg* msg, flag_t flag ) {
13
+	msg->flags |= 1 << flag;
14
+	return 1;
15
+}
16
+
17
+int resetflag( struct sip_msg* msg, flag_t flag ) {
18
+	msg->flags &= ~ flag;
19
+	return 1;
20
+}
21
+
22
+int isflagset( struct sip_msg* msg, flag_t flag ) {
23
+	return msg->flags & (1<<flag) ? 1 : -1;
24
+}
25
+
26
+int flag_in_range( flag_t flag ) {
27
+	if (flag > MAX_FLAG ) {
28
+		LOG(L_ERR, "ERROR: message flag %d too high; MAX=%d\n",
29
+			flag, MAX_FLAG );
30
+		return 0;
31
+	}
32
+	if (flag<=0) {
33
+		LOG(L_ERR, "ERROR: message flag (%d) must be in range %d..%d\n",
34
+			flag, 1, MAX_FLAG );
35
+		return 0;
36
+	}
37
+	return 1;
38
+}
39
+
40
+
41
+#ifdef _GET_AWAY
42
+
43
+/* wrapping functions for flag processing  */
44
+static int fixup_t_flag(void** param, int param_no)
45
+{
46
+    unsigned int *code;
47
+	char *c;
48
+	int token;
49
+
50
+	DBG("DEBUG: fixing flag: %s\n", (char *) (*param));
51
+
52
+	if (param_no!=1) {
53
+		LOG(L_ERR, "ERROR: TM module: only parameter #1 for flags can be fixed\n");
54
+		return E_BUG;
55
+	};
56
+
57
+	if ( !(code = malloc( sizeof( unsigned int) )) ) return E_OUT_OF_MEM;
58
+
59
+	*code = 0;
60
+	c = *param;
61
+	while ( *c && (*c==' ' || *c=='\t')) c++; /* intial whitespaces */
62
+
63
+	token=1;
64
+	if (strcasecmp(c, "white")==0) *code=FL_WHITE;
65
+	else if (strcasecmp(c, "yellow")==0) *code=FL_YELLOW;
66
+	else if (strcasecmp(c, "green")==0) *code=FL_GREEN;
67
+	else if (strcasecmp(c, "red")==0) *code=FL_RED;
68
+	else if (strcasecmp(c, "blue")==0) *code=FL_BLUE;
69
+	else if (strcasecmp(c, "magenta")==0) *code=FL_MAGENTA;
70
+	else if (strcasecmp(c, "brown")==0) *code=FL_BROWN;
71
+	else if (strcasecmp(c, "black")==0) *code=FL_BLACK;
72
+	else if (strcasecmp(c, "acc")==0) *code=FL_ACC;
73
+	else {
74
+		token=0;
75
+		while ( *c && *c>='0' && *c<='9' ) {
76
+			*code = *code*10+ *c-'0';
77
+			if (*code > (sizeof( flag_t ) * CHAR_BIT - 1 )) {
78
+				LOG(L_ERR, "ERROR: TM module: too big flag number: %s; MAX=%d\n",
79
+					(char *) (*param), sizeof( flag_t ) * CHAR_BIT - 1 );
80
+				goto error;
81
+			}
82
+			c++;
83
+		}
84
+	}
85
+	while ( *c && (*c==' ' || *c=='\t')) c++; /* terminating whitespaces */
86
+
87
+	if ( *code == 0 ) {
88
+		LOG(L_ERR, "ERROR: TM module: bad flag number: %s\n", (char *) (*param));
89
+		goto error;
90
+	}
91
+
92
+	if (*code < FL_MAX && token==0) {
93
+		LOG(L_ERR, "ERROR: TM module: too high flag number: %s (%d)\n; lower number"
94
+			" bellow %d reserved\n", (char *) (*param), *code, FL_MAX );
95
+		goto error;
96
+	}
97
+
98
+	/* free string */
99
+	free( *param );
100
+	/* fix now */
101
+	*param = code;
102
+	
103
+	return 0;
104
+
105
+error:
106
+	free( code );
107
+	return E_CFG;
108
+}
109
+
110
+
111
+#endif
0 112
new file mode 100644
... ...
@@ -0,0 +1,24 @@
0
+/*
1
+ * $Id$
2
+ */
3
+
4
+
5
+#ifndef _FLAGS_H
6
+#define _FLAGS_H
7
+
8
+enum { FL_WHITE=1, FL_YELLOW, FL_GREEN, FL_RED, FL_BLUE, FL_MAGENTA,
9
+	   FL_BROWN, FL_BLACK, FL_ACC, FL_MAX };
10
+
11
+typedef unsigned long flag_t;
12
+
13
+#define MAX_FLAG  ( sizeof(flag_t) * CHAR_BIT - 1 )
14
+
15
+struct sip_msg;
16
+
17
+int setflag( struct sip_msg* msg, flag_t flag );
18
+int resetflag( struct sip_msg* msg, flag_t flag );
19
+int isflagset( struct sip_msg* msg, flag_t flag );
20
+
21
+int flag_in_range( flag_t flag );
22
+
23
+#endif
... ...
@@ -14,7 +14,7 @@
14 14
 
15 15
 #include "forward.h"
16 16
 #include "config.h"
17
-#include "msg_parser.h"
17
+#include "parser/msg_parser.h"
18 18
 #include "route.h"
19 19
 #include "dprint.h"
20 20
 #include "udp_server.h"
... ...
@@ -6,7 +6,7 @@
6 6
 #ifndef forward_h
7 7
 #define forward_h
8 8
 
9
-#include "msg_parser.h"
9
+#include "parser/msg_parser.h"
10 10
 #include "route.h"
11 11
 #include "proxy.h"
12 12
 
... ...
@@ -30,7 +30,7 @@
30 30
 #endif
31 31
 #include "sr_module.h"
32 32
 #include "timer.h"
33
-#include "msg_parser.h"
33
+#include "parser/msg_parser.h"
34 34
 
35 35
 
36 36
 #include <signal.h>
... ...
@@ -20,7 +20,7 @@ enum fork_type { DEFAULT, NO_RESPONSE };
20 20
 /* FINAL_RESPONSE_TIMER ... tells how long should the transaction engine
21 21
    wait if no final response comes back*/
22 22
 #define FR_TIME_OUT       30
23
-#define INV_FR_TIME_OUT   60
23
+#define INV_FR_TIME_OUT   120
24 24
 
25 25
 /* WAIT timer ... tells how long state should persist in memory after
26 26
    a transaction was finalized*/
... ...
@@ -11,10 +11,10 @@
11 11
 #include <pthread.h>
12 12
 #include <arpa/inet.h>
13 13
 
14
-#include "../../msg_parser.h"
14
+#include "../../parser/msg_parser.h"
15 15
 #include "../../types.h"
16 16
 #include "config.h"
17
-#include "t_flags.h"
17
+/*#include "t_flags.h"*/
18 18
 
19 19
 struct s_table;
20 20
 struct entry;
... ...
@@ -132,7 +132,7 @@ typedef struct cell
132 132
 	/* protection against concurrent ACK processing */
133 133
 	ser_lock_t	ack_mutex;
134 134
 
135
-	tflags_t	flags;
135
+/*	tflags_t	flags; */
136 136
 
137 137
 #ifdef WAIT
138 138
 	/* protection against reentering WAIT state */
... ...
@@ -6,7 +6,7 @@
6 6
 #ifndef _SIP_MSG_H
7 7
 #define _SIP_MSG_H
8 8
 
9
-#include "../../msg_parser.h"
9
+#include "../../parser/msg_parser.h"
10 10
 
11 11
 #include "sh_malloc.h"
12 12
 
13 13
deleted file mode 100644
... ...
@@ -1,20 +0,0 @@
1
-/*
2
- * $Id$
3
- */
4
-
5
-
6
-#include "t_funcs.h"
7
-
8
-int t_setflag( unsigned int flag ) {
9
-	T->flags |= 1 << flag;
10
-	return 1;
11
-}
12
-
13
-int t_resetflag( unsigned int flag ) {
14
-	T->flags &= ~ flag;
15
-	return 1;
16
-}
17
-
18
-int t_isflagset( unsigned int flag ) {
19
-	return T->flags & (1<<flag) ? 1 : -1;
20
-}
21 1
deleted file mode 100644
... ...
@@ -1,26 +0,0 @@
1
-/*
2
- * $Id$
3
- */
4
-
5
-
6
-#ifndef _FLAGS_H
7
-#define _FLAGS_H
8
-
9
-#define FL_WHITE	1
10
-#define FL_YELLOW	2
11
-#define FL_GREEN	3
12
-#define FL_RED		4
13
-#define FL_BLUE		5
14
-#define FL_MAGENTA	6
15
-#define FL_BROWN	7
16
-#define FL_BLACK	8
17
-
18
-
19
-
20
-typedef unsigned long tflags_t;
21
-
22
-int t_setflag( unsigned int flag );
23
-int t_resetflag( unsigned int flag );
24
-int t_isflagset( unsigned int flag );
25
-
26
-#endif
... ...
@@ -7,7 +7,7 @@
7 7
 #include "t_funcs.h"
8 8
 #include "../../dprint.h"
9 9
 #include "../../config.h"
10
-#include "../../parser_f.h"
10
+#include "../../parser/parser_f.h"
11 11
 #include "../../ut.h"
12 12
 //#include "../../timer.h"
13 13
 
... ...
@@ -10,7 +10,7 @@
10 10
 #include <netinet/in.h>
11 11
 #include <netdb.h>
12 12
 
13
-#include "../../msg_parser.h"
13
+#include "../../parser/msg_parser.h"
14 14
 #include "../../globals.h"
15 15
 #include "../../udp_server.h"
16 16
 #include "../../msg_translator.h"
... ...
@@ -313,9 +313,7 @@ static inline void set_timer( struct s_table *hash_table,
313 313
 {
314 314
 	unsigned int timeout;
315 315
 	struct timer* list;
316
-	static enum lists to_table[NR_OF_TIMER_LISTS] = {
317
-		FR_TIME_OUT, INV_FR_TIME_OUT, WT_TIME_OUT, DEL_TIME_OUT,
318
-		RETR_T1, RETR_T1 << 1, RETR_T1 << 2, RETR_T2 };
316
+
319 317
 
320 318
 	if (list_id<FR_TIMER_LIST || list_id>=NR_OF_TIMER_LISTS) {
321 319
 		LOG(L_CRIT, "ERROR: set_timer: unkown list: %d\n", list_id);
... ...
@@ -324,7 +322,7 @@ static inline void set_timer( struct s_table *hash_table,
324 324
 #endif
325 325
 		return;
326 326
 	}
327
-	timeout = to_table[ list_id ];
327
+	timeout = timer_id2timeout[ list_id ];
328 328
 	list= &(hash_table->timers[ list_id ]);
329 329
 
330 330
 	lock(list->mutex);
... ...
@@ -7,10 +7,12 @@
7 7
 #include "t_funcs.h"
8 8
 #include "../../dprint.h"
9 9
 #include "../../config.h"
10
-#include "../../parser_f.h"
10
+#include "../../parser/parser_f.h"
11 11
 #include "../../ut.h"
12 12
 #include "../../timer.h"
13 13
 
14
+#include "t_hooks.h"
15
+
14 16
 
15 17
 #define shm_free_lump( _lmp) \
16 18
 	do{\
... ...
@@ -172,7 +174,8 @@ int t_forward_nonack( struct sip_msg* p_msg , unsigned int dest_ip_param ,
172 172
 			get_ticks() );
173 173
 		/*sets and starts the FINAL RESPONSE timer */
174 174
 		set_timer( hash_table, &(T->uac[branch].request.fr_timer),
175
-			FR_TIMER_LIST );
175
+			/* p_msg->REQ_METHOD==METHOD_INVITE ? FR_INV_TIMER_LIST : FR_TIMER_LIST ); */
176
+			FR_TIMER_LIST ); 
176 177
 		/* sets and starts the RETRANS timer */
177 178
 		T->uac[branch].request.retr_list = RT_T1_TO_1;
178 179
 		set_timer( hash_table, &(T->uac[branch].request.retr_timer),
... ...
@@ -269,6 +272,7 @@ int t_forward_ack( struct sip_msg* p_msg , unsigned int dest_ip_param ,
269 269
 
270 270
 	T->uas.isACKed = 1;
271 271
 	SEND_PR_BUFFER( &(T->uac[branch].request), ack, len );
272
+	callback_event( TMCB_E2EACK, p_msg );
272 273
 	return attach_ack( T, branch, ack , len );
273 274
 
274 275
 #ifdef _DON_USE
... ...
@@ -354,7 +358,9 @@ int forward_serial_branch(struct cell* Trans,int branch)
354 354
 	DBG("DEBUG: t_forward_serial_branch:starting timers (retrans and FR) %d\n",
355 355
 		get_ticks() );
356 356
 	/*sets and starts the FINAL RESPONSE timer */
357
-	set_timer( hash_table, &(T->uac[branch].request.fr_timer), FR_TIMER_LIST );
357
+	set_timer( hash_table, &(T->uac[branch].request.fr_timer), 
358
+			FR_TIMER_LIST ); 
359
+			/* p_msg->REQ_METHOD==METHOD_INVITE ? FR_INV_TIMER_LIST : FR_TIMER_LIST ); */
358 360
 	/* sets and starts the RETRANS timer */
359 361
 	T->uac[branch].request.retr_list = RT_T1_TO_1;
360 362
 	set_timer( hash_table, &(T->uac[branch].request.retr_timer), RT_T1_TO_1 );
361 363
new file mode 100644
... ...
@@ -0,0 +1,47 @@
0
+/*
1
+ * $Id$
2
+ */
3
+
4
+
5
+#include "t_hooks.h"
6
+
7
+static struct tm_callback_s* callback_array[ TMCB_END ] = { NULL, NULL } ;
8
+static int callback_id=0;
9
+
10
+/* register a callback function 'f' of type 'cbt'; will be called
11
+   back whenever the event 'cbt' occurs in transaction module
12
+*/
13
+int register_tmcb( tmcb_type cbt, transaction_cb f )
14
+{
15
+	struct tm_callback_s *cbs;
16
+
17
+	if (cbt<0 || cbt>=TMCB_END ) {
18
+		LOG(L_ERR, "ERROR: register_tmcb: invalid callback type: %d\n",
19
+			cbt );
20
+		return E_BUG;
21
+	}
22
+
23
+	if (!(cbs=malloc( sizeof( struct tm_callback_s)))) {
24
+		LOG(L_ERR, "ERROR: register_tmcb: out of mem\n");
25
+		return E_OUT_OF_MEM;
26
+	}
27
+
28
+	callback_id++;
29
+	cbs->id=callback_id;
30
+	cbs->callback=f;
31
+	cbs->next=callback_array[ cbt ];
32
+	callback_array[ cbt ]=cbs;
33
+
34
+	return callback_id;
35
+}
36
+
37
+void callback_event( tmcb_type cbt , struct sip_msg *msg )
38
+{
39
+	struct tm_callback_s *cbs;
40
+
41
+	DBG("DBG: callback type %d entered\n", cbt );
42
+	for (cbs=callback_array[ cbt ]; cbs; cbs=cbs->next)  {
43
+		DBG("DBG: callback id %d entered\n", cbs->id );
44
+		cbs->callback( T, msg );
45
+	}
46
+}
0 47
new file mode 100644
... ...
@@ -0,0 +1,29 @@
0
+/*
1
+ * $Id$
2
+ */
3
+
4
+#ifndef _HOOKS_H
5
+#define _HOOKS_H
6
+
7
+#include "h_table.h"
8
+#include "t_funcs.h"
9
+
10
+typedef enum { TMCB_REPLY,  TMCB_E2EACK, TMCB_END } tmcb_type;
11
+
12
+typedef void (transaction_cb) ( struct cell* t, struct sip_msg* msg );
13
+
14
+struct tm_callback_s {
15
+	int id;
16
+	transaction_cb* callback;
17
+	struct tm_callback_s* next;
18
+};
19
+
20
+
21
+extern struct tm_callback_s* callback_array[ TMCB_END ];
22
+
23
+typedef int (*register_tmcb_f)(tmcb_type cbt, transaction_cb f);
24
+
25
+int register_tmcb( tmcb_type cbt, transaction_cb f );
26
+void callback_event( tmcb_type cbt, struct sip_msg *msg );
27
+
28
+#endif
... ...
@@ -6,7 +6,7 @@
6 6
 #include <assert.h>
7 7
 #include "../../dprint.h"
8 8
 #include "../../config.h"
9
-#include "../../parser_f.h"
9
+#include "../../parser/parser_f.h"
10 10
 #include "../../ut.h"
11 11
 #include "../../timer.h"
12 12
 #include "hash_func.h"
... ...
@@ -131,55 +131,55 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked )
131 131
 		{ /* it's a ACK request*/
132 132
 			/* first only the length are checked */
133 133
 			if ( t_msg->first_line.u.request.method_value==METHOD_INVITE
134
-			&& (fprintf(stderr,"------Method name OK->testing callid len...\n"))
134
+			/* && (fprintf(stderr,"------Method name OK->testing callid len...\n")) */
135 135
 			&& /*callid length*/ EQ_LEN(callid)
136
-			&& (fprintf(stderr,"------CallID OK -> testing cseq nr len\n"))
136
+			/* && (fprintf(stderr,"------CallID OK -> testing cseq nr len\n")) */
137 137
 			&& get_cseq(t_msg)->number.len==get_cseq(p_msg)->number.len
138
-			&& (fprintf(stderr,"------Cseq nr OK -> testing from len\n"))
138
+			/* && (fprintf(stderr,"------Cseq nr OK -> testing from len\n")) */
139 139
 			&& /*from length*/ EQ_LEN(from)
140
-			&& (fprintf(stderr,"------from OK -> testing To uri len\n"))
140
+			/* && (fprintf(stderr,"------from OK -> testing To uri len\n")) */
141 141
 			&& /*to uri*/get_to(t_msg)->uri.len==get_to(p_msg)->uri.len
142
-			&& (fprintf(stderr,"------To uri OK -> testing To tag len\n"))
142
+			/* && (fprintf(stderr,"------To uri OK -> testing To tag len\n")) */
143 143
 			&& /*to tag*/p_cell->uas.tag->len==get_to(p_msg)->tag_value.len
144
-			&& (fprintf(stderr,"------To tag OK -> testing uri len\n"))
144
+			/* && (fprintf(stderr,"------To tag OK -> testing uri len\n")) */
145 145
 			&& /*req URI*/(p_cell->uas.status==200 || EQ_REQ_URI_LEN )
146
-			&& (fprintf(stderr,"------uri OK -> testing via len\n"))
146
+			/* && (fprintf(stderr,"------uri OK -> testing via len\n")) */
147 147
 			&& /*VIA*/(p_cell->uas.status==200 || EQ_VIA_LEN(via1)) )
148 148
 				/* so far the lengths are the same
149 149
 				-> let's check the contents */
150
-				if ( fprintf(stderr,"------callid |%.*s| |%.*s|\n",
150
+				if ( /* fprintf(stderr,"------callid |%.*s| |%.*s|\n",
151 151
 					p_msg->callid->body.len,p_msg->callid->body.s,
152 152
 					t_msg->callid->body.len,t_msg->callid->body.s)
153
-				&& /*callid*/!memcmp( t_msg->callid->body.s,
153
+				&& */ /*callid*/!memcmp( t_msg->callid->body.s,
154 154
 					p_msg->callid->body.s,p_msg->callid->body.len)
155
-				&& fprintf(stderr,"------cseq |%.*s| |%.*s|\n",
155
+				/* && fprintf(stderr,"------cseq |%.*s| |%.*s|\n",
156 156
 					get_cseq(p_msg)->number.len,get_cseq(p_msg)->number.s,
157
-					get_cseq(t_msg)->number.len,get_cseq(t_msg)->number.s)
157
+					get_cseq(t_msg)->number.len,get_cseq(t_msg)->number.s) */
158 158
 				&& /*cseq nr*/!memcmp(get_cseq(t_msg)->number.s,
159 159
 					get_cseq(p_msg)->number.s,get_cseq(p_msg)->number.len)
160
-				&& fprintf(stderr,"------from |%.*s| |%.*s|\n",
160
+				/* &&  fprintf(stderr,"------from |%.*s| |%.*s|\n",
161 161
 					p_msg->from->body.len, translate_pointer(p_msg->orig,
162 162
 						p_msg->buf,p_msg->from->body.s),
163
-					t_msg->from->body.len,t_msg->from->body.s)
163
+					t_msg->from->body.len,t_msg->from->body.s) */
164 164
 				&& /*from*/EQ_STR(from)
165
-				&& fprintf(stderr,"------to uri |%.*s| |%.*s|\n",
165
+				/* && fprintf(stderr,"------to uri |%.*s| |%.*s|\n",
166 166
 					get_to(p_msg)->uri.len,get_to(p_msg)->uri.s,
167
-					get_to(t_msg)->uri.len,get_to(t_msg)->uri.s)
167
+					get_to(t_msg)->uri.len,get_to(t_msg)->uri.s) */
168 168
 				&& /*to uri*/!memcmp(get_to(t_msg)->uri.s,
169 169
 					get_to(p_msg)->uri.s,get_to(t_msg)->uri.len)
170
-				&& fprintf(stderr,"------to tag |%.*s| |%.*s|\n",
170
+				/* && fprintf(stderr,"------to tag |%.*s| |%.*s|\n",
171 171
                     get_to(p_msg)->tag_value.len,get_to(p_msg)->tag_value.s,
172
-                    p_cell->uas.tag->len, p_cell->uas.tag->s)
172
+                    p_cell->uas.tag->len, p_cell->uas.tag->s) */
173 173
 				&& /*to tag*/!memcmp(p_cell->uas.tag->s,
174 174
 					get_to(p_msg)->tag_value.s,p_cell->uas.tag->len)
175
-				&& fprintf(stderr,"------URI %d |%.*s| |%.*s|\n",
175
+				/* && fprintf(stderr,"------URI %d |%.*s| |%.*s|\n",
176 176
 					p_cell->uas.status,p_msg->first_line.u.request.uri.len,
177 177
 					translate_pointer(p_msg->orig, p_msg->buf,
178 178
 						p_msg->first_line.u.request.uri.s),
179 179
 					t_msg->first_line.u.request.uri.len,
180
-					t_msg->first_line.u.request.uri.s)
180
+					t_msg->first_line.u.request.uri.s) */
181 181
 				&& /*req URI*/(p_cell->uas.status==200 || EQ_REQ_URI_STR)
182
-				&& fprintf(stderr,"------VIA %d |%.*s| |%.*s|\n",
182
+				/* && fprintf(stderr,"------VIA %d |%.*s| |%.*s|\n",
183 183
 					p_cell->uas.status, 
184 184
 					(p_msg->via1->bsize-(p_msg->via1->name.s-
185 185
 						(p_msg->via1->hdr.s+p_msg->via1->hdr.len))),
... ...
@@ -187,7 +187,7 @@ int t_lookup_request( struct sip_msg* p_msg , int leave_new_locked )
187 187
 						p_msg->via1->name.s),
188 188
                     (t_msg->via1->bsize-(t_msg->via1->name.s-
189 189
 						(t_msg->via1->hdr.s+t_msg->via1->hdr.len))),
190
-					t_msg->via1->name.s)
190
+					t_msg->via1->name.s) */
191 191
 				&& /*VAI*/(p_cell->uas.status==200 ||EQ_VIA_STR(via1)) )
192 192
 					{ /* WE FOUND THE GOLDEN EGG !!!! */
193 193
 						goto found;
... ...
@@ -245,67 +245,67 @@ struct cell* t_lookupOriginalT(  struct s_table* hash_table ,
245 245
 
246 246
 		/* is it the wanted transaction ? */
247 247
 		/* first only the length are checked */
248
-		if ( fprintf(stderr,"starting\n") && p_cell->uas.request->REQ_METHOD!=METHOD_CANCEL
249
-			&& fprintf(stderr,"checking callid length....\n")
248
+		if ( /* fprintf(stderr,"starting\n")  && */ p_cell->uas.request->REQ_METHOD!=METHOD_CANCEL
249
+			/* && fprintf(stderr,"checking callid length....\n") */
250 250
 			&& /*callid length*/ EQ_LEN(callid)
251
-			&& fprintf(stderr,"OK. checking cseg nr len....\n")	
251
+			/* && fprintf(stderr,"OK. checking cseg nr len....\n")	 */
252 252
 			&& get_cseq(t_msg)->number.len==get_cseq(p_msg)->number.len
253
-			&& fprintf(stderr,"OK. checking REQ_URI len.... \n")
253
+			/* && fprintf(stderr,"OK. checking REQ_URI len.... \n") */
254 254
 			&& EQ_REQ_URI_LEN
255
-			&& fprintf(stderr,"OK. checking VIA %d %d....\n",
255
+			/* && fprintf(stderr,"OK. checking VIA %d %d....\n",
256 256
 				(p_msg->via1->bsize-(p_msg->via1->name.s-
257 257
 					(p_msg->via1->hdr.s+p_msg->via1->hdr.len))),
258 258
 				(t_msg->via1->bsize-(t_msg->via1->name.s-
259
-					(t_msg->via1->hdr.s+t_msg->via1->hdr.len))))
260
-            && fprintf(stderr,"OK. VIA |%.*s| |%.*s|\n",
259
+					(t_msg->via1->hdr.s+t_msg->via1->hdr.len)))) */
260
+            /* && fprintf(stderr,"OK. VIA |%.*s| |%.*s|\n",
261 261
                 (p_msg->via1->bsize-(p_msg->via1->name.s-
262 262
                      (p_msg->via1->hdr.s+p_msg->via1->hdr.len))),
263 263
                 translate_pointer(p_msg->orig,p_msg->buf,
264 264
                        p_msg->via1->name.s),
265 265
                 (t_msg->via1->bsize-(t_msg->via1->name.s-
266 266
                       (t_msg->via1->hdr.s+t_msg->via1->hdr.len))),
267
-                t_msg->via1->name.s)
267
+                t_msg->via1->name.s) */
268 268
 			&& EQ_VIA_LEN(via1) 
269
-			&& fprintf(stderr,"OK. checking FROM len... \n")
269
+			/* && fprintf(stderr,"OK. checking FROM len... \n") */
270 270
 			&& EQ_LEN(from)
271
-			&& fprintf(stderr,"OK. checking TO len... \n")
271
+			/* && fprintf(stderr,"OK. checking TO len... \n") */
272 272
 			&& EQ_LEN(to)
273
-			&& fprintf(stderr,"OK\n") )
273
+			/* && fprintf(stderr,"OK\n") */ )
274 274
 				/* so far the lengths are the same
275 275
 				 let's check the contents */
276 276
 				if (
277
-                	fprintf(stderr,"checking callid |%.*s| |%.*s|\n",
277
+                	/* fprintf(stderr,"checking callid |%.*s| |%.*s|\n",
278 278
                     	p_msg->callid->body.len, translate_pointer(p_msg->orig,
279 279
                         	p_msg->buf,p_msg->callid->body.s),
280
-                    	t_msg->callid->body.len,t_msg->callid->body.s)
281
-					&& /*callid*/ EQ_STR(callid)
282
-					&& fprintf(stderr,"OK. cseq nr |%.*s| |%.*s|\n",
280
+                    	t_msg->callid->body.len,t_msg->callid->body.s) 
281
+					&& *//*callid*/ EQ_STR(callid)
282
+					/* && fprintf(stderr,"OK. cseq nr |%.*s| |%.*s|\n",
283 283
 						get_cseq(p_msg)->number.len,get_cseq(p_msg)->number.s,
284
-						get_cseq(t_msg)->number.len,get_cseq(t_msg)->number.s)
284
+						get_cseq(t_msg)->number.len,get_cseq(t_msg)->number.s) */
285 285
 					&& /*cseq_nr*/ !memcmp(get_cseq(t_msg)->number.s,
286 286
 						get_cseq(p_msg)->number.s,get_cseq(p_msg)->number.len)
287
-	                && fprintf(stderr,"OK. URI %d |%.*s| |%.*s|\n",
287
+	                /* && fprintf(stderr,"OK. URI %d |%.*s| |%.*s|\n",
288 288
                     	p_cell->uas.status,p_msg->first_line.u.request.uri.len,
289 289
                     	translate_pointer(p_msg->orig, p_msg->buf,
290 290
                         	p_msg->first_line.u.request.uri.s),
291 291
                     	t_msg->first_line.u.request.uri.len,
292
-                    	t_msg->first_line.u.request.uri.s)
292
+                    	t_msg->first_line.u.request.uri.s) */
293 293
 					&& EQ_REQ_URI_STR
294
-	                && fprintf(stderr,"OK. VIA |%.*s| |%.*s|\n",
294
+	                /* && fprintf(stderr,"OK. VIA |%.*s| |%.*s|\n",
295 295
         	            (p_msg->via1->bsize-(p_msg->via1->name.s-
296 296
             	            (p_msg->via1->hdr.s+p_msg->via1->hdr.len))),
297 297
                 	    translate_pointer(p_msg->orig,p_msg->buf,
298 298
                     	    p_msg->via1->name.s),
299 299
            				(t_msg->via1->bsize-(t_msg->via1->name.s-
300 300
                     	    (t_msg->via1->hdr.s+t_msg->via1->hdr.len))),
301
-						t_msg->via1->name.s)
301
+						t_msg->via1->name.s) */
302 302
 					&& EQ_VIA_STR(via1)
303
-	                && fprintf(stderr,"OK. from |%.*s| |%.*s|\n",
303
+	                /* && fprintf(stderr,"OK. from |%.*s| |%.*s|\n",
304 304
                         p_msg->from->body.len, translate_pointer(p_msg->orig,
305 305
                             p_msg->buf,p_msg->from->body.s),
306
-                        t_msg->from->body.len,t_msg->from->body.s)
306
+                        t_msg->from->body.len,t_msg->from->body.s) */
307 307
 					&& EQ_STR(from)
308
-					&& fprintf(stderr,"OK\n") )
308
+					/* && fprintf(stderr,"OK\n") */ )
309 309
 					{ /* WE FOUND THE GOLDEN EGG !!!! */
310 310
 						DBG("DEBUG: t_lookupOriginalT: canceled transaction"
311 311
 							" found (%p)! \n",p_cell );
... ...
@@ -559,9 +559,13 @@ enum addifnew_status t_addifnew( struct sip_msg* p_msg )
559 559
 	struct cell *new_cell;
560 560
 
561 561
 	/* is T still up-to-date ? */
562
-	DBG("DEBUG: t_check_new_request: msg id=%d , global msg id=%d ,"
562
+	DBG("DEBUG: t_addifnew: msg id=%d , global msg id=%d ,"
563 563
 		" T on entrance=%p\n",p_msg->id,global_msg_id,T);
564
-	if ( p_msg->id != global_msg_id || T==T_UNDEFINED )
564
+	if ( p_msg->id != global_msg_id || T==T_UNDEFINED 
565
+		/* if someone tried to do something previously by mistake with
566
+		   a transaction which did not exist yet, try to look-up
567
+		   the transacion too */
568
+		|| T==T_NULL)
565 569
 	{
566 570
 		global_msg_id = p_msg->id;
567 571
 		T = T_UNDEFINED;
... ...
@@ -604,7 +608,7 @@ enum addifnew_status t_addifnew( struct sip_msg* p_msg )
604 604
 		}
605 605
 	} else {
606 606
 		if (T)
607
-			LOG(L_ERR, "ERROR: t_check_new_request: already "
607
+			LOG(L_ERR, "ERROR: t_addifnew: already "
608 608
 			"processing this message, T found!\n");
609 609
 		else
610 610
 			LOG(L_ERR, "ERROR: t_check_new_request: already "
... ...
@@ -8,10 +8,12 @@
8 8
 #include "t_funcs.h"
9 9
 #include "../../dprint.h"
10 10
 #include "../../config.h"
11
-#include "../../parser_f.h"
11
+#include "../../parser/parser_f.h"
12 12
 #include "../../ut.h"
13 13
 #include "../../timer.h"
14 14
 
15
+#include "t_hooks.h"
16
+
15 17
 
16 18
 
17 19
 
... ...
@@ -38,11 +40,11 @@ int t_retransmit_reply( /* struct sip_msg* p_msg    */ )
38 38
 	int len;
39 39
 
40 40
 	if (!T->uas.response.buffer)
41
-		return 0;
41
+		return -1;
42 42
 
43 43
 	if ( (len=T->uas.response.buffer_len)==0 || len>BUF_SIZE ) {
44 44
 		UNLOCK_REPLIES( T );
45
-		return -1;
45
+		return -2;
46 46
 	}
47 47
 	memcpy( b, T->uas.response.buffer, len );
48 48
 	UNLOCK_REPLIES( T );
... ...
@@ -370,6 +372,7 @@ int t_on_reply( struct sip_msg  *p_msg )
370 370
 	if (relay >= 0) {
371 371
 		SEND_PR_BUFFER( rb, buf, res_len );
372 372
 		t_update_timers_after_sending_reply( rb );
373
+		callback_event( TMCB_REPLY, p_msg );
373 374
 	}
374 375
 
375 376
 	/* *** ACK handling *** */
... ...
@@ -378,6 +381,7 @@ int t_on_reply( struct sip_msg  *p_msg )
378 378
 		{   /*retransmit*/
379 379
 			/* I don't need any additional syncing here -- after ack
380 380
 			   is introduced it's never changed */
381
+			DBG("DEBUG: localy cached ACK retranmitted\n");
381 382
 			SEND_ACK_BUFFER( &(T->uac[branch].request) );
382 383
 		} else if (msg_class>2 ) {
383 384
 			/*on a non-200 reply to INVITE*/
... ...
@@ -17,7 +17,20 @@ int timer_group[NR_OF_TIMER_LISTS] =
17 17
 	TG_RT, TG_RT, TG_RT, TG_RT
18 18
 };
19 19
 
20
-
20
+/* default values of timeouts for all the timer list
21
+   (see timer.h for enumeration of timer lists)
22
+*/
23
+unsigned int timer_id2timeout[NR_OF_TIMER_LISTS] = {
24
+	FR_TIME_OUT, 		/* FR_TIMER_LIST */
25
+	INV_FR_TIME_OUT, 	/* FR_INV_TIMER_LIST */
26
+	WT_TIME_OUT, 		/* WT_TIMER_LIST */
27
+	DEL_TIME_OUT,		/* DELETE_LIST */
28
+	RETR_T1, 			/* RT_T1_TO_1 */
29
+	RETR_T1 << 1, 		/* RT_T1_TO_2 */
30
+	RETR_T1 << 2, 		/* RT_T1_TO_3 */
31
+	RETR_T2 			/* RT_T2 */
32
+						/* NR_OF_TIMER_LISTS */
33
+};
21 34
 
22 35
 
23 36
 void reset_timer_list( struct s_table* hash_table, enum lists list_id)
... ...
@@ -25,7 +25,10 @@ enum lists
25 25
 
26 26
 
27 27
 #define is_in_timer_list2(_tl) ( (_tl)->timer_list )
28
+
28 29
 extern int timer_group[NR_OF_TIMER_LISTS];
30
+extern unsigned int timer_id2timeout[NR_OF_TIMER_LISTS];
31
+
29 32
 struct timer;
30 33
 
31 34
 #include "lock.h"
... ...
@@ -17,6 +17,8 @@
17 17
 #include "sip_msg.h"
18 18
 #include "h_table.h"
19 19
 #include "t_funcs.h"
20
+#include "t_hooks.h"
21
+#include "tm_load.h"
20 22
 
21 23
 
22 24
 
... ...
@@ -39,11 +41,6 @@ static int w_t_add_fork_on_no_rpl(struct sip_msg* msg,char* str,char* str2);
39 39
 static int w_t_clear_forks(struct sip_msg* msg, char* str, char* str2);
40 40
 static void w_onbreak(struct sip_msg* msg) { t_unref(); }
41 41
 
42
-static int w_t_setflag( struct sip_msg* msg, char *flag, char *foo );
43
-static int w_t_resetflag( struct sip_msg* msg, char *flag, char *foo );
44
-static int w_t_isflagset( struct sip_msg* msg, char *flag, char *foo );
45
-static int fixup_t_flag(void** param, int param_no);
46
-
47 42
 static int mod_init(void);
48 43
 
49 44
 #ifdef STATIC_TM
... ...
@@ -51,7 +48,8 @@ struct module_exports tm_exports = {
51 51
 #else
52 52
 struct module_exports exports= {
53 53
 #endif
54
-	"tm_module",
54
+	"tm",
55
+	/* -------- exported functions ----------- */
55 56
 	(char*[]){			
56 57
 				"t_add_transaction",
57 58
 				"t_lookup_request",
... ...
@@ -67,9 +65,8 @@ struct module_exports exports= {
67 67
 				"t_fork_to_uri",
68 68
 				"t_clear_forks",
69 69
 				"t_fork_on_no_response",
70
-				"t_setflag",
71
-				"t_resetflag",
72
-				"t_isflagset"
70
+				"register_tmcb",
71
+				"load_tm"
73 72
 			},
74 73
 	(cmd_function[]){
75 74
 					w_t_add_transaction,
... </