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 134
 <INITIAL>{SEND}	{ count(); yylval.strval=yytext; return SEND; }
132 135
 <INITIAL>{LOG}	{ count(); yylval.strval=yytext; return LOG_TOK; }
133 136
 <INITIAL>{ERROR}	{ count(); yylval.strval=yytext; return ERROR; }
137
+<INITIAL>{SETFLAG}	{ count(); yylval.strval=yytext; return SETFLAG; }
138
+<INITIAL>{RESETFLAG}	{ count(); yylval.strval=yytext; return RESETFLAG; }
139
+<INITIAL>{ISFLAGSET}	{ count(); yylval.strval=yytext; return ISFLAGSET; }
134 140
 <INITIAL>{ROUTE}	{ count(); yylval.strval=yytext; return ROUTE; }
135 141
 <INITIAL>{EXEC}	{ count(); yylval.strval=yytext; return EXEC; }
136 142
 <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 559
 		| LOG_TOK error { $$=0; yyerror("missing '(' or ')' ?"); }
558 560
 		| LOG_TOK LPAREN error RPAREN { $$=0; yyerror("bad log"
559 561
 									"argument"); }
562
+		| SETFLAG LPAREN NUMBER RPAREN {$$=mk_action( SETFLAG_T, NUMBER_ST, 0,
563
+													(void *)$3, 0 ); }
564
+		| SETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
565
+		| RESETFLAG LPAREN NUMBER RPAREN {$$=mk_action(	RESETFLAG_T, NUMBER_ST, 0,
566
+													(void *)$3, 0 ); }
567
+		| RESETFLAG error { $$=0; yyerror("missing '(' or ')'?"); }
568
+		| ISFLAGSET LPAREN NUMBER RPAREN {$$=mk_action(	ISFLAGSET_T, NUMBER_ST, 0,
569
+													(void *)$3, 0 ); }
570
+		| ISFLAGSET error { $$=0; yyerror("missing '(' or ')'?"); }
560 571
 		| ERROR LPAREN STRING COMMA STRING RPAREN {$$=mk_action(ERROR_T,
561 572
 																STRING_ST, 
562 573
 																STRING_ST,
563 574
 																$3,
564 575
 																$5);
565 576
 												  }
566
-												
567 577
 		| ERROR error { $$=0; yyerror("missing '(' or ')' ?"); }
