91efd5c7d6e164d00e4f77a8cc2a8be236b66ae3
[sip-router] / modules / tm / tm.c
1 /*
2  * $Id$
3  *
4  * TM module
5  *
6  *
7  * ***************************************************
8  * * Jiri's Source Memorial                          *
9  * *                                                 *
10  * * Welcome, pilgrim ! This is the greatest place   *
11  * * where dramatic changes happend. There are not   *
12  * * many places with a history like this, as there  *
13  * * are not so many people like Jiri, one of the    *
14  * * ser's fathers, who brought everywhere the wind  *
15  * * of change, the flood of clean-up. We all felt   *
16  * * his fatherly eye watching over us day and night.*
17  * *                                                 *
18  * * Please, preserve this codework heritage, as     *
19  * * it's unlikely for fresh, juicy pieces of code to  *
20  * * arise to give him the again the chance to       *
21  * * demonstrate his clean-up and improvement skills.*
22  * *                                                 *
23  * * Hereby, we solicit you to adopt this historical *
24  * * piece of code. For $100, your name will be      *
25  * * be printed in this banner and we will use       *
26  * * collected funds to create and display an ASCII  *
27  * * statue of Jiri  .                               *
28  * ***************************************************
29  *
30  *
31  * Copyright (C) 2001-2003 FhG Fokus
32  *
33  * This file is part of ser, a free SIP server.
34  *
35  * ser is free software; you can redistribute it and/or modify
36  * it under the terms of the GNU General Public License as published by
37  * the Free Software Foundation; either version 2 of the License, or
38  * (at your option) any later version
39  *
40  * For a license to use the ser software under conditions
41  * other than those described here, or to purchase support for this
42  * software, please contact iptel.org by e-mail at the following addresses:
43  *    info@iptel.org
44  *
45  * ser is distributed in the hope that it will be useful,
46  * but WITHOUT ANY WARRANTY; without even the implied warranty of
47  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48  * GNU General Public License for more details.
49  *
50  * You should have received a copy of the GNU General Public License
51  * along with this program; if not, write to the Free Software
52  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
53  */
54 /*
55  * History:
56  * --------
57  *  2003-02-18  added t_forward_nonack_{udp, tcp}, t_relay_to_{udp,tcp},
58  *               t_replicate_{udp, tcp} (andrei)
59  *  2003-02-19  added t_rely_{udp, tcp} (andrei)
60  *  2003-03-06  voicemail changes accepted (jiri)
61  *  2003-03-10  module export interface updated to the new format (andrei)
62  *  2003-03-16  flags export parameter added (janakj)
63  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
64  *  2003-03-30  set_kr for requests only (jiri)
65  *  2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
66  *  2003-04-14  use protocol from uri (jiri)
67  *  2003-07-07  added t_relay_to_tls, t_replicate_tls, t_forward_nonack_tls
68  *              added #ifdef USE_TCP, USE_TLS
69  *              removed t_relay_{udp,tcp,tls} (andrei)
70  *  2003-09-26  added t_forward_nonack_uri() - same as t_forward_nonack() but
71  *              takes no parameters -> forwards to uri (bogdan)
72  *  2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
73  *  2004-02-18  t_reply exported via FIFO - imported from VM (bogdan)
74  *  2004-10-01  added a new param.: restart_fr_on_each_reply (andrei)
75  *  2005-11-14  new timer support, changed timer related module params (andrei)
76  *  2005-12-09  fixup_hostport2proxy uses route_struct to access param #1
77  *              when fixing param #2
78  *  2005-12-09  added t_set_fr() (andrei)
79  *  2006-02-07  named routes support (andrei)
80  *  2006-09-28  added t_branch_replied, t_branch_timeout, t_any_replied, 
81  *               t_any_timeout, t_is_canceled (andrei)
82  *  2006-10-16  added a new param.: aggregate challenges (andrei)
83  *  2007-05-28  two new params: reparse_invite, ac_extra_hdrs
84  *              added w_t_relay_cancel() (Miklos)
85  */
86
87
88 #include "defs.h"
89
90
91 #include <stdio.h>
92 #include <string.h>
93 #include <netdb.h>
94
95 #include "../../sr_module.h"
96 #include "../../dprint.h"
97 #include "../../error.h"
98 #include "../../ut.h"
99 #include "../../script_cb.h"
100 #include "../../usr_avp.h"
101 #include "../../mem/mem.h"
102 #include "../../route_struct.h"
103 #include "../../route.h"
104
105 #include "sip_msg.h"
106 #include "h_table.h"
107 #include "t_hooks.h"
108 #include "tm_load.h"
109 #include "ut.h"
110 #include "t_reply.h"
111 #include "uac.h"
112 #include "t_fwd.h"
113 #include "t_lookup.h"
114 #include "t_stats.h"
115 #include "callid.h"
116 #include "t_cancel.h"
117 #include "t_fifo.h"
118 #include "timer.h"
119 #include "t_msgbuilder.h"
120 #include "select.h"
121
122 MODULE_VERSION
123
124 /* fixup functions */
125 static int fixup_hostport2proxy(void** param, int param_no);
126 static int fixup_proto_hostport2proxy(void** param, int param_no);
127 static int fixup_on_failure(void** param, int param_no);
128 static int fixup_on_reply(void** param, int param_no);
129 static int fixup_on_branch(void** param, int param_no);
130 static int fixup_t_reply(void** param, int param_no);
131
132
133 /* init functions */
134 static int mod_init(void);
135 static int child_init(int rank);
136
137
138 /* exported functions */
139 inline static int w_t_check(struct sip_msg* msg, char* str, char* str2);
140 inline static int w_t_lookup_cancel(struct sip_msg* msg, char* str, char* str2);
141 inline static int w_t_reply(struct sip_msg* msg, char* str, char* str2);
142 inline static int w_t_release(struct sip_msg* msg, char* str, char* str2);
143 inline static int w_t_retransmit_reply(struct sip_msg* p_msg, char* foo,
144                                 char* bar );
145 inline static int w_t_newtran(struct sip_msg* p_msg, char* foo, char* bar );
146 inline static int w_t_relay( struct sip_msg  *p_msg , char *_foo, char *_bar);
147 inline static int w_t_relay_to_udp( struct sip_msg  *p_msg , char *proxy,
148                                  char *);
149 #ifdef USE_TCP
150 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg , char *proxy,
151                                 char *);
152 #endif
153 #ifdef USE_TLS
154 inline static int w_t_relay_to_tls( struct sip_msg  *p_msg , char *proxy,
155                                 char *);
156 #endif
157 inline static int w_t_relay_to(struct sip_msg* msg, char* str,char*);
158 inline static int w_t_replicate( struct sip_msg  *p_msg ,
159                                 char *proxy, /* struct proxy_l *proxy expected */
160                                 char *_foo       /* nothing expected */ );
161 inline static int w_t_replicate_udp( struct sip_msg  *p_msg ,
162                                 char *proxy, /* struct proxy_l *proxy expected */
163                                 char *_foo       /* nothing expected */ );
164 #ifdef USE_TCP
165 inline static int w_t_replicate_tcp( struct sip_msg  *p_msg ,
166                                 char *proxy, /* struct proxy_l *proxy expected */
167                                 char *_foo       /* nothing expected */ );
168 #endif
169 #ifdef USE_TLS
170 inline static int w_t_replicate_tls( struct sip_msg  *p_msg ,
171                                 char *proxy, /* struct proxy_l *proxy expected */
172                                 char *_foo       /* nothing expected */ );
173 #endif
174 inline static int w_t_replicate_to(struct sip_msg* msg, char* str,char*);
175 inline static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* );
176 inline static int w_t_forward_nonack_uri(struct sip_msg* msg, char* str,char*);
177 inline static int w_t_forward_nonack_udp(struct sip_msg* msg, char* str,char*);
178 #ifdef USE_TCP
179 inline static int w_t_forward_nonack_tcp(struct sip_msg* msg, char* str,char*);
180 #endif
181 #ifdef USE_TLS
182 inline static int w_t_forward_nonack_tls(struct sip_msg* msg, char* str,char*);
183 #endif
184 inline static int w_t_forward_nonack_to(struct sip_msg* msg, char* str,char*);
185 inline static int w_t_relay_cancel(struct sip_msg *p_msg, char *_foo, char *_bar);
186 inline static int w_t_on_negative(struct sip_msg* msg, char *go_to, char *foo);
187 inline static int w_t_on_branch(struct sip_msg* msg, char *go_to, char *foo);
188 inline static int w_t_on_reply(struct sip_msg* msg, char *go_to, char *foo );
189 inline static int t_check_status(struct sip_msg* msg, char *regexp, char *foo);
190 static int t_set_fr_inv(struct sip_msg* msg, char* fr_inv, char* foo);
191 static int t_set_fr_all(struct sip_msg* msg, char* fr_inv, char* fr);
192 static int w_t_set_retr(struct sip_msg* msg, char* retr_t1, char* retr_t2);
193 static int w_t_set_max_lifetime(struct sip_msg* msg, char* inv, char* noninv);
194 static int t_branch_timeout(struct sip_msg* msg, char*, char*);
195 static int t_branch_replied(struct sip_msg* msg, char*, char*);
196 static int t_any_timeout(struct sip_msg* msg, char*, char*);
197 static int t_any_replied(struct sip_msg* msg, char*, char*);
198 static int t_is_canceled(struct sip_msg* msg, char*, char*);
199
200
201 /* by default the fr timers avps are not set, so that the avps won't be
202  * searched for nothing each time a new transaction is created */
203 static char *fr_timer_param = 0 /*FR_TIMER_AVP*/;
204 static char *fr_inv_timer_param = 0 /*FR_INV_TIMER_AVP*/;
205
206 static rpc_export_t tm_rpc[];
207
208 static int default_code = 500;
209 static str default_reason = STR_STATIC_INIT("Server Internal Error");
210
211
212 static cmd_export_t cmds[]={
213         {"t_newtran",          w_t_newtran,             0, 0,
214                         REQUEST_ROUTE},
215         {"t_lookup_request",   w_t_check,               0, 0,
216                         REQUEST_ROUTE},
217         {"t_lookup_cancel",    w_t_lookup_cancel,     0, 0,
218                         REQUEST_ROUTE},
219         {T_REPLY,              w_t_reply,               2, fixup_t_reply,
220                         REQUEST_ROUTE | FAILURE_ROUTE },
221         {"t_retransmit_reply", w_t_retransmit_reply,    0, 0,
222                         REQUEST_ROUTE},
223         {"t_release",          w_t_release,             0, 0,
224                         REQUEST_ROUTE},
225         {T_RELAY_TO_UDP,       w_t_relay_to_udp,        2, fixup_hostport2proxy,
226                         REQUEST_ROUTE|FAILURE_ROUTE},
227 #ifdef USE_TCP
228         {T_RELAY_TO_TCP,       w_t_relay_to_tcp,        2, fixup_hostport2proxy,
229                         REQUEST_ROUTE|FAILURE_ROUTE},
230 #endif
231 #ifdef USE_TLS
232         {T_RELAY_TO_TLS,       w_t_relay_to_tls,        2, fixup_hostport2proxy,
233                         REQUEST_ROUTE|FAILURE_ROUTE},
234 #endif
235         {"t_replicate",        w_t_replicate,           2, fixup_hostport2proxy,
236                         REQUEST_ROUTE},
237         {"t_replicate_udp",    w_t_replicate_udp,       2, fixup_hostport2proxy,
238                         REQUEST_ROUTE},
239 #ifdef USE_TCP
240         {"t_replicate_tcp",    w_t_replicate_tcp,       2, fixup_hostport2proxy,
241                         REQUEST_ROUTE},
242 #endif
243 #ifdef USE_TLS
244         {"t_replicate_tls",    w_t_replicate_tls,       2, fixup_hostport2proxy,
245                         REQUEST_ROUTE},
246 #endif
247         {"t_replicate_to", w_t_replicate_to,            2, fixup_proto_hostport2proxy,
248                         REQUEST_ROUTE},
249         {T_RELAY,              w_t_relay,               0, 0,
250                         REQUEST_ROUTE | FAILURE_ROUTE },
251         {"t_relay_to", w_t_relay_to,                    2, fixup_proto_hostport2proxy,
252                         REQUEST_ROUTE},
253         {T_FORWARD_NONACK,     w_t_forward_nonack,      2, fixup_hostport2proxy,
254                         REQUEST_ROUTE},
255         {T_FORWARD_NONACK_URI, w_t_forward_nonack_uri,  0, 0,
256                         REQUEST_ROUTE},
257         {T_FORWARD_NONACK_UDP, w_t_forward_nonack_udp,  2, fixup_hostport2proxy,
258                         REQUEST_ROUTE},
259 #ifdef USE_TCP
260         {T_FORWARD_NONACK_TCP, w_t_forward_nonack_tcp,  2, fixup_hostport2proxy,
261                         REQUEST_ROUTE},
262 #endif
263 #ifdef USE_TLS
264         {T_FORWARD_NONACK_TLS, w_t_forward_nonack_tls,  2, fixup_hostport2proxy,
265                         REQUEST_ROUTE},
266 #endif
267         {"t_forward_nonack_to", w_t_forward_nonack_to,  2, fixup_proto_hostport2proxy,
268                         REQUEST_ROUTE},
269         {"t_relay_cancel",     w_t_relay_cancel,        0, 0,
270                         REQUEST_ROUTE},
271         {"t_on_failure",       w_t_on_negative,         1, fixup_on_failure,
272                         REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE },
273         {"t_on_reply",         w_t_on_reply,            1, fixup_on_reply,
274                         REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE },
275         {"t_on_branch",       w_t_on_branch,         1, fixup_on_branch,
276                         REQUEST_ROUTE | FAILURE_ROUTE },
277         {"t_check_status",     t_check_status,          1, fixup_regex_1,
278                         REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE },
279         {"t_write_req",       t_write_req,              2, fixup_t_write,
280                         REQUEST_ROUTE | FAILURE_ROUTE },
281         {"t_write_unix",      t_write_unix,             2, fixup_t_write,
282                         REQUEST_ROUTE | FAILURE_ROUTE },
283         {"t_set_fr",          t_set_fr_inv,             1, fixup_var_int_1,
284                         REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
285         {"t_set_fr",          t_set_fr_all,             2, fixup_var_int_12,
286                         REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
287         {"t_set_retr",        w_t_set_retr,               2, fixup_var_int_12,
288                         REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
289         {"t_set_max_lifetime", w_t_set_max_lifetime,      2, fixup_var_int_12,
290                         REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
291         {"t_branch_timeout",  t_branch_timeout,         0, 0,  FAILURE_ROUTE},
292         {"t_branch_replied",  t_branch_replied,         0, 0,  FAILURE_ROUTE},
293         {"t_any_timeout",     t_any_timeout,            0, 0, 
294                         REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
295         {"t_any_replied",     t_any_replied,            0, 0, 
296                         REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
297         {"t_is_canceled",     t_is_canceled,            0, 0,
298                         REQUEST_ROUTE|ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
299
300         /* not applicable from the script */
301         {"register_tmcb",      (cmd_function)register_tmcb,     NO_SCRIPT,   0, 0},
302         {"load_tm",            (cmd_function)load_tm,           NO_SCRIPT,   0, 0},
303         {T_REPLY_WB,           (cmd_function)t_reply_with_body, NO_SCRIPT,   0, 0},
304         {T_IS_LOCAL,           (cmd_function)t_is_local,        NO_SCRIPT,   0, 0},
305         {T_GET_TI,             (cmd_function)t_get_trans_ident, NO_SCRIPT,   0, 0},
306         {T_LOOKUP_IDENT,       (cmd_function)t_lookup_ident,    NO_SCRIPT,   0, 0},
307         {T_ADDBLIND,           (cmd_function)add_blind_uac,     NO_SCRIPT,   0, 0},
308         {"t_request_within",   (cmd_function)req_within,        NO_SCRIPT,   0, 0},
309         {"t_request_outside",  (cmd_function)req_outside,       NO_SCRIPT,   0, 0},
310         {"t_request",          (cmd_function)request,           NO_SCRIPT,   0, 0},
311         {"new_dlg_uac",        (cmd_function)new_dlg_uac,       NO_SCRIPT,   0, 0},
312         {"dlg_response_uac",   (cmd_function)dlg_response_uac,  NO_SCRIPT,   0, 0},
313         {"new_dlg_uas",        (cmd_function)new_dlg_uas,       NO_SCRIPT,   0, 0},
314         {"update_dlg_uas",     (cmd_function)update_dlg_uas,    NO_SCRIPT,   0, 0},
315         {"dlg_request_uas",    (cmd_function)dlg_request_uas,   NO_SCRIPT,   0, 0},
316         {"set_dlg_target",     (cmd_function)set_dlg_target,    NO_SCRIPT,   0, 0},
317         {"free_dlg",           (cmd_function)free_dlg,          NO_SCRIPT,   0, 0},
318         {"print_dlg",          (cmd_function)print_dlg,         NO_SCRIPT,   0, 0},
319         {T_GETT,               (cmd_function)get_t,             NO_SCRIPT,   0, 0},
320         {"calculate_hooks",    (cmd_function)w_calculate_hooks, NO_SCRIPT,   0, 0},
321         {"t_uac",              (cmd_function)t_uac,             NO_SCRIPT,   0, 0},
322         {"t_uac_with_ids",     (cmd_function)t_uac_with_ids,    NO_SCRIPT,   0, 0},
323         {"t_unref",            (cmd_function)t_unref,           NO_SCRIPT,   0, 0},
324         {"run_failure_handlers", (cmd_function)run_failure_handlers, NO_SCRIPT,   0, 0},
325         {"cancel_uacs",        (cmd_function)cancel_uacs,       NO_SCRIPT,   0, 0},
326         {0,0,0,0,0}
327 };
328
329
330 static param_export_t params[]={
331         {"ruri_matching",       PARAM_INT, &ruri_matching                        },
332         {"via1_matching",       PARAM_INT, &via1_matching                        },
333         {"fr_timer",            PARAM_INT, &fr_timeout                           },
334         {"fr_inv_timer",        PARAM_INT, &fr_inv_timeout                       },
335         {"wt_timer",            PARAM_INT, &wait_timeout                         },
336         {"delete_timer",        PARAM_INT, &delete_timeout                       },
337         {"retr_timer1",         PARAM_INT, &rt_t1_timeout                        },
338         {"retr_timer2"  ,       PARAM_INT, &rt_t2_timeout                        },
339         {"max_inv_lifetime",    PARAM_INT, &tm_max_inv_lifetime                  },
340         {"max_noninv_lifetime", PARAM_INT, &tm_max_noninv_lifetime               },
341         {"noisy_ctimer",        PARAM_INT, &noisy_ctimer                         },
342         {"uac_from",            PARAM_STRING, &uac_from                          },
343         {"unix_tx_timeout",     PARAM_INT, &tm_unix_tx_timeout                   },
344         {"restart_fr_on_each_reply", PARAM_INT, &restart_fr_on_each_reply        },
345         {"fr_timer_avp",        PARAM_STRING, &fr_timer_param                    },
346         {"fr_inv_timer_avp",    PARAM_STRING, &fr_inv_timer_param                },
347         {"tw_append",           PARAM_STRING|PARAM_USE_FUNC, 
348                                                                                                         (void*)parse_tw_append   },
349         {"pass_provisional_replies", PARAM_INT, &pass_provisional_replies        },
350         {"aggregate_challenges", PARAM_INT, &tm_aggregate_auth                   },
351         {"unmatched_cancel",    PARAM_INT, &unmatched_cancel                     },
352         {"default_code",        PARAM_INT, &default_code                         },
353         {"default_reason",      PARAM_STR, &default_reason                       },
354         {"reparse_invite",      PARAM_INT, &reparse_invite                       },
355         {"ac_extra_hdrs",       PARAM_STR, &ac_extra_hdrs                        },
356         {0,0,0}
357 };
358
359 #ifdef STATIC_TM
360 struct module_exports tm_exports = {
361 #else
362 struct module_exports exports= {
363 #endif
364         "tm",
365         /* -------- exported functions ----------- */
366         cmds,
367         tm_rpc,    /* RPC methods */
368         /* ------------ exported variables ---------- */
369         params,
370
371         mod_init, /* module initialization function */
372         (response_function) reply_received,
373         (destroy_function) tm_shutdown,
374         0, /* w_onbreak, */
375         child_init /* per-child init function */
376 };
377
378
379
380 /* helper for fixup_on_* */
381 static int fixup_routes(char* r_type, struct route_list* rt, void** param)
382 {
383         int i;
384         
385         i=route_get(rt, (char*)*param);
386         if (i==-1){
387                 LOG(L_ERR, "ERROR: tm: fixup_routes: route_get failed\n");
388                 return E_UNSPEC;
389         }
390         if (rt->rlist[i]==0){
391                 LOG(L_WARN, "WARNING: %s(\"%s\"): empty/non existing route\n",
392                                 r_type, (char*)*param);
393         }
394         *param=(void*)(long)i;
395         return 0;
396 }
397
398 static int fixup_t_reply(void** param, int param_no)
399 {
400         int ret;
401
402         if (param_no == 1) {
403                 ret = fix_param(FPARAM_AVP, param);
404                 if (ret <= 0) return ret;
405                 return fix_param(FPARAM_INT, param);
406         } else if (param_no == 2) {
407                 return fixup_var_str_12(param, 2);
408         }
409     return 0;
410 }
411
412 static int fixup_on_failure(void** param, int param_no)
413 {
414         if (param_no==1){
415                 return fixup_routes("t_on_failure", &failure_rt, param);
416         }
417         return 0;
418 }
419
420
421
422 static int fixup_on_reply(void** param, int param_no)
423 {
424         if (param_no==1){
425                 return fixup_routes("t_on_reply", &onreply_rt, param);
426         }
427         return 0;
428 }
429
430
431
432 static int fixup_on_branch(void** param, int param_no)
433 {
434         if (param_no==1){
435                 return fixup_routes("t_on_branch", &branch_rt, param);
436         }
437         return 0;
438 }
439
440
441
442 /* (char *hostname, char *port_nr) ==> (struct proxy_l *, -)  */
443 static int fixup_hostport2proxy(void** param, int param_no)
444 {
445         unsigned int port;
446         char *host;
447         int err;
448         struct proxy_l *proxy;
449         action_u_t *a;
450         str s;
451
452         DBG("TM module: fixup_hostport2proxy(%s, %d)\n", (char*)*param, param_no);
453         if (param_no==1){
454                 return 0;
455         } else if (param_no==2) {
456                 a = fixup_get_param(param, param_no, 1);
457                 host= a->u.string;
458                 port=str2s(*param, strlen(*param), &err);
459                 if (err!=0) {
460                         LOG(L_ERR, "TM module:fixup_hostport2proxy: bad port number <%s>\n",
461                                 (char*)(*param));
462                          return E_UNSPEC;
463                 }
464                 s.s = host;
465                 s.len = strlen(host);
466                 proxy=mk_proxy(&s, port, 0); /* FIXME: udp or tcp? */
467                 if (proxy==0) {
468                         LOG(L_ERR, "ERROR: fixup_hostport2proxy: bad host name in URI <%s>\n",
469                                 host );
470                         return E_BAD_ADDRESS;
471                 }
472                 /* success -- fix the first parameter to proxy now ! */
473
474                 a->u.data=proxy;
475                 return 0;
476         } else {
477                 LOG(L_ERR,"ERROR: fixup_hostport2proxy called with parameter #<>{1,2}\n");
478                 return E_BUG;
479         }
480 }
481
482 /* (char *$proto, char *$host:port) ==> (fparam, fparam)  */
483 static int fixup_proto_hostport2proxy(void** param, int param_no) {
484         int ret;
485
486         ret = fix_param(FPARAM_AVP, param);
487         if (ret <= 0) return ret;
488 /*      if (param_no = 1) {             FIXME: param_str currently does not offer INT/STR overloading
489                 ret = fix_param(FPARAM_INT, param);
490                 if (ret <= 0) return ret;
491         } */
492         return fix_param(FPARAM_STRING, param);
493 }
494
495
496 /***************************** init functions *****************************/
497 static int w_t_unref( struct sip_msg *foo, void *bar)
498 {
499         return t_unref(foo);
500 }
501
502
503 static int script_init( struct sip_msg *foo, void *bar)
504 {
505         /* we primarily reset all private memory here to make sure
506          * private values left over from previous message will
507          * not be used again */
508
509         /* make sure the new message will not inherit previous
510                 message's t_on_negative value
511         */
512         t_on_negative( 0 );
513         t_on_reply(0);
514         t_on_branch(0);
515         /* reset the kr status */
516         set_kr(0);
517         /* set request mode so that multiple-mode actions know
518          * how to behave */
519         rmode=MODE_REQUEST;
520         return 1;
521 }
522
523
524 static int mod_init(void)
525 {
526         DBG( "TM - (sizeof cell=%ld, sip_msg=%ld) initializing...\n",
527                         (long)sizeof(struct cell), (long)sizeof(struct sip_msg));
528         /* checking if we have sufficient bitmap capacity for given
529            maximum number of  branches */
530         if (MAX_BRANCHES+1>31) {
531                 LOG(L_CRIT, "Too many max UACs for UAC branch_bm_t bitmap: %d\n",
532                         MAX_BRANCHES );
533                 return -1;
534         }
535
536         if (init_callid() < 0) {
537                 LOG(L_CRIT, "Error while initializing Call-ID generator\n");
538                 return -1;
539         }
540
541         /* building the hash table*/
542         if (!init_hash_table()) {
543                 LOG(L_ERR, "ERROR: mod_init: initializing hash_table failed\n");
544                 return -1;
545         }
546
547         /* init static hidden values */
548         init_t();
549
550         if (tm_init_selects()==-1) {
551                 LOG(L_ERR, "ERROR: mod_init: select init failed\n");
552                 return -1;
553         }
554         
555         if (tm_init_timers()==-1) {
556                 LOG(L_ERR, "ERROR: mod_init: timer init failed\n");
557                 return -1;
558         }
559
560              /* First tm_stat initialization function only allocates the top level stat
561               * structure in shared memory, the initialization will complete in child
562               * init with init_tm_stats_child when the final value of estimated_process_count is
563               * known
564               */
565         if (init_tm_stats() < 0) {
566                 LOG(L_CRIT, "ERROR: mod_init: failed to init stats\n");
567                 return -1;
568         }
569
570         if (uac_init()==-1) {
571                 LOG(L_ERR, "ERROR: mod_init: uac_init failed\n");
572                 return -1;
573         }
574
575         if (init_tmcb_lists()!=1) {
576                 LOG(L_CRIT, "ERROR:tm:mod_init: failed to init tmcb lists\n");
577                 return -1;
578         }
579         
580         tm_init_tags();
581         init_twrite_lines();
582         if (init_twrite_sock() < 0) {
583                 LOG(L_ERR, "ERROR:tm:mod_init: Unable to create socket\n");
584                 return -1;
585         }
586
587         /* register post-script clean-up function */
588         if (register_script_cb( w_t_unref, POST_SCRIPT_CB|REQ_TYPE_CB, 0)<0 ) {
589                 LOG(L_ERR,"ERROR:tm:mod_init: failed to register POST request "
590                         "callback\n");
591                 return -1;
592         }
593         if (register_script_cb( script_init, PRE_SCRIPT_CB|REQ_TYPE_CB , 0)<0 ) {
594                 LOG(L_ERR,"ERROR:tm:mod_init: failed to register PRE request "
595                         "callback\n");
596                 return -1;
597         }
598
599         if (init_avp_params( fr_timer_param, fr_inv_timer_param)<0 ){
600                 LOG(L_ERR,"ERROR:tm:mod_init: failed to process timer AVPs\n");
601                 return -1;
602         }
603
604         tm_init = 1;
605         return 0;
606 }
607
608 static int child_init(int rank) {
609         if (child_init_callid(rank) < 0) {
610                 LOG(L_ERR, "ERROR: child_init: Error while initializing Call-ID generator\n");
611                 return -2;
612         }
613
614         if (rank == 1) {
615                 if (init_tm_stats_child() < 0) {
616                         ERR("Error while initializing tm statistics structures\n");
617                         return -1;
618                 }
619         }
620
621         return 0;
622 }
623
624
625
626
627
628 /**************************** wrapper functions ***************************/
629 static int t_check_status(struct sip_msg* msg, char *p1, char *foo)
630 {
631         regmatch_t pmatch;
632         struct cell *t;
633         char *status;
634         char backup;
635         int lowest_status;
636         int n;
637
638         /* first get the transaction */
639         if (t_check( msg , 0 )==-1) return -1;
640         if ( (t=get_t())==0) {
641                 LOG(L_ERR, "ERROR: t_check_status: cannot check status for a reply "
642                         "which has no T-state established\n");
643                 return -1;
644         }
645         backup = 0;
646
647         switch (rmode) {
648                 case MODE_REQUEST:
649                         /* use the status of the last sent reply */
650                         status = int2str( t->uas.status, 0);
651                         break;
652                 case MODE_ONREPLY:
653                         /* use the status of the current reply */
654                         status = msg->first_line.u.reply.status.s;
655                         backup = status[msg->first_line.u.reply.status.len];
656                         status[msg->first_line.u.reply.status.len] = 0;
657                         break;
658                 case MODE_ONFAILURE:
659                         /* use the status of the winning reply */
660                         if (t_pick_branch( -1, 0, t, &lowest_status)<0 ) {
661                                 LOG(L_CRIT,"BUG:t_check_status: t_pick_branch failed to get "
662                                         " a final response in MODE_ONFAILURE\n");
663                                 return -1;
664                         }
665                         status = int2str( lowest_status , 0);
666                         break;
667                 default:
668                         LOG(L_ERR,"ERROR:t_check_status: unsupported mode %d\n",rmode);
669                         return -1;
670         }
671
672         DBG("DEBUG:t_check_status: checked status is <%s>\n",status);
673         /* do the checking */
674         n = regexec(((fparam_t*)p1)->v.regex, status, 1, &pmatch, 0);
675
676         if (backup) status[msg->first_line.u.reply.status.len] = backup;
677         if (n!=0) return -1;
678         return 1;
679 }
680
681
682 inline static int w_t_check(struct sip_msg* msg, char* str, char* str2)
683 {
684         return t_check( msg , 0  ) ? 1 : -1;
685 }
686
687 inline static int w_t_lookup_cancel(struct sip_msg* msg, char* str, char* str2)
688 {
689         struct cell *ret;
690         if (msg->REQ_METHOD==METHOD_CANCEL) {
691                 ret = t_lookupOriginalT( msg );
692                 DBG("lookup_original: t_lookupOriginalT returned: %p\n", ret);
693                 if (ret != T_NULL_CELL) {
694                         /* The cell is reffed by t_lookupOriginalT, but T is not set.
695                         So we must unref it before returning. */
696                         UNREF(ret);
697                         set_t(T_UNDEFINED);
698                         return 1;
699                 }
700                 set_t(T_UNDEFINED);
701         } else {
702                 LOG(L_WARN, "WARNING: script error t_lookup_cancel() called for non-CANCEL request\n");
703         }
704         return -1;
705 }
706
707 inline static int str2proto(char *s, int len) {
708         if (len == 3 && !strncasecmp(s, "udp", 3))
709                 return PROTO_UDP;
710         else if (len == 3 && !strncasecmp(s, "tcp", 3))  /* tcp&tls checks will be passed in getproto() */
711                 return PROTO_TCP;
712         else if (len == 3 && !strncasecmp(s, "tls", 3))
713                 return PROTO_TLS;       
714         else
715                 return PROTO_NONE;
716 }
717
718 inline static struct proxy_l* t_protoaddr2proxy(char *proto_par, char *addr_par) {
719         struct proxy_l *proxy = 0;
720         avp_t* avp;
721         avp_value_t val;
722         int proto, port, err;
723         str s;
724         char *c;
725         
726         switch(((fparam_t *)proto_par)->type) {
727         case FPARAM_AVP:
728                 if (!(avp = search_first_avp(((fparam_t *)proto_par)->v.avp.flags, ((fparam_t *)proto_par)->v.avp.name, &val, 0))) {
729                         proto = PROTO_NONE;
730                 } else {
731                         if (avp->flags & AVP_VAL_STR) {
732                                 proto = str2proto(val.s.s, val.s.len);
733                         }
734                         else {
735                                 proto = val.n;
736                         }
737                 }
738                 break;
739
740         case FPARAM_INT:
741                 proto = ((fparam_t *)proto_par)->v.i;
742                 break;
743         case FPARAM_STRING:
744                 proto = str2proto( ((fparam_t *)proto_par)->v.asciiz, strlen(((fparam_t *)proto_par)->v.asciiz));
745                 break;
746         default:
747                 ERR("BUG: Invalid proto parameter value in t_protoaddr2proxy\n");
748                 return 0;
749         }
750
751
752         switch(((fparam_t *)addr_par)->type) {
753         case FPARAM_AVP:
754                 if (!(avp = search_first_avp(((fparam_t *)addr_par)->v.avp.flags, ((fparam_t *)addr_par)->v.avp.name, &val, 0))) {
755                         s.len = 0;
756                 } else {
757                         if ((avp->flags & AVP_VAL_STR) == 0) {
758                                 LOG(L_ERR, "tm:t_protoaddr2proxy: avp <%.*s> value is not string\n",
759                                         ((fparam_t *)addr_par)->v.avp.name.s.len, ((fparam_t *)addr_par)->v.avp.name.s.s);
760                                 return 0;
761                         }
762                         s = val.s;
763                 }
764                 break;
765
766         case FPARAM_STRING:
767                 s.s = ((fparam_t *) addr_par)->v.asciiz;
768                 s.len = strlen(s.s);
769                 break;
770
771         default:
772                 ERR("BUG: Invalid addr parameter value in t_protoaddr2proxy\n");
773                 return 0;
774         }
775
776         port = 5060;
777         if (s.len) {
778                 c = memchr(s.s, ':', s.len);
779                 if (c) {
780                         port = str2s(c+1, s.len-(c-s.s+1), &err);
781                         if (err!=0) {
782                                 LOG(L_ERR, "tm:t_protoaddr2proxy: bad port number <%.*s>\n",
783                                         s.len, s.s);
784                                  return 0;
785                         }
786                         s.len = c-s.s;
787                 }
788         }
789         if (!s.len) {
790                 LOG(L_ERR, "tm: protoaddr2proxy: host name is empty\n");
791                 return 0;
792         }
793         proxy=mk_proxy(&s, port, proto);
794         if (proxy==0) {
795                 LOG(L_ERR, "tm: protoaddr2proxy: bad host name in URI <%.*s>\n",
796                         s.len, s.s );
797                 return 0;
798         }
799         return proxy;
800 }
801
802 inline static int _w_t_forward_nonack(struct sip_msg* msg, struct proxy_l* proxy,
803         int proto)
804 {
805         struct cell *t;
806         if (t_check( msg , 0 )==-1) {
807                 LOG(L_ERR, "ERROR: forward_nonack: "
808                                 "can't forward when no transaction was set up\n");
809                 return -1;
810         }
811         t=get_t();
812         if ( t && t!=T_UNDEFINED ) {
813                 if (msg->REQ_METHOD==METHOD_ACK) {
814                         LOG(L_WARN,"WARNING: you don't really want to fwd hbh ACK\n");
815                         return -1;
816                 }
817                 return t_forward_nonack(t, msg, proxy, proto );
818         } else {
819                 DBG("DEBUG: forward_nonack: no transaction found\n");
820                 return -1;
821         }
822 }
823
824
825 inline static int w_t_forward_nonack( struct sip_msg* msg, char* proxy,
826                                                                                 char* foo)
827 {
828         return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_NONE);
829 }
830
831
832 inline static int w_t_forward_nonack_uri(struct sip_msg* msg, char *foo,
833                                                                                                                                         char *bar)
834 {
835         return _w_t_forward_nonack(msg, 0, PROTO_NONE);
836 }
837
838
839 inline static int w_t_forward_nonack_udp( struct sip_msg* msg, char* proxy,
840                                                                                 char* foo)
841 {
842         return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_UDP);
843 }
844
845
846 #ifdef USE_TCP
847 inline static int w_t_forward_nonack_tcp( struct sip_msg* msg, char* proxy,
848                                                                                 char* foo)
849 {
850         return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_TCP);
851 }
852 #endif
853
854
855 #ifdef USE_TLS
856 inline static int w_t_forward_nonack_tls( struct sip_msg* msg, char* proxy,
857                                                                                 char* foo)
858 {
859         return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_TLS);
860 }
861 #endif
862
863 inline static int w_t_forward_nonack_to( struct sip_msg  *p_msg ,
864         char *proto_par, 
865         char *addr_par   )
866 {
867         struct proxy_l *proxy;
868         int r = -1;
869         proxy = t_protoaddr2proxy(proto_par, addr_par);
870         if (proxy) {
871                 r = _w_t_forward_nonack(p_msg, proxy, proxy->proto);            
872                 free_proxy(proxy);
873         }
874         return r;
875 }
876
877
878 inline static int w_t_reply(struct sip_msg* msg, char* p1, char* p2)
879 {
880         struct cell *t;
881         int code, ret = -1;
882         str reason;
883         char* r;
884
885         if (msg->REQ_METHOD==METHOD_ACK) {
886                 LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n");
887                 return -1;
888         }
889         if (t_check( msg , 0 )==-1) return -1;
890         t=get_t();
891         if (!t) {
892                 LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message "
893                         "for which no T-state has been established\n");
894                 return -1;
895         }
896
897         if (get_int_fparam(&code, msg, (fparam_t*)p1) < 0) {
898             code = default_code;
899         }
900         
901         if (get_str_fparam(&reason, msg, (fparam_t*)p2) < 0) {
902             reason = default_reason;
903         }
904         
905         r = as_asciiz(&reason);
906         if (r == NULL) r = default_reason.s;
907         
908         /* if called from reply_route, make sure that unsafe version
909          * is called; we are already in a mutex and another mutex in
910          * the safe version would lead to a deadlock
911          */
912          
913         if (rmode==MODE_ONFAILURE) {
914                 DBG("DEBUG: t_reply_unsafe called from w_t_reply\n");
915                 ret = t_reply_unsafe(t, msg, code, r);
916         } else if (rmode==MODE_REQUEST) {
917                 ret = t_reply( t, msg, code, r);
918         } else {
919                 LOG(L_CRIT, "BUG: w_t_reply entered in unsupported mode\n");
920                 ret = -1;
921         }
922
923         if (r) pkg_free(r);
924         return ret;
925 }
926
927
928 inline static int w_t_release(struct sip_msg* msg, char* str, char* str2)
929 {
930         struct cell *t;
931         int ret;
932         
933         if (t_check( msg  , 0  )==-1) return -1;
934         t=get_t();
935         if ( t && t!=T_UNDEFINED ) {
936                 ret = t_release_transaction( t );
937                 t_unref(msg);
938                 return ret;
939         }
940         return 1;
941 }
942
943
944 inline static int w_t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar)
945 {
946         struct cell *t;
947
948
949         if (t_check( p_msg  , 0 )==-1)
950                 return 1;
951         t=get_t();
952         if (t) {
953                 if (p_msg->REQ_METHOD==METHOD_ACK) {
954                         LOG(L_WARN, "WARNING: : ACKs transmit_replies not replied\n");
955                         return -1;
956                 }
957                 return t_retransmit_reply( t );
958         } else
959                 return -1;
960 }
961
962
963 inline static int w_t_newtran( struct sip_msg* p_msg, char* foo, char* bar )
964 {
965         /* t_newtran returns 0 on error (negative value means
966            'transaction exists' */
967         int ret;
968         ret = t_newtran( p_msg );
969         if (ret==E_SCRIPT) {
970                 LOG(L_ERR, "ERROR: t_newtran: "
971                         "transaction already in process %p\n", get_t() );
972         }
973         return ret;
974 }
975
976
977 inline static int w_t_on_negative( struct sip_msg* msg, char *go_to, char *foo)
978 {
979         t_on_negative( (unsigned int )(long) go_to );
980         return 1;
981 }
982
983 inline static int w_t_on_branch( struct sip_msg* msg, char *go_to, char *foo)
984 {
985         t_on_branch( (unsigned int )(long) go_to );
986         return 1;
987 }
988
989
990 inline static int w_t_on_reply( struct sip_msg* msg, char *go_to, char *foo )
991 {
992         t_on_reply( (unsigned int )(long) go_to );
993         return 1;
994 }
995
996
997
998 inline static int _w_t_relay_to( struct sip_msg  *p_msg ,
999         struct proxy_l *proxy )
1000 {
1001         struct cell *t;
1002
1003         if (rmode==MODE_ONFAILURE) {
1004                 t=get_t();
1005                 if (!t || t==T_UNDEFINED) {
1006                         LOG(L_CRIT, "BUG: w_t_relay_to: undefined T\n");
1007                         return -1;
1008                 }
1009                 if (t_forward_nonack(t, p_msg, proxy, PROTO_NONE)<=0 ) {
1010                         LOG(L_ERR, "ERROR: w_t_relay_to: t_relay_to failed\n");
1011                         return -1;
1012                 }
1013                 return 1;
1014         }
1015         if (rmode==MODE_REQUEST)
1016                 return t_relay_to( p_msg, proxy, PROTO_NONE,
1017                         0 /* no replication */ );
1018         LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
1019         return 0;
1020 }
1021
1022
1023 inline static int w_t_relay_to_udp( struct sip_msg  *p_msg ,
1024         char *proxy, /* struct proxy_l *proxy expected */
1025         char *_foo       /* nothing expected */ )
1026 {
1027         ((struct proxy_l *)proxy)->proto=PROTO_UDP;
1028         return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
1029 }
1030
1031
1032 #ifdef USE_TCP
1033 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg ,
1034         char *proxy, /* struct proxy_l *proxy expected */
1035         char *_foo       /* nothing expected */ )
1036 {
1037         ((struct proxy_l *)proxy)->proto=PROTO_TCP;
1038         return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
1039 }
1040 #endif
1041
1042
1043 #ifdef USE_TLS
1044 inline static int w_t_relay_to_tls( struct sip_msg  *p_msg ,
1045         char *proxy, /* struct proxy_l *proxy expected */
1046         char *_foo       /* nothing expected */ )
1047 {
1048         ((struct proxy_l *)proxy)->proto=PROTO_TLS;
1049         return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
1050 }
1051 #endif
1052
1053 inline static int w_t_relay_to( struct sip_msg  *p_msg ,
1054         char *proto_par, 
1055         char *addr_par   )
1056 {
1057         struct proxy_l *proxy;
1058         int r = -1;
1059         proxy = t_protoaddr2proxy(proto_par, addr_par);
1060         if (proxy) {
1061                 r = _w_t_relay_to(p_msg, proxy);                
1062                 free_proxy(proxy);
1063         }
1064         return r;
1065 }
1066
1067
1068 inline static int w_t_replicate( struct sip_msg  *p_msg ,
1069         char *proxy, /* struct proxy_l *proxy expected */
1070         char *_foo       /* nothing expected */ )
1071 {
1072         return t_replicate(p_msg, ( struct proxy_l *) proxy, p_msg->rcv.proto );
1073 }
1074
1075 inline static int w_t_replicate_udp( struct sip_msg  *p_msg ,
1076         char *proxy, /* struct proxy_l *proxy expected */
1077         char *_foo       /* nothing expected */ )
1078 {
1079         return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_UDP );
1080 }
1081
1082
1083 #ifdef USE_TCP
1084 inline static int w_t_replicate_tcp( struct sip_msg  *p_msg ,
1085         char *proxy, /* struct proxy_l *proxy expected */
1086         char *_foo       /* nothing expected */ )
1087 {
1088         return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_TCP );
1089 }
1090 #endif
1091
1092
1093 #ifdef USE_TLS
1094 inline static int w_t_replicate_tls( struct sip_msg  *p_msg ,
1095         char *proxy, /* struct proxy_l *proxy expected */
1096         char *_foo       /* nothing expected */ )
1097 {
1098         return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_TLS );
1099 }
1100 #endif
1101
1102 inline static int w_t_replicate_to( struct sip_msg  *p_msg ,
1103         char *proto_par, 
1104         char *addr_par   )
1105 {
1106         struct proxy_l *proxy;
1107         int r = -1;
1108         proxy = t_protoaddr2proxy(proto_par, addr_par);
1109         if (proxy) {
1110                 r = t_replicate(p_msg, proxy, proxy->proto);            
1111                 free_proxy(proxy);
1112         }
1113         return r;
1114 }
1115
1116 inline static int w_t_relay( struct sip_msg  *p_msg ,
1117                                                 char *_foo, char *_bar)
1118 {
1119         struct cell *t;
1120
1121         if (rmode==MODE_ONFAILURE) {
1122                 t=get_t();
1123                 if (!t || t==T_UNDEFINED) {
1124                         LOG(L_CRIT, "BUG: w_t_relay: undefined T\n");
1125                         return -1;
1126                 }
1127                 if (t_forward_nonack(t, p_msg, ( struct proxy_l *) 0, PROTO_NONE)<=0) {
1128                         LOG(L_ERR, "ERROR: w_t_relay (failure mode): forwarding failed\n");
1129                         return -1;
1130                 }
1131                 return 1;
1132         }
1133         if (rmode==MODE_REQUEST)
1134                 return t_relay_to( p_msg,
1135                 (struct proxy_l *) 0 /* no proxy */, PROTO_NONE,
1136                 0 /* no replication */ );
1137         LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
1138         return 0;
1139 }
1140
1141 /* relays CANCEL at the beginning of the script */
1142 inline static int w_t_relay_cancel( struct sip_msg  *p_msg ,
1143                                                 char *_foo, char *_bar)
1144 {
1145         if (p_msg->REQ_METHOD!=METHOD_CANCEL)
1146                 return 1;
1147
1148         /* it makes no sense to use this function without reparse_invite=1 */
1149         if (!reparse_invite)
1150                 LOG(L_WARN, "WARNING: t_relay_cancel is probably used with "
1151                         "wrong configuration, check the readme for details\n");
1152
1153         return t_relay_cancel(p_msg);
1154 }
1155
1156 /* set fr_inv_timeout & or fr_timeout; 0 means: use the default value */
1157 static int t_set_fr_all(struct sip_msg* msg, char* p1, char* p2)
1158 {
1159     int fr, fr_inv;
1160
1161     if (get_int_fparam(&fr_inv, msg, (fparam_t*)p1) < 0) return -1;
1162     if (p2) {
1163         if (get_int_fparam(&fr, msg, (fparam_t*)p2) < 0) return -1;
1164     } else {
1165         fr = 0;
1166     }
1167
1168     return t_set_fr(msg, fr_inv, fr);
1169 }
1170
1171 static int t_set_fr_inv(struct sip_msg* msg, char* fr_inv, char* foo)
1172 {
1173         return t_set_fr_all(msg, fr_inv, (char*)0);
1174 }
1175
1176
1177
1178 /* set retr. intervals per transaction; 0 means: use the default value */
1179 static int w_t_set_retr(struct sip_msg* msg, char* p1, char* p2)
1180 {
1181         int t1, t2;
1182         
1183         if (get_int_fparam(&t1, msg, (fparam_t*)p1) < 0) return -1;
1184         if (p2) {
1185                 if (get_int_fparam(&t2, msg, (fparam_t*)p2) < 0) return -1;
1186         } else {
1187                 t2 = 0;
1188         }
1189 #ifdef TM_DIFF_RT_TIMEOUT
1190         return t_set_retr(msg, t1, t2);
1191 #else
1192         ERR("w_t_set_retr: support for changing retransmission intervals on "
1193                         "the fly not compiled in (re-compile tm with"
1194                         " -DTM_DIFF_RT_TIMEOUT)\n");
1195         return -1;
1196 #endif
1197 }
1198
1199
1200
1201 /* set maximum transaction lifetime for inv & noninv */
1202 static int w_t_set_max_lifetime(struct sip_msg* msg, char* p1, char* p2)
1203 {
1204         int t1, t2;
1205         
1206         if (get_int_fparam(&t1, msg, (fparam_t*)p1) < 0) return -1;
1207         if (p2) {
1208                 if (get_int_fparam(&t2, msg, (fparam_t*)p2) < 0) return -1;
1209         } else {
1210                 t2 = 0;
1211         }
1212         return t_set_max_lifetime(msg, t1, t2);
1213 }
1214
1215
1216
1217 /* script function, FAILURE_ROUTE only, returns true if the 
1218  * choosed "failure" branch failed because of a timeout, 
1219  * -1 otherwise */
1220 int t_branch_timeout(struct sip_msg* msg, char* foo, char* bar)
1221 {
1222         return (msg->msg_flags & FL_TIMEOUT)?1:-1;
1223 }
1224
1225
1226
1227 /* script function, FAILURE_ROUTE only, returns true if the 
1228  * choosed "failure" branch ever received a reply, -1 otherwise */
1229 int t_branch_replied(struct sip_msg* msg, char* foo, char* bar)
1230 {
1231         return (msg->msg_flags & FL_REPLIED)?1:-1;
1232 }
1233
1234
1235
1236 /* script function, returns: 1 if the transaction was canceled, -1 if not */
1237 int t_is_canceled(struct sip_msg* msg, char* foo, char* bar)
1238 {
1239         struct cell *t;
1240         int ret;
1241         
1242         
1243         if (t_check( msg , 0 )==-1) return -1;
1244         t=get_t();
1245         if ((t==0) || (t==T_UNDEFINED)){
1246                 LOG(L_ERR, "ERROR: t_is_canceled: cannot check a message "
1247                         "for which no T-state has been established\n");
1248                 ret=-1;
1249         }else{
1250                 ret=(t->flags & T_CANCELED)?1:-1;
1251         }
1252         return ret;
1253 }
1254
1255
1256
1257 /* script function, returns: 1 if any of the branches did timeout, -1 if not */
1258 int t_any_timeout(struct sip_msg* msg, char* foo, char* bar)
1259 {
1260         struct cell *t;
1261         int r;
1262         
1263         if (t_check( msg , 0 )==-1) return -1;
1264         t=get_t();
1265         if ((t==0) || (t==T_UNDEFINED)){
1266                 LOG(L_ERR, "ERROR: t_any_timeout: cannot check a message "
1267                         "for which no T-state has been established\n");
1268                 return -1;
1269         }else{
1270                 for (r=0; r<t->nr_of_outgoings; r++){
1271                         if (t->uac[r].request.flags & F_RB_TIMEOUT)
1272                                 return 1;
1273                 }
1274         }
1275         return -1;
1276 }
1277
1278
1279
1280 /* script function, returns: 1 if any of the branches received at leat one
1281  * reply, -1 if not */
1282 int t_any_replied(struct sip_msg* msg, char* foo, char* bar)
1283 {
1284         struct cell *t;
1285         int r;
1286         
1287         if (t_check( msg , 0 )==-1) return -1;
1288         t=get_t();
1289         if ((t==0) || (t==T_UNDEFINED)){
1290                 LOG(L_ERR, "ERROR: t_any_replied: cannot check a message "
1291                         "for which no T-state has been established\n");
1292                 return -1;
1293         }else{
1294                 for (r=0; r<t->nr_of_outgoings; r++){
1295                         if (t->uac[r].request.flags & F_RB_REPLIED)
1296                                 return 1;
1297                 }
1298         }
1299         return -1;
1300 }
1301
1302
1303
1304 static rpc_export_t tm_rpc[] = {
1305         {"tm.cancel", rpc_cancel,   rpc_cancel_doc,   0},
1306         {"tm.reply",  rpc_reply,    rpc_reply_doc,    0},
1307         {"tm.stats",  tm_rpc_stats, tm_rpc_stats_doc, 0},
1308         {0, 0, 0, 0}
1309 };
1310
1311 /* wrapper function needed after changes in w_t_reply */
1312 int w_t_reply_wrp(struct sip_msg *m, unsigned int code, char *txt)
1313 {
1314         fparam_t c;
1315         fparam_t r;
1316         
1317         c.type = FPARAM_INT;
1318         c.orig = NULL; /* ? */
1319         c.v.i = code;
1320         
1321         r.type = FPARAM_STRING;
1322         r.orig = NULL; /* ? */
1323         r.v.asciiz = txt;
1324
1325         return w_t_reply(m, (char *)&c, (char*)&r);
1326 }
1327