added support for provisional responses while using t_uac_dlg.
[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  */
76
77
78 #include "defs.h"
79
80
81 #include <stdio.h>
82 #include <string.h>
83 #include <netdb.h>
84
85 #include "../../sr_module.h"
86 #include "../../dprint.h"
87 #include "../../error.h"
88 #include "../../ut.h"
89 #include "../../script_cb.h"
90 #include "../../fifo_server.h"
91 #include "../../usr_avp.h"
92 #include "../../mem/mem.h"
93 #include "../../unixsock_server.h"
94
95 #include "sip_msg.h"
96 #include "h_table.h"
97 #include "t_hooks.h"
98 #include "tm_load.h"
99 #include "ut.h"
100 #include "t_reply.h"
101 #include "uac.h"
102 #include "uac_fifo.h"
103 #include "uac_unixsock.h"
104 #include "t_fwd.h"
105 #include "t_lookup.h"
106 #include "t_stats.h"
107 #include "callid.h"
108 #include "t_cancel.h"
109 #include "t_fifo.h"
110
111 MODULE_VERSION
112
113 /* fixup functions */
114 static int fixup_hostport2proxy(void** param, int param_no);
115
116
117 /* init functions */
118 static int mod_init(void);
119 static int child_init(int rank);
120
121
122 /* exported functions */
123 inline static int w_t_check(struct sip_msg* msg, char* str, char* str2);
124 inline static int w_t_reply(struct sip_msg* msg, char* str, char* str2);
125 inline static int w_t_release(struct sip_msg* msg, char* str, char* str2);
126 inline static int w_t_retransmit_reply(struct sip_msg* p_msg, char* foo,
127                                 char* bar );
128 inline static int w_t_newtran(struct sip_msg* p_msg, char* foo, char* bar );
129 inline static int w_t_relay( struct sip_msg  *p_msg , char *_foo, char *_bar);
130 inline static int w_t_relay_to_udp( struct sip_msg  *p_msg , char *proxy, 
131                                  char *);
132 #ifdef USE_TCP
133 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg , char *proxy,
134                                 char *);
135 #endif
136 #ifdef USE_TLS
137 inline static int w_t_relay_to_tls( struct sip_msg  *p_msg , char *proxy,
138                                 char *);
139 #endif
140 inline static int w_t_replicate( struct sip_msg  *p_msg , 
141                                 char *proxy, /* struct proxy_l *proxy expected */
142                                 char *_foo       /* nothing expected */ );
143 inline static int w_t_replicate_udp( struct sip_msg  *p_msg , 
144                                 char *proxy, /* struct proxy_l *proxy expected */
145                                 char *_foo       /* nothing expected */ );
146 #ifdef USE_TCP
147 inline static int w_t_replicate_tcp( struct sip_msg  *p_msg , 
148                                 char *proxy, /* struct proxy_l *proxy expected */
149                                 char *_foo       /* nothing expected */ );
150 #endif
151 #ifdef USE_TLS
152 inline static int w_t_replicate_tls( struct sip_msg  *p_msg , 
153                                 char *proxy, /* struct proxy_l *proxy expected */
154                                 char *_foo       /* nothing expected */ );
155 #endif
156 inline static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* );
157 inline static int w_t_forward_nonack_uri(struct sip_msg* msg, char* str,char*);
158 inline static int w_t_forward_nonack_udp(struct sip_msg* msg, char* str,char*);
159 #ifdef USE_TCP
160 inline static int w_t_forward_nonack_tcp(struct sip_msg* msg, char* str,char*);
161 #endif
162 #ifdef USE_TLS
163 inline static int w_t_forward_nonack_tls(struct sip_msg* msg, char* str,char*);
164 #endif
165 inline static int w_t_on_negative(struct sip_msg* msg, char *go_to, char *foo);
166 inline static int w_t_on_branch(struct sip_msg* msg, char *go_to, char *foo);
167 inline static int w_t_on_reply(struct sip_msg* msg, char *go_to, char *foo );
168 inline static int t_check_status(struct sip_msg* msg, char *regexp, char *foo);
169
170
171 static char *fr_timer_param = FR_TIMER_AVP;
172 static char *fr_inv_timer_param = FR_INV_TIMER_AVP;
173
174
175 static cmd_export_t cmds[]={
176         {"t_newtran",          w_t_newtran,             0, 0,
177                         REQUEST_ROUTE},
178         {"t_lookup_request",   w_t_check,               0, 0,
179                         REQUEST_ROUTE},
180         {T_REPLY,              w_t_reply,               2, fixup_int_1,
181                         REQUEST_ROUTE | FAILURE_ROUTE },
182         {"t_retransmit_reply", w_t_retransmit_reply,    0, 0,
183                         REQUEST_ROUTE},
184         {"t_release",          w_t_release,             0, 0,
185                         REQUEST_ROUTE},
186         {T_RELAY_TO_UDP,       w_t_relay_to_udp,        2, fixup_hostport2proxy,
187                         REQUEST_ROUTE|FAILURE_ROUTE},
188 #ifdef USE_TCP
189         {T_RELAY_TO_TCP,       w_t_relay_to_tcp,        2, fixup_hostport2proxy,
190                         REQUEST_ROUTE|FAILURE_ROUTE},
191 #endif
192 #ifdef USE_TLS
193         {T_RELAY_TO_TLS,       w_t_relay_to_tls,        2, fixup_hostport2proxy,
194                         REQUEST_ROUTE|FAILURE_ROUTE},
195 #endif
196         {"t_replicate",        w_t_replicate,           2, fixup_hostport2proxy,
197                         REQUEST_ROUTE},
198         {"t_replicate_udp",    w_t_replicate_udp,       2, fixup_hostport2proxy,
199                         REQUEST_ROUTE},
200 #ifdef USE_TCP
201         {"t_replicate_tcp",    w_t_replicate_tcp,       2, fixup_hostport2proxy,
202                         REQUEST_ROUTE},
203 #endif
204 #ifdef USE_TLS
205         {"t_replicate_tls",    w_t_replicate_tls,       2, fixup_hostport2proxy,
206                         REQUEST_ROUTE},
207 #endif
208         {T_RELAY,              w_t_relay,               0, 0,
209                         REQUEST_ROUTE | FAILURE_ROUTE },
210         {T_FORWARD_NONACK,     w_t_forward_nonack,      2, fixup_hostport2proxy,
211                         REQUEST_ROUTE},
212         {T_FORWARD_NONACK_URI, w_t_forward_nonack_uri,  0, 0,
213                         REQUEST_ROUTE},
214         {T_FORWARD_NONACK_UDP, w_t_forward_nonack_udp,  2, fixup_hostport2proxy,
215                         REQUEST_ROUTE},
216 #ifdef USE_TCP
217         {T_FORWARD_NONACK_TCP, w_t_forward_nonack_tcp,  2, fixup_hostport2proxy,
218                         REQUEST_ROUTE},
219 #endif
220 #ifdef USE_TLS
221         {T_FORWARD_NONACK_TLS, w_t_forward_nonack_tls,  2, fixup_hostport2proxy,
222                         REQUEST_ROUTE},
223 #endif
224         {"t_on_failure",       w_t_on_negative,         1, fixup_int_1,
225                         REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE },
226         {"t_on_reply",         w_t_on_reply,            1, fixup_int_1,
227                         REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE },
228         {"t_on_branch",       w_t_on_branch,         1, fixup_int_1,
229                         REQUEST_ROUTE | FAILURE_ROUTE },
230         {"t_check_status",     t_check_status,          1, fixup_regex_1,
231                         REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE },
232         {"t_write_req",       t_write_req,              2, fixup_t_write,
233                         REQUEST_ROUTE | FAILURE_ROUTE },
234         {"t_write_unix",      t_write_unix,             2, fixup_t_write,
235                         REQUEST_ROUTE | FAILURE_ROUTE },
236
237         /* not applicable from the script */
238         {"register_tmcb",      (cmd_function)register_tmcb,     NO_SCRIPT,   0, 0},
239         {"load_tm",            (cmd_function)load_tm,           NO_SCRIPT,   0, 0},
240         {T_REPLY_WB,           (cmd_function)t_reply_with_body, NO_SCRIPT,   0, 0},
241         {T_IS_LOCAL,           (cmd_function)t_is_local,        NO_SCRIPT,   0, 0},
242         {T_GET_TI,             (cmd_function)t_get_trans_ident, NO_SCRIPT,   0, 0},
243         {T_LOOKUP_IDENT,       (cmd_function)t_lookup_ident,    NO_SCRIPT,   0, 0},
244         {T_ADDBLIND,           (cmd_function)add_blind_uac,     NO_SCRIPT,   0, 0},
245         {"t_request_within",   (cmd_function)req_within,        NO_SCRIPT,   0, 0},
246         {"t_request_outside",  (cmd_function)req_outside,       NO_SCRIPT,   0, 0},
247         {"t_request",          (cmd_function)request,           NO_SCRIPT,   0, 0},
248         {"new_dlg_uac",        (cmd_function)new_dlg_uac,       NO_SCRIPT,   0, 0},
249         {"dlg_response_uac",   (cmd_function)dlg_response_uac,  NO_SCRIPT,   0, 0},
250         {"new_dlg_uas",        (cmd_function)new_dlg_uas,       NO_SCRIPT,   0, 0},
251         {"dlg_request_uas",    (cmd_function)dlg_request_uas,   NO_SCRIPT,   0, 0},
252         {"free_dlg",           (cmd_function)free_dlg,          NO_SCRIPT,   0, 0},
253         {"print_dlg",          (cmd_function)print_dlg,         NO_SCRIPT,   0, 0},
254         {T_GETT,               (cmd_function)get_t,             NO_SCRIPT,   0,0},
255         {"calculate_hooks",    (cmd_function)w_calculate_hooks, NO_SCRIPT,   0, 0},
256         {0,0,0,0,0}
257 };
258
259
260 static param_export_t params[]={
261         {"ruri_matching",       INT_PARAM, &ruri_matching                        },
262         {"via1_matching",       INT_PARAM, &via1_matching                        },
263         {"fr_timer",            INT_PARAM, &(timer_id2timeout[FR_TIMER_LIST])    },
264         {"fr_inv_timer",        INT_PARAM, &(timer_id2timeout[FR_INV_TIMER_LIST])},
265         {"wt_timer",            INT_PARAM, &(timer_id2timeout[WT_TIMER_LIST])    },
266         {"delete_timer",        INT_PARAM, &(timer_id2timeout[DELETE_LIST])      },
267         {"retr_timer1p1",       INT_PARAM, &(timer_id2timeout[RT_T1_TO_1])       },
268         {"retr_timer1p2",       INT_PARAM, &(timer_id2timeout[RT_T1_TO_2])       },
269         {"retr_timer1p3",       INT_PARAM, &(timer_id2timeout[RT_T1_TO_3])       },
270         {"retr_timer2",         INT_PARAM, &(timer_id2timeout[RT_T2])            },
271         {"noisy_ctimer",        INT_PARAM, &noisy_ctimer                         },
272         {"uac_from",            STR_PARAM, &uac_from                             },
273         {"unix_tx_timeout",     INT_PARAM, &tm_unix_tx_timeout                   },
274         {"restart_fr_on_each_reply", INT_PARAM, &restart_fr_on_each_reply        },
275         {"fr_timer_avp",        STR_PARAM, &fr_timer_param                       },
276         {"fr_inv_timer_avp",    STR_PARAM, &fr_inv_timer_param                   },
277         {"tw_append",           STR_PARAM|USE_FUNC_PARAM, (void*)parse_tw_append },
278         {"pass_provisional_replies", INT_PARAM, &pass_provisional_replies        },
279         {0,0,0}
280 };
281
282
283 #ifdef STATIC_TM
284 struct module_exports tm_exports = {
285 #else
286 struct module_exports exports= {
287 #endif
288         "tm",
289         /* -------- exported functions ----------- */
290         cmds,
291         /* ------------ exported variables ---------- */
292         params,
293         
294         mod_init, /* module initialization function */
295         (response_function) reply_received,
296         (destroy_function) tm_shutdown,
297         0, /* w_onbreak, */
298         child_init /* per-child init function */
299 };
300
301
302 /* (char *hostname, char *port_nr) ==> (struct proxy_l *, -)  */
303 static int fixup_hostport2proxy(void** param, int param_no)
304 {
305         unsigned int port;
306         char *host;
307         int err;
308         struct proxy_l *proxy;
309         str s;
310         
311         DBG("TM module: fixup_hostport2proxy(%s, %d)\n", (char*)*param, param_no);
312         if (param_no==1){
313                 return 0;
314         } else if (param_no==2) {
315                 host=(char *) (*(param-1)); 
316                 port=str2s(*param, strlen(*param), &err);
317                 if (err!=0) {
318                         LOG(L_ERR, "TM module:fixup_hostport2proxy: bad port number <%s>\n",
319                                 (char*)(*param));
320                          return E_UNSPEC;
321                 }
322                 s.s = host;
323                 s.len = strlen(host);
324                 proxy=mk_proxy(&s, port, 0); /* FIXME: udp or tcp? */
325                 if (proxy==0) {
326                         LOG(L_ERR, "ERROR: fixup_hostport2proxy: bad host name in URI <%s>\n",
327                                 host );
328                         return E_BAD_ADDRESS;
329                 }
330                 /* success -- fix the first parameter to proxy now ! */
331
332                 *(param-1)=proxy;
333                 return 0;
334         } else {
335                 LOG(L_ERR,"ERROR: fixup_hostport2proxy called with parameter #<>{1,2}\n");
336                 return E_BUG;
337         }
338 }
339
340
341 /***************************** init functions *****************************/
342 static int w_t_unref( struct sip_msg *foo, void *bar)
343 {
344         return t_unref(foo);
345 }
346
347
348 static int script_init( struct sip_msg *foo, void *bar)
349 {   
350         /* we primarily reset all private memory here to make sure
351          * private values left over from previous message will
352          * not be used again */
353
354         /* make sure the new message will not inherit previous
355                 message's t_on_negative value
356         */
357         t_on_negative( 0 );
358         t_on_reply(0);
359         t_on_branch(0);
360         /* reset the kr status */
361         set_kr(0);
362         /* set request mode so that multiple-mode actions know
363          * how to behave */
364         rmode=MODE_REQUEST;
365         return 1;
366 }
367
368
369 static int mod_init(void)
370 {
371         DBG( "TM - (size of cell=%ld, sip_msg=%ld) initializing...\n", 
372                         (long)sizeof(struct cell), (long)sizeof(struct sip_msg));
373         /* checking if we have sufficient bitmap capacity for given
374            maximum number of  branches */
375         if (MAX_BRANCHES+1>31) {
376                 LOG(L_CRIT, "Too many max UACs for UAC branch_bm_t bitmap: %d\n",
377                         MAX_BRANCHES );
378                 return -1;
379         }
380
381         if (init_callid() < 0) {
382                 LOG(L_CRIT, "Error while initializing Call-ID generator\n");
383                 return -1;
384         }
385
386         if (register_fifo_cmd(fifo_uac, "t_uac_dlg", 0) < 0) {
387                 LOG(L_CRIT, "cannot register fifo t_uac\n");
388                 return -1;
389         }
390
391         if (register_fifo_cmd(fifo_uac_cancel, "t_uac_cancel", 0) < 0) {
392                 LOG(L_CRIT, "cannot register fifo t_uac_cancel\n");
393                 return -1;
394         }
395
396         if (register_fifo_cmd(fifo_hash, "t_hash", 0)<0) {
397                 LOG(L_CRIT, "cannot register hash\n");
398                 return -1;
399         }
400
401         if (register_fifo_cmd(fifo_t_reply, "t_reply", 0)<0) {
402                 LOG(L_CRIT, "cannot register t_reply\n");
403                 return -1;
404         }
405
406         if (unixsock_register_cmd("t_uac_dlg", unixsock_uac) < 0) {
407                 LOG(L_CRIT, "cannot register t_uac with the unix server\n");
408                 return -1;
409         }
410
411         if (unixsock_register_cmd("t_uac_cancel", unixsock_uac_cancel) < 0) {
412                 LOG(L_CRIT, "cannot register t_uac_cancel with the unix server\n");
413                 return -1;
414         }
415
416         if (unixsock_register_cmd("t_hash", unixsock_hash) < 0) {
417                 LOG(L_CRIT, "cannot register t_hash with the unix server\n");
418                 return -1;
419         }
420
421         if (unixsock_register_cmd("t_reply", unixsock_t_reply) < 0) {
422                 LOG(L_CRIT, "cannot register t_reply with the unix server\n");
423                 return -1;
424         }
425
426         /* building the hash table*/
427         if (!init_hash_table()) {
428                 LOG(L_ERR, "ERROR: mod_init: initializing hash_table failed\n");
429                 return -1;
430         }
431
432         /* init static hidden values */
433         init_t();
434
435         if (!tm_init_timers()) {
436                 LOG(L_ERR, "ERROR: mod_init: timer init failed\n");
437                 return -1;
438         }
439         /* register the timer function */
440         register_timer( timer_routine , 0 /* empty attr */, 1 );
441
442         /* init_tm_stats calls process_count, which should
443          * NOT be called from mod_init, because one does not
444          * now, if a timer is used and thus how many processes
445          * will be started; however we started already our
446          * timers, so we know and process_count should not
447          * change any more
448          */     
449         if (init_tm_stats()<0) {
450                 LOG(L_CRIT, "ERROR: mod_init: failed to init stats\n");
451                 return -1;
452         }
453
454         if (uac_init()==-1) {
455                 LOG(L_ERR, "ERROR: mod_init: uac_init failed\n");
456                 return -1;
457         }
458
459         if (init_tmcb_lists()!=1) {
460                 LOG(L_CRIT, "ERROR:tm:mod_init: failed to init tmcb lists\n");
461                 return -1;
462         }
463
464         tm_init_tags();
465         init_twrite_lines();
466         if (init_twrite_sock() < 0) {
467                 LOG(L_ERR, "ERROR:tm:mod_init: Unable to create socket\n");
468                 return -1;
469         }
470
471         /* register post-script clean-up function */
472         if (register_script_cb( w_t_unref, POST_SCRIPT_CB|REQ_TYPE_CB, 0)<0 ) {
473                 LOG(L_ERR,"ERROR:tm:mod_init: failed to register POST request "
474                         "callback\n");
475                 return -1;
476         }
477         if (register_script_cb( script_init, PRE_SCRIPT_CB|REQ_TYPE_CB , 0)<0 ) {
478                 LOG(L_ERR,"ERROR:tm:mod_init: failed to register PRE request "
479                         "callback\n");
480                 return -1;
481         }
482
483         if (init_avp_params( fr_timer_param, fr_inv_timer_param)<0 ){
484                 LOG(L_ERR,"ERROR:tm:mod_init: failed to process timer AVPs\n");
485                 return -1;
486         }
487
488         tm_init = 1;
489         return 0;
490 }
491
492 static int child_init(int rank) {
493         if (child_init_callid(rank) < 0) {
494                 LOG(L_ERR, "ERROR: child_init: Error while initializing Call-ID generator\n");
495                 return -2;
496         }
497
498         return 0;
499 }
500
501
502
503
504
505 /**************************** wrapper functions ***************************/
506 static int t_check_status(struct sip_msg* msg, char *regexp, char *foo)
507 {
508         regmatch_t pmatch;
509         struct cell *t;
510         char *status;
511         char backup;
512         int lowest_status;
513         int n;
514
515         /* first get the transaction */
516         if (t_check( msg , 0 )==-1) return -1;
517         if ( (t=get_t())==0) {
518                 LOG(L_ERR, "ERROR: t_check_status: cannot check status for a reply "
519                         "which has no T-state established\n");
520                 return -1;
521         }
522         backup = 0;
523
524         switch (rmode) {
525                 case MODE_REQUEST:
526                         /* use the status of the last sent reply */
527                         status = int2str( t->uas.status, 0);
528                         break;
529                 case MODE_ONREPLY:
530                         /* use the status of the current reply */
531                         status = msg->first_line.u.reply.status.s;
532                         backup = status[msg->first_line.u.reply.status.len];
533                         status[msg->first_line.u.reply.status.len] = 0;
534                         break;
535                 case MODE_ONFAILURE:
536                         /* use the status of the winning reply */
537                         if (t_pick_branch( -1, 0, t, &lowest_status)<0 ) {
538                                 LOG(L_CRIT,"BUG:t_check_status: t_pick_branch failed to get "
539                                         " a final response in MODE_ONFAILURE\n");
540                                 return -1;
541                         }
542                         status = int2str( lowest_status , 0);
543                         break;
544                 default:
545                         LOG(L_ERR,"ERROR:t_check_status: unsupported mode %d\n",rmode);
546                         return -1;
547         }
548
549         DBG("DEBUG:t_check_status: checked status is <%s>\n",status);
550         /* do the checking */
551         n = regexec((regex_t*)regexp, status, 1, &pmatch, 0);
552
553         if (backup) status[msg->first_line.u.reply.status.len] = backup;
554         if (n!=0) return -1;
555         return 1;
556 }
557
558
559 inline static int w_t_check(struct sip_msg* msg, char* str, char* str2)
560 {
561         return t_check( msg , 0  ) ? 1 : -1;
562 }
563
564
565 inline static int _w_t_forward_nonack(struct sip_msg* msg, char* proxy,
566                                                                                                                                         int proto)
567 {
568         struct cell *t;
569         if (t_check( msg , 0 )==-1) {
570                 LOG(L_ERR, "ERROR: forward_nonack: "
571                                 "can't forward when no transaction was set up\n");
572                 return -1;
573         }
574         t=get_t();
575         if ( t && t!=T_UNDEFINED ) {
576                 if (msg->REQ_METHOD==METHOD_ACK) {
577                         LOG(L_WARN,"WARNING: you don't really want to fwd hbh ACK\n");
578                         return -1;
579                 }
580                 return t_forward_nonack(t, msg, ( struct proxy_l *) proxy, proto );
581         } else {
582                 DBG("DEBUG: forward_nonack: no transaction found\n");
583                 return -1;
584         }
585 }
586
587
588 inline static int w_t_forward_nonack( struct sip_msg* msg, char* proxy,
589                                                                                 char* foo)
590 {
591         return _w_t_forward_nonack(msg, proxy, PROTO_NONE);
592 }
593
594
595 inline static int w_t_forward_nonack_uri(struct sip_msg* msg, char *foo,
596                                                                                                                                         char *bar)
597 {
598         return _w_t_forward_nonack(msg, 0, PROTO_NONE);
599 }
600
601
602 inline static int w_t_forward_nonack_udp( struct sip_msg* msg, char* proxy,
603                                                                                 char* foo)
604 {
605         return _w_t_forward_nonack(msg, proxy, PROTO_UDP);
606 }
607
608
609 #ifdef USE_TCP
610 inline static int w_t_forward_nonack_tcp( struct sip_msg* msg, char* proxy,
611                                                                                 char* foo)
612 {
613         return _w_t_forward_nonack(msg, proxy, PROTO_TCP);
614 }
615 #endif
616
617
618 #ifdef USE_TLS
619 inline static int w_t_forward_nonack_tls( struct sip_msg* msg, char* proxy,
620                                                                                 char* foo)
621 {
622         return _w_t_forward_nonack(msg, proxy, PROTO_TLS);
623 }
624 #endif
625
626
627 inline static int w_t_reply(struct sip_msg* msg, char* str, char* str2)
628 {
629         struct cell *t;
630
631         if (msg->REQ_METHOD==METHOD_ACK) {
632                 LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n");
633                 return -1;
634         }
635         if (t_check( msg , 0 )==-1) return -1;
636         t=get_t();
637         if (!t) {
638                 LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message "
639                         "for which no T-state has been established\n");
640                 return -1;
641         }
642         /* if called from reply_route, make sure that unsafe version
643          * is called; we are already in a mutex and another mutex in
644          * the safe version would lead to a deadlock
645          */
646         if (rmode==MODE_ONFAILURE) { 
647                 DBG("DEBUG: t_reply_unsafe called from w_t_reply\n");
648                 return t_reply_unsafe(t, msg, (unsigned int)(long) str, str2);
649         } else if (rmode==MODE_REQUEST) {
650                 return t_reply( t, msg, (unsigned int)(long) str, str2);
651         } else {
652                 LOG(L_CRIT, "BUG: w_t_reply entered in unsupported mode\n");
653                 return -1;
654         }
655 }
656
657
658 inline static int w_t_release(struct sip_msg* msg, char* str, char* str2)
659 {
660         struct cell *t;
661         if (t_check( msg  , 0  )==-1) return -1;
662         t=get_t();
663         if ( t && t!=T_UNDEFINED ) 
664                 return t_release_transaction( t );
665         return 1;
666 }
667
668
669 inline static int w_t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar)
670 {
671         struct cell *t;
672
673
674         if (t_check( p_msg  , 0 )==-1) 
675                 return 1;
676         t=get_t();
677         if (t) {
678                 if (p_msg->REQ_METHOD==METHOD_ACK) {
679                         LOG(L_WARN, "WARNING: : ACKs transmit_replies not replied\n");
680                         return -1;
681                 }
682                 return t_retransmit_reply( t );
683         } else 
684                 return -1;
685 }
686
687
688 inline static int w_t_newtran( struct sip_msg* p_msg, char* foo, char* bar ) 
689 {
690         /* t_newtran returns 0 on error (negative value means
691            'transaction exists' */
692         return t_newtran( p_msg );
693 }
694
695
696 inline static int w_t_on_negative( struct sip_msg* msg, char *go_to, char *foo)
697 {
698         t_on_negative( (unsigned int )(long) go_to );
699         return 1;
700 }
701
702 inline static int w_t_on_branch( struct sip_msg* msg, char *go_to, char *foo)
703 {
704         t_on_branch( (unsigned int )(long) go_to );
705         return 1;
706 }
707
708
709 inline static int w_t_on_reply( struct sip_msg* msg, char *go_to, char *foo )
710 {
711         t_on_reply( (unsigned int )(long) go_to );
712         return 1;
713 }
714
715
716
717 inline static int _w_t_relay_to( struct sip_msg  *p_msg , 
718         struct proxy_l *proxy )
719 {
720         struct cell *t;
721
722         if (rmode==MODE_ONFAILURE) { 
723                 t=get_t();
724                 if (!t || t==T_UNDEFINED) {
725                         LOG(L_CRIT, "BUG: w_t_relay_to: undefined T\n");
726                         return -1;
727                 }
728                 if (t_forward_nonack(t, p_msg, proxy, PROTO_NONE)<=0 ) {
729                         LOG(L_ERR, "ERROR: w_t_relay_to: t_relay_to failed\n");
730                         return -1;
731                 }
732                 return 1;
733         }
734         if (rmode==MODE_REQUEST) 
735                 return t_relay_to( p_msg, proxy, PROTO_NONE,
736                         0 /* no replication */ );
737         LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
738         return 0;
739 }
740
741
742 inline static int w_t_relay_to_udp( struct sip_msg  *p_msg , 
743         char *proxy, /* struct proxy_l *proxy expected */
744         char *_foo       /* nothing expected */ )
745 {
746         ((struct proxy_l *)proxy)->proto=PROTO_UDP;
747         return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
748 }
749
750
751 #ifdef USE_TCP
752 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg , 
753         char *proxy, /* struct proxy_l *proxy expected */
754         char *_foo       /* nothing expected */ )
755 {
756         ((struct proxy_l *)proxy)->proto=PROTO_TCP;
757         return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
758 }
759 #endif
760
761
762 #ifdef USE_TLS
763 inline static int w_t_relay_to_tls( struct sip_msg  *p_msg , 
764         char *proxy, /* struct proxy_l *proxy expected */
765         char *_foo       /* nothing expected */ )
766 {
767         ((struct proxy_l *)proxy)->proto=PROTO_TLS;
768         return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy);
769 }
770 #endif
771
772
773 inline static int w_t_replicate( struct sip_msg  *p_msg , 
774         char *proxy, /* struct proxy_l *proxy expected */
775         char *_foo       /* nothing expected */ )
776 {
777         return t_replicate(p_msg, ( struct proxy_l *) proxy, p_msg->rcv.proto );
778 }
779
780
781 inline static int w_t_replicate_udp( struct sip_msg  *p_msg , 
782         char *proxy, /* struct proxy_l *proxy expected */
783         char *_foo       /* nothing expected */ )
784 {
785         return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_UDP );
786 }
787
788
789 #ifdef USE_TCP
790 inline static int w_t_replicate_tcp( struct sip_msg  *p_msg , 
791         char *proxy, /* struct proxy_l *proxy expected */
792         char *_foo       /* nothing expected */ )
793 {
794         return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_TCP );
795 }
796 #endif
797
798
799 #ifdef USE_TLS
800 inline static int w_t_replicate_tls( struct sip_msg  *p_msg , 
801         char *proxy, /* struct proxy_l *proxy expected */
802         char *_foo       /* nothing expected */ )
803 {
804         return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_TLS );
805 }
806 #endif
807
808
809 inline static int w_t_relay( struct sip_msg  *p_msg , 
810                                                 char *_foo, char *_bar)
811 {
812         struct cell *t;
813
814         if (rmode==MODE_ONFAILURE) { 
815                 t=get_t();
816                 if (!t || t==T_UNDEFINED) {
817                         LOG(L_CRIT, "BUG: w_t_relay: undefined T\n");
818                         return -1;
819                 } 
820                 if (t_forward_nonack(t, p_msg, ( struct proxy_l *) 0, PROTO_NONE)<=0) {
821                         LOG(L_ERR, "ERROR: w_t_relay (failure mode): forwarding failed\n");
822                         return -1;
823                 }
824                 return 1;
825         }
826         if (rmode==MODE_REQUEST) 
827                 return t_relay_to( p_msg, 
828                 (struct proxy_l *) 0 /* no proxy */, PROTO_NONE,
829                 0 /* no replication */ );
830         LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported mode: %d\n", rmode);
831         return 0;
832 }