568 578
 		| ERROR LPAREN error RPAREN { $$=0; yyerror("bad error"
569 579
 														"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 23
 # not handle DNS at all)
20 24
 listen=195.37.77.101
21 25
 
26
+# ------------------ module loading ----------------------------------
27
+
22 28
 loadmodule "../sip_router/modules/sl/sl.so"
23 29
 loadmodule "../sip_router/modules/print/print.so"
24 30
 loadmodule "../sip_router/modules/tm/tm.so"
31
+loadmodule "../sip_router/modules/acc/acc.so"
25 32
 loadmodule "../sip_router/modules/rr/rr.so"
26 33
 loadmodule "../sip_router/modules/maxfwd/maxfwd.so"
27 34
 loadmodule "../sip_router/modules/mysql/mysql.so"
... ...
@@ -29,6 +36,10 @@ loadmodule "../sip_router/modules/usrloc/usrloc.so"
29 36
 loadmodule "../sip_router/modules/auth/auth.so"
30 37
 loadmodule "../sip_router/modules/cpl/cpl.so"
31 38
 
39
+# ----------------- setting module-specific parameters ---------------
40
+
41
+# -- usrloc params --
42
+
32 43
 modparam("usrloc", "use_database",   1)
33 44
 modparam("usrloc", "table",          "location")
34 45
 modparam("usrloc", "user_column",    "user")
... ...
@@ -40,16 +51,51 @@ modparam("usrloc", "cseq_column",    "cseq")
40 51
 modparam("usrloc", "flush_interval", 60)
41 52
 modparam("usrloc", "db_url",         "sql://csps:47csps11@dbhost/csps107")
42 53
 
54
+# -- auth params --
55
+
43 56
 modparam("auth", "db_url",        "sql://csps:47csps11@dbhost/csps107")
44 57
 modparam("auth", "user_column",   "user_id")
58
+# nonce generation secret; particularly useful if multiple servers
59
+# in a proxy farm are configured to authenticate
45 60
 modparam("auth", "secret",        "439tg8h349g8hq349t9384hg")
61
+# calculate_ha1=false means password column includes ha1 strings;
62
+# if it was false, plain-text passwords would be assumed
46 63
 modparam("auth", "calculate_ha1", false)
47 64
 modparam("auth", "nonce_expire",  300)
48 65
 modparam("auth", "retry_count",   5)
66
+# password_column, realm_column, group_table, group_user_column,
67
+#   group_group_column are set to their default values
68
+# password_column_2 allows to deal with clients who put domain name
69
+#   in authentication credentials when calculate_ha1=false (if true,
70
+#   it works); if set to a value and USER_DOMAIN_HACK was enabled
71
+#   in defs.h, authentication will still work
49 72
 
73
+# -- acc params --
74
+# report ACKs too for sake of completeness -- as we account PSTN
75
+# destinations which are RR, ACKs should show up
76
+modparam("acc", "report_ack", 1)
77
+# don't bother me with early media reports (I don't like 183 
78
+# too much anyway...ever thought of timer C hitting after
79
+# listening to music-on-hold for five minutes?)
80
+modparam("acc", "early_media", 0)
81
+modparam("acc", "log_level", 1)
82
+# that is the flag for which we will account -- don't forget to
83
+# set the same one :-)
84
+modparam("acc", "acc_flag", 1 )
85
+# we are interested only in succesful transactions
86
+modparam("acc", "failed_transactions", 0 )
87
+
88
+# -- tm params --
89
+modparam("tm", "fr_timer", 10 )
90
+modparam("tm", "fr_inv_timer", 30 )
91
+
92
+# -------------------------  request routing logic -------------------
93
+
94
+# main routing logic
50 95
 
51 96
 route{
52
-	# filter local stateless ACK generated by authentication and other replies
97
+
98
+	# filter local stateless ACK generated by authentication of mf replies
53 99
 	sl_filter_ACK();
54 100
 
55 101
 	# filter too old messages
... ...
@@ -71,163 +117,215 @@ route{
71 117
 		break;
72 118
 	};
73 119
 
120
+	# if this request is not for our domain, fall over to
121
+	# outbound request processing; include gateway's address
122
+	# in matching too -- we RR requests to it, so that
123
+	# its address may show up in subsequent requests
124
+	# after rewriteFromRoute
125
+	
126
+	if (!(uri=~"[@:]iptel\.org([;:].*)*" 
127
+		| uri=~"[@:]195\.37\.77\.101([;:].*)*" |
128
+		uri=~"@195\.37\.77\.110([;:].*)*" )) {
129
+		route(2);
130
+	};
131
+	# here we continue with requests for our domain...
132
+
74 133
 	# various aliases (might use a database in future)
75
-	if (uri=~"sip:9040@.*") {
76
-		setuser("jiri");
134
+	if (uri=~"sip:9040@") {
135
+		seturi("jiri@iptel.org");
77 136
 	};
78
-	# special measure for our US friends
79 137
 	if (uri=~"sip:17@") {
80 138
 		seturi("sip:henry@siptest.wcom.com");
81 139
 	};
140
+	# check again, if it is still for our domain after aliases
141
+	if ( !(uri=~"[@:]iptel\.org([;:].*)*" | 
142
+		uri=~"[@:]195\.37\.77\.101([;:].*)*" |
143
+		uri=~"@195\.37\.77\.110([;:].*)*" )) {
144
+		route(2);
145
+	};
146
+	log("Request is for iptel.org\n");	
82 147
 
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");
148
+	# registers always MUST be authenticated to
149
+	# avoid stealing incoming calls	
150
+	if (method=="REGISTER") {
151
+		log("Request is REGISTER\n");
152
+		if (!www_authorize(	"iptel.org" /* realm */, 
153
+			 				"subscriber" /* table name */ )) {
154
+			log("REGISTER has no credentials, sending challenge\n");
155
+			www_challenge(	"iptel.org" /* realm */, 
156
+							"0" /* no qop -- M$ can't deal with it */);
157
+			break;
158
+		};
159
+		# prohibit attempts to grab someone else's To address 
160
+		# using  valid credentials
161
+		if (!check_to()) {
162
+			log("To Cheating attempt\n");
163
+			sl_send_reply("403", "That is ugly -- use To=id next time");
114 164
 			break;
115 165
 		};
166
+			
167
+		# update Contact database
168
+       	log("REGISTER is authorized, saving location\n");
169
+		save_contact("location");
170
+		break;
171
+	};
116 172
 
173
+	# now check if it's about PSTN destinations through our gateway;
174
+	# note that 8.... is exempted for numerical destinations
175
+	if (uri=~"sip:[0-79][0-9]*@.*") {
176
+		route(3);
177
+	}; 
117 178
 
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
179
+	# ---------- demo - begin --------------
180
+	/* added by Bogdan for cpl demo - Dorgham request*/
181
+	if (uri=~"sip:test@.*" && method=="INVITE")
182
+	{
183
+		log("SER : runing CPL!! :)\n");
184
+		if ( !cpl_run_script() )
185
+		{
186
+   			log("SER : Error during running CPL script!\n");
187
+		}else{
188
+   			if ( cpl_is_response_reject() ) {
189
+				log("SER: reject");
190
+       			sl_send_reply("603","I am not available!");
191
+       			break;
192
+   			}else if ( cpl_is_response_redirect() ) {
193
+       			log("SER : redirect\n");
194
+       			cpl_update_contact();
195
+       			sl_send_reply("302","Moved temporarily");
196
+       			break;
197
+   			};
198
+		};
199
+	};
200
+	# -------------- demo - end -------------
138 201
 
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
-					};
202
+	# native SIP destinations are handled using our USRLOC DB
203
+	if (!lookup_contact("location")) {
204
+		log("Unable to lookup contact, sending 404\n");
205
+		sl_send_reply("404", "Not Found");
206
+		break;
207
+	};
208
+	# check whether some inventive user has uploaded  gateway 
209
+	# contacts to UsrLoc to bypass our authorization logic
210
+	if (uri=~"@195\.37\.77\.110([;:].*)*" ) {
211
+		log("Weird! Gateway address in UsrLoc!\n");
212
+		route(3);
213
+	};
169 214
 
170
-				};
171
-			};
215
+	# requests from gateway should be RR-ed too
216
+	if (src_ip==195.37.77.110 && method=="INVITE")  {
217
+		addRecordRoute();
218
+	};
172 219
 
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 *******************************************
220
+	# we now know we may, we know where, let it go out now!
221
+	t_relay();
222
+}
204 223
 
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
-			};
224
+# routing logic for outbound requests targeted out of our domain
225
+route[2] {
226
+		# outbound requests are allowed only for our users -- we don't
227
+		# support relaying and don't like strangers bothering us
228
+		# with resolving DNS
229
+		log("that's a request to outside");
230
+		if (!(src_ip==195.37.77.110) & 
231
+			!(proxy_authorize(	"iptel.org" /* realm */,
232
+							"subscriber" /* table name */ ))) {
233
+			# see comments bellow on these ACK/CANCEL exceptions
234
+			if (method=="ACK" ) {
235
+				log("failed outbound authentication for ACK granted");
236
+			} else if (method=="CANCEL") {
237
+				log("failed outbound authentication for ACK granted");
238
+			} else proxy_challenge("iptel.org" /* realm */, "0" /* no-qop */);
239
+			break;
216 240
 		};
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
241
+		# to maintain credibility of our proxy, we check From to be
242
+		# equal of credential id -- all outbound request leaving our
243
+		# proxy are guaranteed to be generated by persons in "From"
244
+		if (!check_from()) {
245
+			log("From Cheating attempt\n");
246
+			sl_send_reply("403", "That is ugly -- use From=id next time");
247
+			break;
228 248
 		};
229 249
 
230
-		# we now know we may, we now where, let it go out now!
231 250
 		t_relay();
232 251
 }
233 252
 
253
+# logic for calls through our PSTN gateway
254
+route[3] {
255
+	# free call destinations ... no authentication needed
256
+	if (uri=~"sip:001795061546@.*" | uri=~"sip:0016097265544.*" 
257
+		| uri=~"sip:[79][0-9][0-9][0-9]@.*") {
258
+		log("Free PSTN\n");
259
+	} else {
260
+		# all other PSTN destinations only for authenticated users
261
+		# (Cisco GW, which has no digest support, is authenticated
262
+		# by its IP address -- that's for sure not very strong;
263
+		# wth confirmed that we filter packets coming from outside
264
+		# and bearing SRC IP address of our network)
265
+		if (!(src_ip==195.37.77.110) & 
266
+			!(proxy_authorize(	"iptel.org" /* realm */,
267
+								"subscriber" /* table name */)))  {
268
+			# we are forgiving and ignore improper credentials
269
+			# for ACK/CANCEL as bis-09 is somewhat cryptic about
270
+			# its use and many UACs have not gotten it right
271
+			if (method=="ACK" ) {
272
+				log("failed gw authentication for ACK granted");
273
+			} else if (method=="CANCEL") {
274
+				log("failed gw authentication for ACK granted");
275
+			} else proxy_challenge(	"iptel.org" /* realm */, 
276
+									"0" /* no qop */ );
277
+			break;
278
+		};
279
+		
280
+		# authorize only for INVITEs -- RR/Contact may result in weird
281
+		# things showing up in d-uri that would break our logic; our
282
+		# major concern is INVITE which causes PSTN costs anyway
283
+
284
+		if (method=="INVITE") {
285
+
286
+			# does the authenticated user have a permission for local
287
+			# calls? (i.e., is he in the "local" group?)
288
+			if (uri=~"sip:0[1-9][0-9]+@.*") {
289
+				if (!is_in_group("local")) {
290
+					sl_send_reply("403", "Local Toodle Noodle...");
291
+					break;
292
+				};
293
+			# the same for long-distance
294
+			} else if (uri=~"sip:00[1-9][0-9]+@.*") {
295
+				if (uri=~"sip:001[089]" | uri=~"sip:00900.*" ) {
296
+					sl_send_reply("403", "Added Value Destinations not permitted...");
297
+					break;
298
+				};
299
+				if (!is_in_group("ld")) {
300
+					sl_send_reply("403", "LD Toodle Noodle...");
301
+					break;
302
+				};
303
+			# the same for international calls
304
+			} else if (uri=~"sip:000[1-9][0-9]+@.*") {
305
+				if (!is_in_group("int")) {
306
+					sl_send_reply("403", "International Toodle Noodle...");
307
+					break;
308
+				};
309
+			# everything else (e.g., interplanetary calls) is denied
310
+			} else {
311
+				sl_send_reply("403", "interplanetary Toodle Noodle...");
312
+				break;
313
+			};
314
+
315
+		}; # INVITE to authorized PSTN
316
+
317
+	}; # authorized PSTN
318
+
319
+	# requests to gateway must be record-route because the GW accepts
320
+	# only reqeusts coming from our proxy
321
+	if (method=="INVITE")
322
+		addRecordRoute();
323
+
324
+	# if you have passed through all the checks, let your call go to GW!
325
+	rewritehostport("195.37.77.110:5060");
326
+
327
+	# tag this transaction for accounting
328
+	setflag(1);
329
+
330
+	t_relay();
331
+}
234 332
new file mode 100644
... ...
@@ -0,0 +1,112 @@
1
+/*
2
+ * $Id$
3
+ */
4
+
5
+#include <limits.h>
6
+#include "sr_module.h"
7
+#include "dprint.h"
8
+#include "parser/msg_parser.h"
9
+#include "flags.h"
10
+#include "error.h"
11
+#include "stdlib.h"
12
+
13
+int setflag( struct sip_msg* msg, flag_t flag ) {
14
+	msg->flags |= 1 << flag;
15
+	return 1;
16
+}
17
+
18
+int resetflag( struct sip_msg* msg, flag_t flag ) {
19
+	msg->flags &= ~ flag;
20
+	return 1;
21
+}
22
+
23
+int isflagset( struct sip_msg* msg, flag_t flag ) {
24
+	return msg->flags & (1<<flag) ? 1 : -1;
25
+}
26
+
27
+int flag_in_range( flag_t flag ) {
28
+	if (flag > MAX_FLAG ) {
29
+		LOG(L_ERR, "ERROR: message flag %d too high; MAX=%d\n",
30
+			flag, MAX_FLAG );
31
+		return 0;
32
+	}
33
+	if (flag<=0) {
34
+		LOG(L_ERR, "ERROR: message flag (%d) must be in range %d..%d\n",
35
+			flag, 1, MAX_FLAG );
36
+		return 0;
37
+	}
38
+	return 1;
39
+}
40
+
41
+
42
+#ifdef _GET_AWAY
43
+
44
+/* wrapping functions for flag processing  */
45
+static int fixup_t_flag(void** param, int param_no)
46
+{
47
+    unsigned int *code;
48
+	char *c;
49
+	int token;
50
+
51
+	DBG("DEBUG: fixing flag: %s\n", (char *) (*param));
52
+
53
+	if (param_no!=1) {
54
+		LOG(L_ERR, "ERROR: TM module: only parameter #1 for flags can be fixed\n");
55
+		return E_BUG;
56
+	};
57
+
58
+	if ( !(code = malloc( sizeof( unsigned int) )) ) return E_OUT_OF_MEM;
59
+
60
+	*code = 0;
61
+	c = *param;
62
+	while ( *c && (*c==' ' || *c=='\t')) c++; /* intial whitespaces */
63
+
64
+	token=1;
65
+	if (strcasecmp(c, "white")==0) *code=FL_WHITE;
66
+	else if (strcasecmp(c, "yellow")==0) *code=FL_YELLOW;
67
+	else if (strcasecmp(c, "green")==0) *code=FL_GREEN;
68
+	else if (strcasecmp(c, "red")==0) *code=FL_RED;
69
+	else if (strcasecmp(c, "blue")==0) *code=FL_BLUE;
70
+	else if (strcasecmp(c, "magenta")==0) *code=FL_MAGENTA;
71
+	else if (strcasecmp(c, "brown")==0) *code=FL_BROWN;
72
+	else if (strcasecmp(c, "black")==0) *code=FL_BLACK;
73
+	else if (strcasecmp(c, "acc")==0) *code=FL_ACC;
74
+	else {
75
+		token=0;
76
+		while ( *c && *c>='0' && *c<='9' ) {
77
+			*code = *code*10+ *c-'0';
78
+			if (*code > (sizeof( flag_t ) * CHAR_BIT - 1 )) {
79
+				LOG(L_ERR, "ERROR: TM module: too big flag number: %s; MAX=%d\n",
80
+					(char *) (*param), sizeof( flag_t ) * CHAR_BIT - 1 );
81
+				goto error;
82
+			}
83
+			c++;
84
+		}
85
+	}
86
+	while ( *c && (*c==' ' || *c=='\t')) c++; /* terminating whitespaces */
87
+
88
+	if ( *code == 0 ) {
89
+		LOG(L_ERR, "ERROR: TM module: bad flag number: %s\n", (char *) (*param));
90
+		goto error;
91
+	}
92
+
93
+	if (*code < FL_MAX && token==0) {
94
+		LOG(L_ERR, "ERROR: TM module: too high flag number: %s (%d)\n; lower number"
95
+			" bellow %d reserved\n", (char *) (*param), *code, FL_MAX );
96
+		goto error;
97
+	}
98
+
99
+	/* free string */
100
+	free( *param );
101
+	/* fix now */
102
+	*param = code;
103
+	
104
+	return 0;
105
+
106
+error:
107
+	free( code );
108
+	return E_CFG;
109
+}
110
+
111
+
112
+#endif
0 113
new file mode 100644
... ...
@@ -0,0 +1,24 @@
1
+/*
2
+ * $Id$
3
+ */
4
+
5
+
6
+#ifndef _FLAGS_H
7
+#define _FLAGS_H
8
+
9
+enum { FL_WHITE=1, FL_YELLOW, FL_GREEN, FL_RED, FL_BLUE, FL_MAGENTA,
10
+	   FL_BROWN, FL_BLACK, FL_ACC, FL_MAX };
11
+
12
+typedef unsigned long flag_t;
13
+
14
+#define MAX_FLAG  ( sizeof(flag_t) * CHAR_BIT - 1 )
15
+
16
+struct sip_msg;
17
+
18
+int setflag( struct sip_msg* msg, flag_t flag );
19
+int resetflag( struct sip_msg* msg, flag_t flag );
20
+int isflagset( struct sip_msg* msg, flag_t flag );
21
+
22
+int flag_in_range( flag_t flag );
23
+
24
+#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 0
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 322
 #endif
325 323
 		return;
326 324
 	}
327
-	timeout = to_table[ list_id ];
325
+	timeout = timer_id2timeout[ list_id ];
328 326
 	list= &(hash_table->timers[ list_id ]);
329 327
 
330 328
 	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 174
 			get_ticks() );
173 175
 		/*sets and starts the FINAL RESPONSE timer */
174 176
 		set_timer( hash_table, &(T->uac[branch].request.fr_timer),
175
-			FR_TIMER_LIST );
177
+			/* p_msg->REQ_METHOD==METHOD_INVITE ? FR_INV_TIMER_LIST : FR_TIMER_LIST ); */
178
+			FR_TIMER_LIST ); 
176 179
 		/* sets and starts the RETRANS timer */
177 180
 		T->uac[branch].request.retr_list = RT_T1_TO_1;
178 181
 		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 272
 
270 273
 	T->uas.isACKed = 1;
271 274
 	SEND_PR_BUFFER( &(T->uac[branch].request), ack, len );
275
+	callback_event( TMCB_E2EACK, p_msg );
272 276
 	return attach_ack( T, branch, ack , len );
273 277
 
274 278
 #ifdef _DON_USE
... ...
@@ -354,7 +358,9 @@ int forward_serial_branch(struct cell* Trans,int branch)
354 358
 	DBG("DEBUG: t_forward_serial_branch:starting timers (retrans and FR) %d\n",
355 359
 		get_ticks() );
356 360
 	/*sets and starts the FINAL RESPONSE timer */
357
-	set_timer( hash_table, &(T->uac[branch].request.fr_timer), FR_TIMER_LIST );
361
+	set_timer( hash_table, &(T->uac[branch].request.fr_timer), 
362
+			FR_TIMER_LIST ); 
363
+			/* p_msg->REQ_METHOD==METHOD_INVITE ? FR_INV_TIMER_LIST : FR_TIMER_LIST ); */
358 364
 	/* sets and starts the RETRANS timer */
359 365
 	T->uac[branch].request.retr_list = RT_T1_TO_1;
360 366
 	set_timer( hash_table, &(T->uac[branch].request.retr_timer), RT_T1_TO_1 );
361 367
new file mode 100644
... ...
@@ -0,0 +1,47 @@
1
+/*
2
+ * $Id$
3
+ */
4
+
5
+
6
+#include "t_hooks.h"
7
+
8
+static struct tm_callback_s* callback_array[ TMCB_END ] = { NULL, NULL } ;
9
+static int callback_id=0;
10
+
11
+/* register a callback function 'f' of type 'cbt'; will be called
12
+   back whenever the event 'cbt' occurs in transaction module
13
+*/
14
+int register_tmcb( tmcb_type cbt, transaction_cb f )
15
+{
16
+	struct tm_callback_s *cbs;
17
+
18
+	if (cbt<0 || cbt>=TMCB_END ) {
19
+		LOG(L_ERR, "ERROR: register_tmcb: invalid callback type: %d\n",
20
+			cbt );
21
+		return E_BUG;
22
+	}
23
+
24
+	if (!(cbs=malloc( sizeof( struct tm_callback_s)))) {
25
+		LOG(L_ERR, "ERROR: register_tmcb: out of mem\n");
26
+		return E_OUT_OF_MEM;
27
+	}
28
+
29
+	callback_id++;
30
+	cbs->id=callback_id;
31
+	cbs->callback=f;
32
+	cbs->next=callback_array[ cbt ];
33
+	callback_array[ cbt ]=cbs;
34
+
35
+	return callback_id;
36
+}
37
+
38
+void callback_event( tmcb_type cbt , struct sip_msg *msg )
39
+{
40
+	struct tm_callback_s *cbs;
41
+
42
+	DBG("DBG: callback type %d entered\n", cbt );
43
+	for (cbs=callback_array[ cbt ]; cbs; cbs=cbs->next)  {
44
+		DBG("DBG: callback id %d entered\n", cbs->id );
45
+		cbs->callback( T, msg );
46
+	}
47
+}
0 48
new file mode 100644
... ...
@@ -0,0 +1,29 @@
1
+/*
2
+ * $Id$
3
+ */
4
+
5
+#ifndef _HOOKS_H
6
+#define _HOOKS_H
7
+
8
+#include "h_table.h"
9
+#include "t_funcs.h"
10
+
11
+typedef enum { TMCB_REPLY,  TMCB_E2EACK, TMCB_END } tmcb_type;
12
+
13
+typedef void (transaction_cb) ( struct cell* t, struct sip_msg* msg );
14
+
15
+struct tm_callback_s {
16
+	int id;
17
+	transaction_cb* callback;
18
+	struct tm_callback_s* next;
19
+};
20
+
21
+
22
+extern struct tm_callback_s* callback_array[ TMCB_END ];
23
+
24
+typedef int (*register_tmcb_f)(tmcb_type cbt, transaction_cb f);
25
+
26
+int register_tmcb( tmcb_type cbt, transaction_cb f );
27
+void callback_event( tmcb_type cbt, struct sip_msg *msg );
28
+
29
+#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 608
 		}
605 609
 	} else {
606 610
 		if (T)
607
-			LOG(L_ERR, "ERROR: t_check_new_request: already "
611
+			LOG(L_ERR, "ERROR: t_addifnew: already "
608 612
 			"processing this message, T found!\n");
609 613
 		else
610 614
 			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 40
 	int len;
39 41
 
40 42
 	if (!T->uas.response.buffer)
41
-		return 0;
43
+		return -1;
42 44
 
43 45
 	if ( (len=T->uas.response.buffer_len)==0 || len>BUF_SIZE ) {
44 46
 		UNLOCK_REPLIES( T );
45
-		return -1;
47
+		return -2;
46 48
 	}
47 49
 	memcpy( b, T->uas.response.buffer, len );
48 50
 	UNLOCK_REPLIES( T );
... ...
@@ -370,6 +372,7 @@ int t_on_reply( struct sip_msg  *p_msg )
370 372
 	if (relay >= 0) {
371 373
 		SEND_PR_BUFFER( rb, buf, res_len );
372 374
 		t_update_timers_after_sending_reply( rb );
375
+		callback_event( TMCB_REPLY, p_msg );
373 376
 	}
374 377
 
375 378
 	/* *** ACK handling *** */
... ...
@@ -378,6 +381,7 @@ int t_on_reply( struct sip_msg  *p_msg )
378 381
 		{   /*retransmit*/
379 382
 			/* I don't need any additional syncing here -- after ack
380 383
 			   is introduced it's never changed */
384
+			DBG("DEBUG: localy cached ACK retranmitted\n");
381 385
 			SEND_ACK_BUFFER( &(T->uac[branch].request) );
382 386
 		} else if (msg_class>2 ) {
383 387
 			/*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 41
 static int w_t_clear_forks(struct sip_msg* msg, char* str, char* str2);
40 42
 static void w_onbreak(struct sip_msg* msg) { t_unref(); }
41 43
 
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 44
 static int mod_init(void);
48 45
 
49 46
 #ifdef STATIC_TM
... ...
@@ -51,7 +48,8 @@ struct module_exports tm_exports = {
51 48
 #else
52 49
 struct module_exports exports= {
53 50
 #endif
54
-	"tm_module",
51
+	"tm",
52
+	/* -------- exported functions ----------- */
55 53
 	(char*[]){			
56 54
 				"t_add_transaction",
57 55
 				"t_lookup_request",
... ...
@@ -67,9 +65,8 @@ struct module_exports exports= {
67 65
 				"t_fork_to_uri",
68 66
 				"t_clear_forks",
69 67
 				"t_fork_on_no_response",
70
-				"t_setflag",
71
-				"t_resetflag",
72
-				"t_isflagset"
68
+				"register_tmcb",
69
+				"load_tm"
73 70
 			},
74 71
 	(cmd_function[]){