tm/tm.c

Go to the documentation of this file.
00001 /*
00002  * $Id$
00003  *
00004  * TM module
00005  *
00006  *
00007  * ***************************************************
00008  * * Jiri's Source Memorial                          *
00009  * *                                                 *
00010  * * Welcome, pilgrim ! This is the greatest place   *
00011  * * where dramatic changes happend. There are not   *
00012  * * many places with a history like this, as there  *
00013  * * are not so many people like Jiri, one of the    *
00014  * * ser's fathers, who brought everywhere the wind  *
00015  * * of change, the flood of clean-up. We all felt   *
00016  * * his fatherly eye watching over us day and night.*
00017  * *                                                 *
00018  * * Please, preserve this codework heritage, as     *
00019  * * it's unlikely for fresh, juicy pieces of code to  *
00020  * * arise to give him the again the chance to       *
00021  * * demonstrate his clean-up and improvement skills.*
00022  * *                                                 *
00023  * * Hereby, we solicit you to adopt this historical *
00024  * * piece of code. For $100, your name will be      *
00025  * * be printed in this banner and we will use       *
00026  * * collected funds to create and display an ASCII  *
00027  * * statue of Jiri  .                               *
00028  * ***************************************************
00029  *
00030  *
00031  * Copyright (C) 2001-2003 FhG Fokus
00032  *
00033  * This file is part of SIP-router, a free SIP server.
00034  *
00035  * SIP-router is free software; you can redistribute it and/or modify
00036  * it under the terms of the GNU General Public License as published by
00037  * the Free Software Foundation; either version 2 of the License, or
00038  * (at your option) any later version
00039  *
00040  * SIP-router is distributed in the hope that it will be useful,
00041  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00042  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00043  * GNU General Public License for more details.
00044  *
00045  * You should have received a copy of the GNU General Public License
00046  * along with this program; if not, write to the Free Software
00047  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00048  */
00049 /*
00050  * History:
00051  * --------
00052  *  2003-02-18  added t_forward_nonack_{udp, tcp}, t_relay_to_{udp,tcp},
00053  *               t_replicate_{udp, tcp} (andrei)
00054  *  2003-02-19  added t_rely_{udp, tcp} (andrei)
00055  *  2003-03-06  voicemail changes accepted (jiri)
00056  *  2003-03-10  module export interface updated to the new format (andrei)
00057  *  2003-03-16  flags export parameter added (janakj)
00058  *  2003-03-19  replaced all mallocs/frees w/ pkg_malloc/pkg_free (andrei)
00059  *  2003-03-30  set_kr for requests only (jiri)
00060  *  2003-04-05  s/reply_route/failure_route, onreply_route introduced (jiri)
00061  *  2003-04-14  use protocol from uri (jiri)
00062  *  2003-07-07  added t_relay_to_tls, t_replicate_tls, t_forward_nonack_tls
00063  *              added #ifdef USE_TCP, USE_TLS
00064  *              removed t_relay_{udp,tcp,tls} (andrei)
00065  *  2003-09-26  added t_forward_nonack_uri() - same as t_forward_nonack() but
00066  *              takes no parameters -> forwards to uri (bogdan)
00067  *  2004-02-11  FIFO/CANCEL + alignments (hash=f(callid,cseq)) (uli+jiri)
00068  *  2004-02-18  t_reply exported via FIFO - imported from VM (bogdan)
00069  *  2004-10-01  added a new param.: restart_fr_on_each_reply (andrei)
00070  *  2005-11-14  new timer support, changed timer related module params (andrei)
00071  *  2005-12-09  fixup_hostport2proxy uses route_struct to access param #1
00072  *              when fixing param #2
00073  *  2005-12-09  added t_set_fr() (andrei)
00074  *  2006-02-07  named routes support (andrei)
00075  *  2006-09-28  added t_branch_replied, t_branch_timeout, t_any_replied, 
00076  *               t_any_timeout, t_is_canceled (andrei)
00077  *  2006-10-16  added a new param.: aggregate challenges (andrei)
00078  *  2007-05-28  two new params: reparse_invite, ac_extra_hdrs
00079  *              added w_t_relay_cancel() (Miklos)
00080  *  2007-06-05  added t_set_auto_inv_100() and auto_inv_100 (param);
00081  *               t_set_max_lifetime(), max_{non}inv_lifetime  (andrei)
00082  *  2008-02-05  module config parameters use the configuration framework (Miklos)
00083  *  2008-02-29  added t_grep_status(code) (andrei)
00084  *  2008-05-15  added t_relay(host, port) (similar to forward(host, port)) &
00085  *               t_relay_to_{udp,tcp,tls}(<no param>) (force protocol, but 
00086  *               forward to uri)  (andrei)
00087  *  2008-08-11  sctp support: t_relay_to_sctp, t_replicate_sctp,
00088  *               t_forward_nonack_sctp (andrei)
00089  *  2009-03-18  added a new param: auto_inv_100_reason (aheise) 
00090  *  2010-03-03  added new params: local_cancel_reason and e2e_cancel_reason
00091  *              (andrei)
00092  */
00093 
00146 #include "defs.h"
00147 
00148 
00149 #include <stdio.h>
00150 #include <string.h>
00151 #include <netdb.h>
00152 
00153 #include "../../sr_module.h"
00154 #include "../../dprint.h"
00155 #include "../../error.h"
00156 #include "../../ut.h"
00157 #include "../../script_cb.h"
00158 #include "../../usr_avp.h"
00159 #include "../../mem/mem.h"
00160 #include "../../route_struct.h"
00161 #include "../../route.h"
00162 #include "../../cfg/cfg.h"
00163 #include "../../globals.h"
00164 #include "../../timer_ticks.h"
00165 #include "../../mod_fix.h"
00166 
00167 #include "config.h"
00168 #include "sip_msg.h"
00169 #include "h_table.h"
00170 #include "t_hooks.h"
00171 #include "tm_load.h"
00172 #include "ut.h"
00173 #include "t_reply.h"
00174 #include "uac.h"
00175 #include "t_fwd.h"
00176 #include "t_lookup.h"
00177 #include "t_stats.h"
00178 #include "callid.h"
00179 #include "t_cancel.h"
00180 #include "t_fifo.h"
00181 #include "timer.h"
00182 #include "t_msgbuilder.h"
00183 #include "select.h"
00184 #include "t_serial.h"
00185 #include "rpc_uac.h"
00186 
00187 MODULE_VERSION
00188 
00189 /* fixup functions */
00190 static int fixup_hostport2proxy(void** param, int param_no);
00191 static int fixup_proto_hostport2proxy(void** param, int param_no);
00192 static int fixup_on_failure(void** param, int param_no);
00193 static int fixup_on_reply(void** param, int param_no);
00194 static int fixup_on_branch(void** param, int param_no);
00195 static int fixup_t_reply(void** param, int param_no);
00196 static int fixup_on_sl_reply(modparam_t type, void* val);
00197 static int fixup_t_relay_to(void** param, int param_no);
00198 
00199 /* init functions */
00200 static int mod_init(void);
00201 static int child_init(int rank);
00202 
00203 
00204 /* exported functions */
00205 inline static int w_t_check(struct sip_msg* msg, char* str, char* str2);
00206 inline static int w_t_lookup_cancel(struct sip_msg* msg, char* str, char* str2);
00207 inline static int w_t_reply(struct sip_msg* msg, char* str, char* str2);
00208 inline static int w_t_release(struct sip_msg* msg, char* str, char* str2);
00209 inline static int w_t_retransmit_reply(struct sip_msg* p_msg, char* foo,
00210                                 char* bar );
00211 inline static int w_t_newtran(struct sip_msg* p_msg, char* foo, char* bar );
00212 inline static int w_t_relay( struct sip_msg  *p_msg , char *_foo, char *_bar);
00213 inline static int w_t_relay2( struct sip_msg  *p_msg , char *proxy, char*);
00214 inline static int w_t_relay_to_udp( struct sip_msg  *p_msg , char *proxy,
00215                                  char *);
00216 inline static int w_t_relay_to_udp_uri( struct sip_msg  *p_msg , char*, char*);
00217 #ifdef USE_TCP
00218 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg , char *proxy,
00219                                 char *);
00220 inline static int w_t_relay_to_tcp_uri( struct sip_msg  *p_msg , char*, char*);
00221 #endif
00222 #ifdef USE_TLS
00223 inline static int w_t_relay_to_tls( struct sip_msg  *p_msg , char *proxy,
00224                                 char *);
00225 inline static int w_t_relay_to_tls_uri( struct sip_msg  *p_msg , char*, char*);
00226 #endif
00227 #ifdef USE_SCTP
00228 inline static int w_t_relay_to_sctp( struct sip_msg  *p_msg , char *proxy,
00229                                 char *);
00230 inline static int w_t_relay_to_sctp_uri( struct sip_msg*, char*, char*);
00231 #endif
00232 inline static int w_t_relay_to_avp(struct sip_msg* msg, char* str,char*);
00233 inline static int w_t_relay_to(struct sip_msg* msg, char* str,char*);
00234 inline static int w_t_replicate_uri( struct sip_msg  *p_msg ,
00235                                 char *uri,       /* sip uri as string or variable */
00236                                 char *_foo       /* nothing expected */ );
00237 inline static int w_t_replicate( struct sip_msg  *p_msg ,
00238                                 char *proxy, /* struct proxy_l *proxy expected */
00239                                 char *_foo       /* nothing expected */ );
00240 inline static int w_t_replicate_udp( struct sip_msg  *p_msg ,
00241                                 char *proxy, /* struct proxy_l *proxy expected */
00242                                 char *_foo       /* nothing expected */ );
00243 #ifdef USE_TCP
00244 inline static int w_t_replicate_tcp( struct sip_msg  *p_msg ,
00245                                 char *proxy, /* struct proxy_l *proxy expected */
00246                                 char *_foo       /* nothing expected */ );
00247 #endif
00248 #ifdef USE_TLS
00249 inline static int w_t_replicate_tls( struct sip_msg  *p_msg ,
00250                                 char *proxy, /* struct proxy_l *proxy expected */
00251                                 char *_foo       /* nothing expected */ );
00252 #endif
00253 #ifdef USE_SCTP
00254 inline static int w_t_replicate_sctp( struct sip_msg  *p_msg ,
00255                                 char *proxy, /* struct proxy_l *proxy expected */
00256                                 char *_foo       /* nothing expected */ );
00257 #endif
00258 inline static int w_t_replicate_to(struct sip_msg* msg, char* str,char*);
00259 inline static int w_t_forward_nonack(struct sip_msg* msg, char* str, char* );
00260 inline static int w_t_forward_nonack_uri(struct sip_msg* msg, char* str,char*);
00261 inline static int w_t_forward_nonack_udp(struct sip_msg* msg, char* str,char*);
00262 #ifdef USE_TCP
00263 inline static int w_t_forward_nonack_tcp(struct sip_msg*, char* str,char*);
00264 #endif
00265 #ifdef USE_TLS
00266 inline static int w_t_forward_nonack_tls(struct sip_msg*, char* str,char*);
00267 #endif
00268 #ifdef USE_SCTP
00269 inline static int w_t_forward_nonack_sctp(struct sip_msg*, char* str,char*);
00270 #endif
00271 inline static int w_t_forward_nonack_to(struct sip_msg* msg, char* str,char*);
00272 inline static int w_t_relay_cancel(struct sip_msg *p_msg, char *_foo, char *_bar);
00273 inline static int w_t_on_negative(struct sip_msg* msg, char *go_to, char *foo);
00274 inline static int w_t_on_branch(struct sip_msg* msg, char *go_to, char *foo);
00275 inline static int w_t_on_reply(struct sip_msg* msg, char *go_to, char *foo );
00276 inline static int t_check_status(struct sip_msg* msg, char *match, char *foo);
00277 static int t_set_fr_inv(struct sip_msg* msg, char* fr_inv, char* foo);
00278 static int t_set_fr_all(struct sip_msg* msg, char* fr_inv, char* fr);
00279 static int w_t_reset_fr(struct sip_msg* msg, char* foo, char* bar);
00280 static int w_t_set_retr(struct sip_msg* msg, char* retr_t1, char* retr_t2);
00281 static int w_t_reset_retr(struct sip_msg* msg, char* foo, char* bar);
00282 static int w_t_set_max_lifetime(struct sip_msg* msg, char* inv, char* noninv);
00283 static int w_t_reset_max_lifetime(struct sip_msg* msg, char* foo, char* bar);
00284 static int t_set_auto_inv_100(struct sip_msg* msg, char* on_off, char* foo);
00285 static int t_set_disable_6xx(struct sip_msg* msg, char* on_off, char* foo);
00286 static int t_set_disable_failover(struct sip_msg* msg, char* on_off, char* f);
00287 #ifdef CANCEL_REASON_SUPPORT
00288 static int t_set_no_e2e_cancel_reason(struct sip_msg* msg, char* on_off,
00289                                                                                 char* f);
00290 #endif /* CANCEL_REASON_SUPPORT */
00291 static int t_branch_timeout(struct sip_msg* msg, char*, char*);
00292 static int t_branch_replied(struct sip_msg* msg, char*, char*);
00293 static int t_any_timeout(struct sip_msg* msg, char*, char*);
00294 static int t_any_replied(struct sip_msg* msg, char*, char*);
00295 static int w_t_is_canceled(struct sip_msg* msg, char*, char*);
00296 static int t_is_expired(struct sip_msg* msg, char*, char*);
00297 static int t_grep_status(struct sip_msg* msg, char*, char*);
00298 static int w_t_drop_replies(struct sip_msg* msg, char* foo, char* bar);
00299 static int w_t_save_lumps(struct sip_msg* msg, char* foo, char* bar);
00300 static int w_t_check_trans(struct sip_msg* msg, char* foo, char* bar);
00301 
00302 
00303 /* by default the fr timers avps are not set, so that the avps won't be
00304  * searched for nothing each time a new transaction is created */
00305 static char *fr_timer_param = 0 /*FR_TIMER_AVP*/;
00306 static char *fr_inv_timer_param = 0 /*FR_INV_TIMER_AVP*/;
00307 static char *contacts_avp_param = 0;
00308 
00309 static rpc_export_t tm_rpc[];
00310 
00311 static int fixup_t_check_status(void** param, int param_no);
00312 
00313 static cmd_export_t cmds[]={
00314         {"t_newtran",          w_t_newtran,             0, 0,
00315                         REQUEST_ROUTE},
00316         {"t_lookup_request",   w_t_check,               0, 0,
00317                         REQUEST_ROUTE},
00318         {"t_lookup_cancel",    w_t_lookup_cancel,       0, 0,
00319                         REQUEST_ROUTE},
00320         {"t_lookup_cancel",    w_t_lookup_cancel,       1, fixup_int_1,
00321                         REQUEST_ROUTE},
00322         {"t_reply",              w_t_reply,               2, fixup_t_reply,
00323                         REQUEST_ROUTE | ONREPLY_ROUTE | FAILURE_ROUTE },
00324         {"t_retransmit_reply", w_t_retransmit_reply,    0, 0,
00325                         REQUEST_ROUTE},
00326         {"t_release",          w_t_release,             0, 0,
00327                         REQUEST_ROUTE},
00328         {"t_relay_to_udp",       w_t_relay_to_udp,        2, fixup_hostport2proxy,
00329                         REQUEST_ROUTE|FAILURE_ROUTE},
00330         {"t_relay_to_udp",       w_t_relay_to_udp_uri,    0, 0,
00331                         REQUEST_ROUTE|FAILURE_ROUTE},
00332 #ifdef USE_TCP
00333         {"t_relay_to_tcp",       w_t_relay_to_tcp,        2, fixup_hostport2proxy,
00334                         REQUEST_ROUTE|FAILURE_ROUTE},
00335         {"t_relay_to_tcp",       w_t_relay_to_tcp_uri,    0, 0,
00336                         REQUEST_ROUTE|FAILURE_ROUTE},
00337 #endif
00338 #ifdef USE_TLS
00339         {"t_relay_to_tls",       w_t_relay_to_tls,        2, fixup_hostport2proxy,
00340                         REQUEST_ROUTE|FAILURE_ROUTE},
00341         {"t_relay_to_tls",       w_t_relay_to_tls_uri,    0, 0,
00342                         REQUEST_ROUTE|FAILURE_ROUTE},
00343 #endif
00344 #ifdef USE_SCTP
00345         {"t_relay_to_sctp",       w_t_relay_to_sctp,       2, fixup_hostport2proxy,
00346                         REQUEST_ROUTE|FAILURE_ROUTE},
00347         {"t_relay_to_sctp",       w_t_relay_to_sctp_uri,    0, 0,
00348                         REQUEST_ROUTE|FAILURE_ROUTE},
00349 #endif
00350         {"t_replicate",        w_t_replicate_uri,       1, fixup_var_str_1,
00351                         REQUEST_ROUTE},
00352         {"t_replicate",        w_t_replicate,           2, fixup_hostport2proxy,
00353                         REQUEST_ROUTE},
00354         {"t_replicate_udp",    w_t_replicate_udp,       2, fixup_hostport2proxy,
00355                         REQUEST_ROUTE},
00356 #ifdef USE_TCP
00357         {"t_replicate_tcp",    w_t_replicate_tcp,       2, fixup_hostport2proxy,
00358                         REQUEST_ROUTE},
00359 #endif
00360 #ifdef USE_TLS
00361         {"t_replicate_tls",    w_t_replicate_tls,       2, fixup_hostport2proxy,
00362                         REQUEST_ROUTE},
00363 #endif
00364 #ifdef USE_SCTP
00365         {"t_replicate_sctp",    w_t_replicate_sctp,     2, fixup_hostport2proxy,
00366                         REQUEST_ROUTE},
00367 #endif
00368         {"t_replicate_to", w_t_replicate_to,            2, fixup_proto_hostport2proxy,
00369                         REQUEST_ROUTE},
00370         {"t_relay",              w_t_relay,               0, 0,
00371                         REQUEST_ROUTE | FAILURE_ROUTE },
00372         {"t_relay",              w_t_relay2,              2, fixup_hostport2proxy,
00373                         REQUEST_ROUTE | FAILURE_ROUTE },
00374         {"t_relay_to_avp", w_t_relay_to_avp,            2, fixup_proto_hostport2proxy,
00375                         REQUEST_ROUTE},
00376         {"t_relay_to",                  w_t_relay_to,           0, 0,
00377                         REQUEST_ROUTE | FAILURE_ROUTE },
00378         {"t_relay_to",                  w_t_relay_to,           1, fixup_t_relay_to,
00379                         REQUEST_ROUTE | FAILURE_ROUTE },
00380         {"t_relay_to",                  w_t_relay_to,           2, fixup_t_relay_to,
00381                         REQUEST_ROUTE | FAILURE_ROUTE },
00382         {"t_forward_nonack",     w_t_forward_nonack,      2, fixup_hostport2proxy,
00383                         REQUEST_ROUTE},
00384         {"t_forward_nonack_uri", w_t_forward_nonack_uri,  0, 0,
00385                         REQUEST_ROUTE},
00386         {"t_forward_nonack_udp", w_t_forward_nonack_udp,  2, fixup_hostport2proxy,
00387                         REQUEST_ROUTE},
00388 #ifdef USE_TCP
00389         {"t_forward_nonack_tcp", w_t_forward_nonack_tcp,  2, fixup_hostport2proxy,
00390                         REQUEST_ROUTE},
00391 #endif
00392 #ifdef USE_TLS
00393         {"t_forward_nonack_tls", w_t_forward_nonack_tls,  2, fixup_hostport2proxy,
00394                         REQUEST_ROUTE},
00395 #endif
00396 #ifdef USE_SCTP
00397         {"t_forward_nonack_sctp", w_t_forward_nonack_sctp, 2, fixup_hostport2proxy,
00398                         REQUEST_ROUTE},
00399 #endif
00400         {"t_forward_nonack_to", w_t_forward_nonack_to,  2, fixup_proto_hostport2proxy,
00401                         REQUEST_ROUTE},
00402         {"t_relay_cancel",     w_t_relay_cancel,        0, 0,
00403                         REQUEST_ROUTE},
00404         {"t_on_failure",       w_t_on_negative,         1, fixup_on_failure,
00405                         REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE | BRANCH_ROUTE },
00406         {"t_on_reply",         w_t_on_reply,            1, fixup_on_reply,
00407                         REQUEST_ROUTE | FAILURE_ROUTE | TM_ONREPLY_ROUTE | BRANCH_ROUTE },
00408         {"t_on_branch",       w_t_on_branch,         1, fixup_on_branch,
00409                         REQUEST_ROUTE | FAILURE_ROUTE },
00410         {"t_check_status",     t_check_status,          1, fixup_t_check_status,
00411                         REQUEST_ROUTE | FAILURE_ROUTE | ONREPLY_ROUTE },
00412         {"t_write_req",       t_write_req,              2, fixup_t_write,
00413                         REQUEST_ROUTE | FAILURE_ROUTE },
00414         {"t_write_unix",      t_write_unix,             2, fixup_t_write,
00415                         REQUEST_ROUTE | FAILURE_ROUTE },
00416         {"t_set_fr",          t_set_fr_inv,             1, fixup_var_int_1,
00417                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00418         {"t_set_fr",          t_set_fr_all,             2, fixup_var_int_12,
00419                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00420         {"t_reset_fr",        w_t_reset_fr,             0, 0,
00421                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00422         {"t_set_retr",        w_t_set_retr,               2, fixup_var_int_12,
00423                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00424         {"t_reset_retr",      w_t_reset_retr,           0, 0,
00425                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00426         {"t_set_max_lifetime", w_t_set_max_lifetime,      2, fixup_var_int_12,
00427                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00428         {"t_reset_max_lifetime", w_t_reset_max_lifetime, 0, 0,
00429                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00430         {"t_set_auto_inv_100", t_set_auto_inv_100,       1, fixup_var_int_1,
00431                                                                                                           REQUEST_ROUTE},
00432         {"t_set_disable_6xx", t_set_disable_6xx,         1, fixup_var_int_1,
00433                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00434         {"t_set_disable_failover", t_set_disable_failover, 1, fixup_var_int_1,
00435                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00436 #ifdef CANCEL_REASON_SUPPORT
00437         {"t_set_no_e2e_cancel_reason", t_set_no_e2e_cancel_reason, 1,
00438                 fixup_var_int_1,
00439                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00440         /* alias for t_set_no_e2e_cancel_reason */
00441         {"t_disable_e2e_cancel_reason", t_set_no_e2e_cancel_reason, 1,
00442                 fixup_var_int_1,
00443                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00444 #endif /* CANCEL_REASON_SUPPORT */
00445         {"t_branch_timeout",  t_branch_timeout,         0, 0,  FAILURE_ROUTE},
00446         {"t_branch_replied",  t_branch_replied,         0, 0,  FAILURE_ROUTE},
00447         {"t_any_timeout",     t_any_timeout,            0, 0, 
00448                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00449         {"t_any_replied",     t_any_replied,            0, 0, 
00450                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00451         {"t_is_canceled",     w_t_is_canceled,          0, 0,
00452                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00453         {"t_is_expired",      t_is_expired,             0, 0,
00454                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00455         {"t_grep_status",     t_grep_status,            1, fixup_var_int_1, 
00456                         REQUEST_ROUTE|TM_ONREPLY_ROUTE|FAILURE_ROUTE|BRANCH_ROUTE },
00457         {"t_drop_replies",    w_t_drop_replies,         0, 0,
00458                         FAILURE_ROUTE},
00459         {"t_drop_replies",    w_t_drop_replies,         1, 0,
00460                         FAILURE_ROUTE},
00461         {"t_save_lumps",      w_t_save_lumps,           0, 0,
00462                         REQUEST_ROUTE},
00463         {"t_check_trans",         w_t_check_trans,                      0, 0,
00464                         REQUEST_ROUTE|ONREPLY_ROUTE|BRANCH_ROUTE },
00465 
00466         {"t_load_contacts", t_load_contacts,            0, 0,
00467                         REQUEST_ROUTE | FAILURE_ROUTE},
00468         {"t_next_contacts", t_next_contacts,            0, 0,
00469                         REQUEST_ROUTE | FAILURE_ROUTE},
00470 
00471         /* not applicable from the script */
00472         {"load_tm",            (cmd_function)load_tm,           NO_SCRIPT,   0, 0},
00473         {"load_xtm",           (cmd_function)load_xtm,          NO_SCRIPT,   0, 0},
00474         {0,0,0,0,0}
00475 };
00476 
00477 
00478 static param_export_t params[]={
00479         {"ruri_matching",       PARAM_INT, &default_tm_cfg.ruri_matching         },
00480         {"via1_matching",       PARAM_INT, &default_tm_cfg.via1_matching         },
00481         {"fr_timer",            PARAM_INT, &default_tm_cfg.fr_timeout            },
00482         {"fr_inv_timer",        PARAM_INT, &default_tm_cfg.fr_inv_timeout        },
00483         {"wt_timer",            PARAM_INT, &default_tm_cfg.wait_timeout          },
00484         {"delete_timer",        PARAM_INT, &default_tm_cfg.delete_timeout        },
00485         {"retr_timer1",         PARAM_INT, &default_tm_cfg.rt_t1_timeout_ms      },
00486         {"retr_timer2"  ,       PARAM_INT, &default_tm_cfg.rt_t2_timeout_ms      },
00487         {"max_inv_lifetime",    PARAM_INT, &default_tm_cfg.tm_max_inv_lifetime   },
00488         {"max_noninv_lifetime", PARAM_INT, &default_tm_cfg.tm_max_noninv_lifetime},
00489         {"noisy_ctimer",        PARAM_INT, &default_tm_cfg.noisy_ctimer          },
00490         {"auto_inv_100",        PARAM_INT, &default_tm_cfg.tm_auto_inv_100       },
00491         {"auto_inv_100_reason", PARAM_STRING, &default_tm_cfg.tm_auto_inv_100_r  },
00492         {"unix_tx_timeout",     PARAM_INT, &default_tm_cfg.tm_unix_tx_timeout    },
00493         {"restart_fr_on_each_reply", PARAM_INT,
00494                                                                         &default_tm_cfg.restart_fr_on_each_reply},
00495         {"fr_timer_avp",        PARAM_STRING, &fr_timer_param                    },
00496         {"fr_inv_timer_avp",    PARAM_STRING, &fr_inv_timer_param                },
00497         {"tw_append",           PARAM_STRING|PARAM_USE_FUNC, 
00498                                                                                                         (void*)parse_tw_append   },
00499         {"pass_provisional_replies", PARAM_INT, 
00500                                                                         &default_tm_cfg.pass_provisional_replies },
00501         {"aggregate_challenges", PARAM_INT, &default_tm_cfg.tm_aggregate_auth    },
00502         {"unmatched_cancel",    PARAM_INT, &default_tm_cfg.unmatched_cancel      },
00503         {"default_code",        PARAM_INT, &default_tm_cfg.default_code          },
00504         {"default_reason",      PARAM_STRING, &default_tm_cfg.default_reason     },
00505         {"reparse_invite",      PARAM_INT, &default_tm_cfg.reparse_invite        },
00506         {"ac_extra_hdrs",       PARAM_STR, &default_tm_cfg.ac_extra_hdrs         },
00507         {"blst_503",            PARAM_INT, &default_tm_cfg.tm_blst_503           },
00508         {"blst_503_def_timeout",PARAM_INT, &default_tm_cfg.tm_blst_503_default   },
00509         {"blst_503_min_timeout",PARAM_INT, &default_tm_cfg.tm_blst_503_min       },
00510         {"blst_503_max_timeout",PARAM_INT, &default_tm_cfg.tm_blst_503_max       },
00511         {"blst_methods_add",    PARAM_INT, &default_tm_cfg.tm_blst_methods_add   },
00512         {"blst_methods_lookup", PARAM_INT, &default_tm_cfg.tm_blst_methods_lookup},
00513         {"cancel_b_method",     PARAM_INT, &default_tm_cfg.cancel_b_flags},
00514         {"reparse_on_dns_failover", PARAM_INT, &default_tm_cfg.reparse_on_dns_failover},
00515         {"on_sl_reply",         PARAM_STRING|PARAM_USE_FUNC, fixup_on_sl_reply   },
00516         {"contacts_avp",        PARAM_STRING, &contacts_avp_param                },
00517         {"disable_6xx_block",   PARAM_INT, &default_tm_cfg.disable_6xx           },
00518         {"local_ack_mode",      PARAM_INT, &default_tm_cfg.local_ack_mode        },
00519         {"failure_reply_mode",  PARAM_INT, &failure_reply_mode                   },
00520         {"faked_reply_prio",    PARAM_INT, &faked_reply_prio                     },
00521 #ifdef CANCEL_REASON_SUPPORT
00522         {"local_cancel_reason", PARAM_INT, &default_tm_cfg.local_cancel_reason   },
00523         {"e2e_cancel_reason",   PARAM_INT, &default_tm_cfg.e2e_cancel_reason     },
00524 #endif /* CANCEL_REASON_SUPPORT */
00525         {0,0,0}
00526 };
00527 
00528 #ifdef STATIC_TM
00529 struct module_exports tm_exports = {
00530 #else
00531 struct module_exports exports= {
00532 #endif
00533         "tm",
00534         /* -------- exported functions ----------- */
00535         cmds,
00536         tm_rpc,    /* RPC methods */
00537         /* ------------ exported variables ---------- */
00538         params,
00539 
00540         mod_init, /* module initialization function */
00541         (response_function) reply_received,
00542         (destroy_function) tm_shutdown,
00543         0, /* w_onbreak, */
00544         child_init /* per-child init function */
00545 };
00546 
00547 
00548 
00549 /* helper for fixup_on_* */
00550 static int fixup_routes(char* r_type, struct route_list* rt, void** param)
00551 {
00552         int i;
00553         
00554         i=route_get(rt, (char*)*param);
00555         if (i==-1){
00556                 LOG(L_ERR, "ERROR: tm: fixup_routes: route_get failed\n");
00557                 return E_UNSPEC;
00558         }
00559         if (r_type && rt->rlist[i]==0){
00560                 LOG(L_WARN, "WARNING: %s(\"%s\"): empty/non existing route\n",
00561                                 r_type, (char*)*param);
00562         }
00563         *param=(void*)(long)i;
00564         return 0;
00565 }
00566 
00567 static int fixup_t_reply(void** param, int param_no)
00568 {
00569         if (param_no == 1) {
00570                 if (fixup_var_int_12(param, 1) != 0) return -1;
00571         } else if (param_no == 2) {
00572                 return fixup_var_str_12(param, 2);
00573         }
00574     return 0;
00575 }
00576 
00577 static int fixup_on_failure(void** param, int param_no)
00578 {
00579         if (param_no==1){
00580                 if(strlen((char*)*param)<=1
00581                                 && (*(char*)(*param)==0 || *(char*)(*param)=='0')) {
00582                         *param = (void*)0;
00583                         return 0;
00584                 }
00585                 return fixup_routes("t_on_failure", &failure_rt, param);
00586         }
00587         return 0;
00588 }
00589 
00590 
00591 
00592 static int fixup_on_reply(void** param, int param_no)
00593 {
00594         if (param_no==1){
00595                 if(strlen((char*)*param)<=1
00596                                 && (*(char*)(*param)==0 || *(char*)(*param)=='0')) {
00597                         *param = (void*)0;
00598                         return 0;
00599                 }
00600                 return fixup_routes("t_on_reply", &onreply_rt, param);
00601         }
00602         return 0;
00603 }
00604 
00605 
00606 
00607 static int fixup_on_branch(void** param, int param_no)
00608 {
00609         if (param_no==1){
00610                 if(strlen((char*)*param)<=1
00611                                 && (*(char*)(*param)==0 || *(char*)(*param)=='0')) {
00612                         *param = (void*)0;
00613                         return 0;
00614                 }
00615                 return fixup_routes("t_on_branch", &branch_rt, param);
00616         }
00617         return 0;
00618 }
00619 
00620 static int fixup_on_sl_reply(modparam_t type, void* val)
00621 {
00622         if ((type & PARAM_STRING) == 0) {
00623                 LOG(L_ERR, "ERROR: tm: fixup_on_sl_reply: not a string parameter\n");
00624                 return -1;
00625         }
00626 
00627         if (fixup_routes(0, &onreply_rt, &val))
00628                 return -1;
00629 
00630         goto_on_sl_reply = (int)(long)val;
00631         return 0;
00632 }
00633 
00634 
00635 
00636 /* (char *hostname, char *port_nr) ==> (struct proxy_l *, -)  */
00637 static int fixup_hostport2proxy(void** param, int param_no)
00638 {
00639         unsigned int port;
00640         char *host;
00641         int err;
00642         struct proxy_l *proxy;
00643         action_u_t *a;
00644         str s;
00645 
00646         DBG("TM module: fixup_hostport2proxy(%s, %d)\n", (char*)*param, param_no);
00647         if (param_no==1){
00648                 return 0;
00649         } else if (param_no==2) {
00650                 a = fixup_get_param(param, param_no, 1);
00651                 host= a->u.string;
00652                 port=str2s(*param, strlen(*param), &err);
00653                 if (err!=0) {
00654                         LOG(L_ERR, "TM module:fixup_hostport2proxy: bad port number <%s>\n",
00655                                 (char*)(*param));
00656                          return E_UNSPEC;
00657                 }
00658                 s.s = host;
00659                 s.len = strlen(host);
00660                 proxy=mk_proxy(&s, port, 0); /* FIXME: udp or tcp? */
00661                 if (proxy==0) {
00662                         LOG(L_ERR, "ERROR: fixup_hostport2proxy: bad host name in URI <%s>\n",
00663                                 host );
00664                         return E_BAD_ADDRESS;
00665                 }
00666                 /* success -- fix the first parameter to proxy now ! */
00667 
00668                 a->u.data=proxy;
00669                 return 0;
00670         } else {
00671                 LOG(L_ERR,"ERROR: fixup_hostport2proxy called with parameter #<>{1,2}\n");
00672                 return E_BUG;
00673         }
00674 }
00675 
00676 /* (char *$proto, char *$host:port) ==> (fparam, fparam)  */
00677 static int fixup_proto_hostport2proxy(void** param, int param_no) {
00678         int ret;
00679 
00680         ret = fix_param(FPARAM_AVP, param);
00681         if (ret <= 0) return ret;
00682 /*      if (param_no = 1) {             FIXME: param_str currently does not offer INT/STR overloading
00683                 ret = fix_param(FPARAM_INT, param);
00684                 if (ret <= 0) return ret;
00685         } */
00686         if (fix_param(FPARAM_STRING, param) != 0) return -1;
00687         return 0;
00688 }
00689 
00690 
00691 static int fixup_t_check_status(void** param, int param_no)
00692 {
00693         int ret;
00694 
00695         ret = fix_param(FPARAM_AVP, param);
00696         if (ret <= 0) return ret;
00697 
00698         ret = fix_param(FPARAM_SELECT, param);
00699         if (ret <= 0) return ret;
00700 
00701         if (fix_param(FPARAM_REGEX, param) != 0) return -1;
00702         return 0;
00703 }
00704 
00705 
00706 /***************************** init functions *****************************/
00707 static int w_t_unref( struct sip_msg *foo, unsigned int flags, void *bar)
00708 {
00709         return t_unref(foo);
00710 }
00711 
00712 
00713 static int script_init( struct sip_msg *foo, unsigned int flags, void *bar)
00714 {
00715         /* we primarily reset all private memory here to make sure
00716          * private values left over from previous message will
00717          * not be used again */
00718 
00719         /* make sure the new message will not inherit previous
00720                 message's t_on_negative value
00721         */
00722         t_on_negative( 0 );
00723         t_on_reply(0);
00724         t_on_branch(0);
00725         /* reset the kr status */
00726         reset_kr();
00727         /* set request mode so that multiple-mode actions know
00728          * how to behave */
00729         set_route_type(REQUEST_ROUTE);
00730         lumps_are_cloned = 0;
00731         return 1;
00732 }
00733 
00734 
00735 static int mod_init(void)
00736 {
00737         DBG( "TM - (sizeof cell=%ld, sip_msg=%ld) initializing...\n",
00738                         (long)sizeof(struct cell), (long)sizeof(struct sip_msg));
00739 
00740         /* checking if we have sufficient bitmap capacity for given
00741            maximum number of  branches */
00742         if (MAX_BRANCHES+1>31) {
00743                 LOG(L_CRIT, "Too many max UACs for UAC branch_bm_t bitmap: %d\n",
00744                         MAX_BRANCHES );
00745                 return -1;
00746         }
00747 
00748         if (init_callid() < 0) {
00749                 LOG(L_CRIT, "Error while initializing Call-ID generator\n");
00750                 return -1;
00751         }
00752 
00753         /* building the hash table*/
00754         if (!init_hash_table()) {
00755                 LOG(L_ERR, "ERROR: mod_init: initializing hash_table failed\n");
00756                 return -1;
00757         }
00758 
00759         /* init static hidden values */
00760         init_t();
00761 
00762         if (tm_init_selects()==-1) {
00763                 LOG(L_ERR, "ERROR: mod_init: select init failed\n");
00764                 return -1;
00765         }
00766 
00767         /* the default timer values must be fixed-up before
00768          * declaring the configuration (Miklos) */
00769         if (tm_init_timers()==-1) {
00770                 LOG(L_ERR, "ERROR: mod_init: timer init failed\n");
00771                 return -1;
00772         }
00773         
00774         /* the cancel branch flags must be fixed before declaring the 
00775          * configuration */
00776         if (cancel_b_flags_get(&default_tm_cfg.cancel_b_flags, 
00777                                                         default_tm_cfg.cancel_b_flags)<0){
00778                 LOG(L_ERR, "ERROR: mod_init: bad cancel branch method\n");
00779                 return -1;
00780         }
00781 
00782 #ifdef USE_DNS_FAILOVER
00783         if (default_tm_cfg.reparse_on_dns_failover && mhomed) {
00784                 LOG(L_WARN, "WARNING: mod_init: "
00785                         "reparse_on_dns_failover is enabled on a "
00786                         "multihomed host -- check the readme of tm module!\n");
00787         }
00788 #endif
00789 
00790         /* declare the configuration */
00791         if (cfg_declare("tm", tm_cfg_def, &default_tm_cfg, cfg_sizeof(tm),
00792                          &tm_cfg)) {
00793                 LOG(L_ERR, "ERROR: mod_init: failed to declare the configuration\n");
00794                 return -1;
00795         }
00796 
00797              /* First tm_stat initialization function only allocates the top level stat
00798               * structure in shared memory, the initialization will complete in child
00799               * init with init_tm_stats_child when the final value of estimated_process_count is
00800               * known
00801               */
00802         if (init_tm_stats() < 0) {
00803                 LOG(L_CRIT, "ERROR: mod_init: failed to init stats\n");
00804                 return -1;
00805         }
00806 
00807         if (uac_init()==-1) {
00808                 LOG(L_ERR, "ERROR: mod_init: uac_init failed\n");
00809                 return -1;
00810         }
00811 
00812         if (init_tmcb_lists()!=1) {
00813                 LOG(L_CRIT, "ERROR:tm:mod_init: failed to init tmcb lists\n");
00814                 return -1;
00815         }
00816         
00817         tm_init_tags();
00818         init_twrite_lines();
00819         if (init_twrite_sock() < 0) {
00820                 LOG(L_ERR, "ERROR:tm:mod_init: Unable to create socket\n");
00821                 return -1;
00822         }
00823 
00824         /* register post-script clean-up function */
00825         if (register_script_cb( w_t_unref, POST_SCRIPT_CB|REQUEST_CB, 0)<0 ) {
00826                 LOG(L_ERR,"ERROR:tm:mod_init: failed to register POST request "
00827                         "callback\n");
00828                 return -1;
00829         }
00830         if (register_script_cb( script_init, PRE_SCRIPT_CB|REQUEST_CB , 0)<0 ) {
00831                 LOG(L_ERR,"ERROR:tm:mod_init: failed to register PRE request "
00832                         "callback\n");
00833                 return -1;
00834         }
00835 
00836         if (init_avp_params( fr_timer_param, fr_inv_timer_param,
00837                                                  contacts_avp_param)<0 ){
00838                 LOG(L_ERR,"ERROR:tm:mod_init: failed to process AVP params\n");
00839                 return -1;
00840         }
00841 #ifdef WITH_EVENT_LOCAL_REQUEST
00842         goto_on_local_req=route_lookup(&event_rt, "tm:local-request");
00843         if (goto_on_local_req>=0 && event_rt.rlist[goto_on_local_req]==0)
00844                 goto_on_local_req=-1; /* disable */
00845         if (goto_on_local_req>=0)
00846                 set_child_rpc_sip_mode();
00847 #endif /* WITH_EVENT_LOCAL_REQUEST */
00848         if (goto_on_sl_reply && onreply_rt.rlist[goto_on_sl_reply]==0)
00849                 WARN("empty/non existing on_sl_reply route\n");
00850         tm_init = 1;
00851         return 0;
00852 }
00853 
00854 static int child_init(int rank)
00855 {
00856         if (rank == PROC_INIT) {
00857                 /* we must init stats when rank==PROC_INIT: after mod_init we know
00858                  * the exact number of processes and we must init the shared structure
00859                  * before any other process is starting (or else some new process
00860                  * might try to use the stats before the stats array is allocated) */
00861                 if (init_tm_stats_child() < 0) {
00862                         ERR("Error while initializing tm statistics structures\n");
00863                         return -1;
00864                 }
00865         }else if (child_init_callid(rank) < 0) { 
00866                 /* don't init callid for PROC_INIT*/
00867                 LOG(L_ERR, "ERROR: child_init: Error while initializing Call-ID"
00868                                 " generator\n");
00869                 return -2;
00870         }
00871         return 0;
00872 }
00873 
00874 
00875 
00876 
00877 
00878 /**************************** wrapper functions ***************************/
00879 static int t_check_status(struct sip_msg* msg, char *p1, char *foo)
00880 {
00881         regmatch_t pmatch;
00882         struct cell *t;
00883         char *status, *s = NULL;
00884         char backup;
00885         int lowest_status, n, ret;
00886         fparam_t* fp;
00887         regex_t* re = NULL;
00888         str tmp;
00889         
00890         fp = (fparam_t*)p1;
00891         t = 0;
00892         /* first get the transaction */
00893         if (t_check(msg, 0 ) == -1) return -1;
00894         if ((t = get_t()) == 0) {
00895                 LOG(L_ERR, "ERROR: t_check_status: cannot check status for a reply "
00896                         "which has no T-state established\n");
00897                 goto error;
00898         }
00899         backup = 0;
00900         
00901         switch(fp->type) {
00902         case FPARAM_REGEX:
00903                 re = fp->v.regex;
00904                 break;
00905                 
00906         default:
00907                 /* AVP or select, get the value and compile the regex */
00908                 if (get_str_fparam(&tmp, msg, fp) < 0) goto error;
00909                 s = pkg_malloc(tmp.len + 1);
00910                 if (s == NULL) {
00911                         ERR("Out of memory\n");
00912                         goto error;
00913                 }
00914                 memcpy(s, tmp.s, tmp.len);
00915                 s[tmp.len] = '\0';
00916                 
00917                 if ((re = pkg_malloc(sizeof(regex_t))) == 0) {
00918                         ERR("No memory left\n");
00919                         goto error;
00920                 }
00921                 
00922                 if (regcomp(re, s, REG_EXTENDED|REG_ICASE|REG_NEWLINE)) {
00923                         ERR("Bad regular expression '%s'\n", s);
00924                         goto error;
00925                 }
00926                 break;
00927         }
00928         
00929         switch(get_route_type()) {
00930         case REQUEST_ROUTE:
00931                 /* use the status of the last sent reply */
00932                 status = int2str( t->uas.status, 0);
00933                 break;
00934                 
00935         case TM_ONREPLY_ROUTE:
00936         case CORE_ONREPLY_ROUTE:
00937                 /* use the status of the current reply */
00938                 status = msg->first_line.u.reply.status.s;
00939                 backup = status[msg->first_line.u.reply.status.len];
00940                 status[msg->first_line.u.reply.status.len] = 0;
00941                 break;
00942 
00943         case FAILURE_ROUTE:
00944                 /* use the status of the winning reply */
00945                 ret = t_pick_branch( -1, 0, t, &lowest_status);
00946                 if (ret == -1) {
00947                         /* t_pick_branch() retuns error also when there are only
00948                          * blind UACs. Let us give it another chance including the
00949                          * blind branches. */
00950                         LOG(L_DBG, "DEBUG: t_check_status: t_pick_branch returned error, "
00951                                 "trying t_pick_branch_blind\n");
00952                         ret = t_pick_branch_blind(t, &lowest_status);
00953                 }
00954                 if (ret < 0) {
00955                         LOG(L_CRIT,"BUG:t_check_status: t_pick_branch failed to get "
00956                                 " a final response in FAILURE_ROUTE\n");
00957                         goto error;
00958                 }
00959                 status = int2str( lowest_status , 0);
00960                 break;
00961 
00962         default:
00963                 LOG(L_ERR,"ERROR:t_check_status: unsupported route type %d\n",
00964                                 get_route_type());
00965                 goto error;
00966         }
00967 
00968         DBG("DEBUG:t_check_status: checked status is <%s>\n",status);
00969         /* do the checking */
00970         n = regexec(re, status, 1, &pmatch, 0);
00971 
00972         if (backup) status[msg->first_line.u.reply.status.len] = backup;
00973         if (s) pkg_free(s);
00974         if ((fp->type != FPARAM_REGEX) && re) {
00975                 regfree(re);
00976                 pkg_free(re);
00977         }
00978         
00979         if (unlikely(t && is_route_type(CORE_ONREPLY_ROUTE))){
00980                 /* t_check() above has the side effect of setting T and
00981                    REFerencing T => we must unref and unset it.  */
00982                 UNREF( t );
00983                 set_t(T_UNDEFINED, T_BR_UNDEFINED);
00984         }
00985         if (n!=0) return -1;
00986         return 1;
00987 
00988  error:
00989         if (unlikely(t && is_route_type(CORE_ONREPLY_ROUTE))){
00990                 /* t_check() above has the side effect of setting T and
00991                    REFerencing T => we must unref and unset it.  */
00992                 UNREF( t );
00993                 set_t(T_UNDEFINED, T_BR_UNDEFINED);
00994         }
00995         if (s) pkg_free(s);
00996         if ((fp->type != FPARAM_REGEX) && re) {
00997                 regfree(re);
00998                 pkg_free(re);
00999         }
01000         return -1;
01001 }
01002 
01003 
01004 inline static int w_t_check(struct sip_msg* msg, char* str, char* str2)
01005 {
01006         return (t_check_msg( msg , 0  )==1) ? 1 : -1;
01007 }
01008 
01009 inline static int w_t_lookup_cancel(struct sip_msg* msg, char* str, char* str2)
01010 {
01011         struct cell *ret;
01012         int i=0;
01013         if (msg->REQ_METHOD==METHOD_CANCEL) {
01014                 ret = t_lookupOriginalT( msg );
01015                 DBG("lookup_original: t_lookupOriginalT returned: %p\n", ret);
01016                 if (ret != T_NULL_CELL) {
01017                         /* If the parameter is set to 1, overwrite the message flags of
01018                          * the CANCEL with the flags of the INVITE */
01019                         if (str && (get_int_fparam(&i, msg, (fparam_t*)str)==0) && i)
01020                                 msg->flags = ret->uas.request->flags;
01021 
01022                         /* The cell is reffed by t_lookupOriginalT, but T is not set.
01023                         So we must unref it before returning. */
01024                         UNREF(ret);
01025                         return 1;
01026                 }
01027         } else {
01028                 LOG(L_WARN, "WARNING: script error t_lookup_cancel() called for non-CANCEL request\n");
01029         }
01030         return -1;
01031 }
01032 
01033 inline static int str2proto(char *s, int len) {
01034         if (len == 3 && !strncasecmp(s, "udp", 3))
01035                 return PROTO_UDP;
01036         else if (len == 3 && !strncasecmp(s, "tcp", 3))  /* tcp&tls checks will be passed in getproto() */
01037                 return PROTO_TCP;
01038         else if (len == 3 && !strncasecmp(s, "tls", 3))
01039                 return PROTO_TLS;       
01040         else if (len == 4 && !strncasecmp(s, "sctp", 4))
01041                 return PROTO_SCTP;
01042         else
01043                 return PROTO_NONE;
01044 }
01045 
01046 inline static struct proxy_l* t_protoaddr2proxy(char *proto_par, char *addr_par) {
01047         struct proxy_l *proxy = 0;
01048         avp_t* avp;
01049         avp_value_t val;
01050         int proto, port, err;
01051         str s;
01052         char *c;
01053         
01054         switch(((fparam_t *)proto_par)->type) {
01055         case FPARAM_AVP:
01056                 if (!(avp = search_first_avp(((fparam_t *)proto_par)->v.avp.flags, ((fparam_t *)proto_par)->v.avp.name, &val, 0))) {
01057                         proto = PROTO_NONE;
01058                 } else {
01059                         if (avp->flags & AVP_VAL_STR) {
01060                                 proto = str2proto(val.s.s, val.s.len);
01061                         }
01062                         else {
01063                                 proto = val.n;
01064                         }
01065                 }
01066                 break;
01067 
01068         case FPARAM_INT:
01069                 proto = ((fparam_t *)proto_par)->v.i;
01070                 break;
01071         case FPARAM_STRING:
01072                 proto = str2proto( ((fparam_t *)proto_par)->v.asciiz, strlen(((fparam_t *)proto_par)->v.asciiz));
01073                 break;
01074         default:
01075                 ERR("BUG: Invalid proto parameter value in t_protoaddr2proxy\n");
01076                 return 0;
01077         }
01078 
01079 
01080         switch(((fparam_t *)addr_par)->type) {
01081         case FPARAM_AVP:
01082                 if (!(avp = search_first_avp(((fparam_t *)addr_par)->v.avp.flags, ((fparam_t *)addr_par)->v.avp.name, &val, 0))) {
01083                         s.len = 0;
01084                 } else {
01085                         if ((avp->flags & AVP_VAL_STR) == 0) {
01086                                 LOG(L_ERR, "tm:t_protoaddr2proxy: avp <%.*s> value is not string\n",
01087                                         ((fparam_t *)addr_par)->v.avp.name.s.len, ((fparam_t *)addr_par)->v.avp.name.s.s);
01088                                 return 0;
01089                         }
01090                         s = val.s;
01091                 }
01092                 break;
01093 
01094         case FPARAM_STRING:
01095                 s.s = ((fparam_t *) addr_par)->v.asciiz;
01096                 s.len = strlen(s.s);
01097                 break;
01098 
01099         default:
01100                 ERR("BUG: Invalid addr parameter value in t_protoaddr2proxy\n");
01101                 return 0;
01102         }
01103 
01104         port = 5060;
01105         if (s.len) {
01106                 c = memchr(s.s, ':', s.len);
01107                 if (c) {
01108                         port = str2s(c+1, s.len-(c-s.s+1), &err);
01109                         if (err!=0) {
01110                                 LOG(L_ERR, "tm:t_protoaddr2proxy: bad port number <%.*s>\n",
01111                                         s.len, s.s);
01112                                  return 0;
01113                         }
01114                         s.len = c-s.s;
01115                 }
01116         }
01117         if (!s.len) {
01118                 LOG(L_ERR, "tm: protoaddr2proxy: host name is empty\n");
01119                 return 0;
01120         }
01121         proxy=mk_proxy(&s, port, proto);
01122         if (proxy==0) {
01123                 LOG(L_ERR, "tm: protoaddr2proxy: bad host name in URI <%.*s>\n",
01124                         s.len, s.s );
01125                 return 0;
01126         }
01127         return proxy;
01128 }
01129 
01130 inline static int _w_t_forward_nonack(struct sip_msg* msg, struct proxy_l* proxy,
01131         int proto)
01132 {
01133         struct cell *t;
01134         if (t_check( msg , 0 )==-1) {
01135                 LOG(L_ERR, "ERROR: forward_nonack: "
01136                                 "can't forward when no transaction was set up\n");
01137                 return -1;
01138         }
01139         t=get_t();
01140         if ( t && t!=T_UNDEFINED ) {
01141                 if (msg->REQ_METHOD==METHOD_ACK) {
01142                         LOG(L_WARN,"WARNING: you don't really want to fwd hbh ACK\n");
01143                         return -1;
01144                 }
01145                 return t_forward_nonack(t, msg, proxy, proto );
01146         } else {
01147                 DBG("DEBUG: forward_nonack: no transaction found\n");
01148                 return -1;
01149         }
01150 }
01151 
01152 
01153 inline static int w_t_forward_nonack( struct sip_msg* msg, char* proxy,
01154                                                                                 char* foo)
01155 {
01156         return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_NONE);
01157 }
01158 
01159 
01160 inline static int w_t_forward_nonack_uri(struct sip_msg* msg, char *foo,
01161                                                                                                                                         char *bar)
01162 {
01163         return _w_t_forward_nonack(msg, 0, PROTO_NONE);
01164 }
01165 
01166 
01167 inline static int w_t_forward_nonack_udp( struct sip_msg* msg, char* proxy,
01168                                                                                 char* foo)
01169 {
01170         return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_UDP);
01171 }
01172 
01173 
01174 #ifdef USE_TCP
01175 inline static int w_t_forward_nonack_tcp( struct sip_msg* msg, char* proxy,
01176                                                                                 char* foo)
01177 {
01178         return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_TCP);
01179 }
01180 #endif
01181 
01182 
01183 #ifdef USE_TLS
01184 inline static int w_t_forward_nonack_tls( struct sip_msg* msg, char* proxy,
01185                                                                                 char* foo)
01186 {
01187         return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_TLS);
01188 }
01189 #endif
01190 
01191 
01192 #ifdef USE_SCTP
01193 inline static int w_t_forward_nonack_sctp( struct sip_msg* msg, char* proxy,
01194                                                                                 char* foo)
01195 {
01196         return _w_t_forward_nonack(msg, ( struct proxy_l *) proxy, PROTO_SCTP);
01197 }
01198 #endif
01199 
01200 
01201 inline static int w_t_forward_nonack_to( struct sip_msg  *p_msg ,
01202         char *proto_par, 
01203         char *addr_par   )
01204 {
01205         struct proxy_l *proxy;
01206         int r = -1;
01207         proxy = t_protoaddr2proxy(proto_par, addr_par);
01208         if (proxy) {
01209                 r = _w_t_forward_nonack(p_msg, proxy, proxy->proto);            
01210                 free_proxy(proxy);
01211                 pkg_free(proxy);
01212         }
01213         return r;
01214 }
01215 
01216 
01217 inline static int w_t_reply(struct sip_msg* msg, char* p1, char* p2)
01218 {
01219         struct cell *t;
01220         int code, ret = -1;
01221         str reason;
01222         char* r;
01223 
01224         if (msg->REQ_METHOD==METHOD_ACK) {
01225                 LOG(L_WARN, "WARNING: t_reply: ACKs are not replied\n");
01226                 return -1;
01227         }
01228         if (t_check( msg , 0 )==-1) return -1;
01229         t=get_t();
01230         if (!t) {
01231                 LOG(L_ERR, "ERROR: t_reply: cannot send a t_reply to a message "
01232                         "for which no T-state has been established\n");
01233                 return -1;
01234         }
01235 
01236         if (get_int_fparam(&code, msg, (fparam_t*)p1) < 0) {
01237             code = cfg_get(tm, tm_cfg, default_code);
01238         }
01239         
01240         if (get_str_fparam(&reason, msg, (fparam_t*)p2) < 0) {
01241                 r = cfg_get(tm, tm_cfg, default_reason);
01242         } else {
01243                 r = as_asciiz(&reason);
01244                 if (r == NULL) r = cfg_get(tm, tm_cfg, default_reason);
01245         }
01246         
01247         /* if called from reply_route, make sure that unsafe version
01248          * is called; we are already in a mutex and another mutex in
01249          * the safe version would lead to a deadlock
01250          */
01251          
01252         if (is_route_type(FAILURE_ROUTE)) {
01253                 DBG("DEBUG: t_reply_unsafe called from w_t_reply\n");
01254                 ret = t_reply_unsafe(t, msg, code, r);
01255         } else if (is_route_type(REQUEST_ROUTE)) {
01256                 ret = t_reply( t, msg, code, r);
01257         } else if (is_route_type(ONREPLY_ROUTE)) {
01258                 if (likely(t->uas.request)){
01259                         if (is_route_type(CORE_ONREPLY_ROUTE))
01260                                 ret=t_reply(t, t->uas.request, code, r);
01261                         else
01262                                 ret=t_reply_unsafe(t, t->uas.request, code, r);
01263                 }else
01264                         ret=-1;
01265                 /* t_check() above has the side effect of setting T and
01266                    REFerencing T => we must unref and unset it.
01267                    Note: this is needed only in the CORE_ONREPLY_ROUTE and not also in
01268                    the TM_ONREPLY_ROUTE.
01269                  */
01270                 if (is_route_type(CORE_ONREPLY_ROUTE)) {
01271                         UNREF( t );
01272                         set_t(T_UNDEFINED, T_BR_UNDEFINED);
01273                 }
01274         } else {
01275                 LOG(L_CRIT, "BUG: w_t_reply entered in unsupported mode\n");
01276                 ret = -1;
01277         }
01278 
01279         if (r && (r != cfg_get(tm, tm_cfg, default_reason))) pkg_free(r);
01280         return ret;
01281 }
01282 
01283 
01284 inline static int w_t_release(struct sip_msg* msg, char* str, char* str2)
01285 {
01286         struct cell *t;
01287         int ret;
01288         
01289         if(get_route_type()!=REQUEST_ROUTE)
01290         {
01291                 LM_INFO("invalid usage - not in request route\n");
01292                 return -1;
01293         }
01294 
01295         if (t_check( msg  , 0  )==-1) return -1;
01296         t=get_t();
01297         if ( t && t!=T_UNDEFINED ) {
01298                 ret = t_release_transaction( t );
01299                 t_unref(msg);
01300                 return ret;
01301         }
01302         return 1;
01303 }
01304 
01305 
01306 inline static int w_t_retransmit_reply( struct sip_msg* p_msg, char* foo, char* bar)
01307 {
01308         struct cell *t;
01309 
01310 
01311         if (t_check( p_msg  , 0 )==-1)
01312                 return 1;
01313         t=get_t();
01314         if (t) {
01315                 if (p_msg->REQ_METHOD==METHOD_ACK) {
01316                         LOG(L_WARN, "WARNING: : ACKs transmit_replies not replied\n");
01317                         return -1;
01318                 }
01319                 return t_retransmit_reply( t );
01320         } else
01321                 return -1;
01322 }
01323 
01324 
01325 inline static int w_t_newtran( struct sip_msg* p_msg, char* foo, char* bar )
01326 {
01327         /* t_newtran returns 0 on error (negative value means
01328            'transaction exists' */
01329         int ret;
01330         ret = t_newtran( p_msg );
01331         if (ret==E_SCRIPT) {
01332                 LOG(L_ERR, "ERROR: t_newtran: "
01333                         "transaction already in process %p\n", get_t() );
01334         }
01335         return ret;
01336 }
01337 
01338 
01339 inline static int w_t_on_negative( struct sip_msg* msg, char *go_to, char *foo)
01340 {
01341         t_on_negative( (unsigned int )(long) go_to );
01342         return 1;
01343 }
01344 
01345 inline static int w_t_on_branch( struct sip_msg* msg, char *go_to, char *foo)
01346 {
01347         t_on_branch( (unsigned int )(long) go_to );
01348         return 1;
01349 }
01350 
01351 
01352 inline static int w_t_on_reply( struct sip_msg* msg, char *go_to, char *foo )
01353 {
01354         t_on_reply( (unsigned int )(long) go_to );
01355         return 1;
01356 }
01357 
01358 
01359 
01360 inline static int _w_t_relay_to(struct sip_msg  *p_msg ,
01361                                                                         struct proxy_l *proxy, int force_proto)
01362 {
01363         struct cell *t;
01364         int res;
01365 
01366         if (is_route_type(FAILURE_ROUTE)) {
01367                 t=get_t();
01368                 if (!t || t==T_UNDEFINED) {
01369                         LOG(L_CRIT, "BUG: w_t_relay_to: undefined T\n");
01370                         return -1;
01371                 }
01372                 res = t_forward_nonack(t, p_msg, proxy, force_proto);
01373                 if (res <= 0) {
01374                         if (res != E_CFG) {
01375                             LOG(L_ERR, "ERROR: w_t_relay_to: t_relay_to failed\n");
01376                             /* let us save the error code, we might need it later
01377                                when the failure_route has finished (Miklos) */
01378                         }
01379                         tm_error=ser_error;
01380                         return -1;
01381                 }
01382                 return 1;
01383         }
01384         if (is_route_type(REQUEST_ROUTE))
01385                 return t_relay_to( p_msg, proxy, force_proto,
01386                                                         0 /* no replication */ );
01387         LOG(L_CRIT, "ERROR: w_t_relay_to: unsupported route type: %d\n",
01388                         get_route_type());
01389         return 0;
01390 }
01391 
01392 
01393 inline static int w_t_relay_to_udp( struct sip_msg  *p_msg ,
01394                                                                         char *proxy,/* struct proxy_l * expected */
01395                                                                         char *_foo       /* nothing expected */ )
01396 {
01397         return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_UDP);
01398 }
01399 
01400 /* forward to uri, but force udp as transport */
01401 inline static int w_t_relay_to_udp_uri( struct sip_msg  *p_msg ,
01402                                                                                 char *_foo, char *_bar   )
01403 {
01404         return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_UDP);
01405 }
01406 
01407 
01408 #ifdef USE_TCP
01409 inline static int w_t_relay_to_tcp( struct sip_msg  *p_msg ,
01410                                                                         char *proxy, /* struct proxy_l* */
01411                                                                         char *_foo       /* nothing expected */ )
01412 {
01413         return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TCP);
01414 }
01415 
01416 /* forward to uri, but force tcp as transport */
01417 inline static int w_t_relay_to_tcp_uri( struct sip_msg  *p_msg ,
01418                                                                                 char *_foo, char *_bar   )
01419 {
01420         return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_TCP);
01421 }
01422 #endif
01423 
01424 
01425 #ifdef USE_TLS
01426 inline static int w_t_relay_to_tls( struct sip_msg  *p_msg ,
01427                                                                         char *proxy, /* struct proxy_l* expected */
01428                                                                         char *_foo       /* nothing expected */ )
01429 {
01430         return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TLS);
01431 }
01432 
01433 /* forward to uri, but force tls as transport */
01434 inline static int w_t_relay_to_tls_uri( struct sip_msg  *p_msg ,
01435                                                                                 char *_foo, char *_bar   )
01436 {
01437         return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_TLS);
01438 }
01439 #endif
01440 
01441 
01442 #ifdef USE_SCTP
01443 inline static int w_t_relay_to_sctp( struct sip_msg  *p_msg ,
01444                                                                         char *proxy, /* struct proxy_l* */
01445                                                                         char *_foo       /* nothing expected */ )
01446 {
01447         return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_SCTP);
01448 }
01449 
01450 /* forward to uri, but force tcp as transport */
01451 inline static int w_t_relay_to_sctp_uri( struct sip_msg  *p_msg ,
01452                                                                                 char *_foo, char *_bar   )
01453 {
01454         return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_SCTP);
01455 }
01456 #endif
01457 
01458 
01459 inline static int w_t_relay_to_avp( struct sip_msg  *p_msg ,
01460                                                                         char *proto_par, 
01461                                                                         char *addr_par   )
01462 {
01463         struct proxy_l *proxy;
01464         int r = -1;
01465         
01466         proxy = t_protoaddr2proxy(proto_par, addr_par);
01467         if (proxy) {
01468                 r = _w_t_relay_to(p_msg, proxy, PROTO_NONE);
01469                 free_proxy(proxy);
01470                 pkg_free(proxy);
01471         }
01472         return r;
01473 }
01474 
01475 int t_replicate_uri(struct sip_msg *msg, str *suri)
01476 {
01477         struct proxy_l *proxy;
01478         struct sip_uri turi;
01479         int r = -1;
01480 
01481         memset(&turi, 0, sizeof(struct sip_uri));
01482         if(parse_uri(suri->s, suri->len, &turi)!=0)
01483         {
01484                 LM_ERR("bad replicate SIP address!\n");
01485                 return -1;
01486         }
01487 
01488         proxy=mk_proxy(&turi.host, turi.port_no, turi.proto);
01489         if (proxy==0) {
01490                 LM_ERR("cannot create proxy from URI <%.*s>\n",
01491                         suri->len, suri->s );
01492                 return -1;
01493         }
01494 
01495         r = t_replicate(msg, proxy, proxy->proto);
01496         free_proxy(proxy);
01497         pkg_free(proxy);
01498         return r;
01499 }
01500 
01501 inline static int w_t_replicate_uri(struct sip_msg  *msg ,
01502                                 char *uri,       /* sip uri as string or variable */
01503                                 char *_foo       /* nothing expected */ )
01504 {
01505         str suri;
01506 
01507         if(fixup_get_svalue(msg, (gparam_p)uri, &suri)!=0)
01508         {
01509                 LM_ERR("invalid replicate uri parameter");
01510                 return -1;
01511         }
01512         return t_replicate_uri(msg, &suri);
01513 }
01514 
01515 inline static int w_t_replicate( struct sip_msg  *p_msg ,
01516         char *proxy, /* struct proxy_l *proxy expected */
01517         char *_foo       /* nothing expected */ )
01518 {
01519         return t_replicate(p_msg, ( struct proxy_l *) proxy, p_msg->rcv.proto );
01520 }
01521 
01522 inline static int w_t_replicate_udp( struct sip_msg  *p_msg ,
01523         char *proxy, /* struct proxy_l *proxy expected */
01524         char *_foo       /* nothing expected */ )
01525 {
01526         return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_UDP );
01527 }
01528 
01529 
01530 #ifdef USE_TCP
01531 inline static int w_t_replicate_tcp( struct sip_msg  *p_msg ,
01532         char *proxy, /* struct proxy_l *proxy expected */
01533         char *_foo       /* nothing expected */ )
01534 {
01535         return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_TCP );
01536 }
01537 #endif
01538 
01539 
01540 #ifdef USE_TLS
01541 inline static int w_t_replicate_tls( struct sip_msg  *p_msg ,
01542         char *proxy, /* struct proxy_l *proxy expected */
01543         char *_foo       /* nothing expected */ )
01544 {
01545         return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_TLS );
01546 }
01547 #endif
01548 
01549 
01550 #ifdef USE_SCTP
01551 inline static int w_t_replicate_sctp( struct sip_msg  *p_msg ,
01552         char *proxy, /* struct proxy_l *proxy expected */
01553         char *_foo       /* nothing expected */ )
01554 {
01555         return t_replicate(p_msg, ( struct proxy_l *) proxy, PROTO_SCTP );
01556 }
01557 #endif
01558 
01559 
01560 inline static int w_t_replicate_to( struct sip_msg  *p_msg ,
01561         char *proto_par, 
01562         char *addr_par   )
01563 {
01564         struct proxy_l *proxy;
01565         int r = -1;
01566         proxy = t_protoaddr2proxy(proto_par, addr_par);
01567         if (proxy) {
01568                 r = t_replicate(p_msg, proxy, proxy->proto);
01569                 free_proxy(proxy);
01570                 pkg_free(proxy);
01571         }
01572         return r;
01573 }
01574 
01575 inline static int w_t_relay( struct sip_msg  *p_msg ,
01576                                                                 char *_foo, char *_bar)
01577 {
01578         return _w_t_relay_to(p_msg, (struct proxy_l *)0, PROTO_NONE);
01579 }
01580 
01581 
01582 /* like t_relay but use the specified destination and port and the same proto
01583  * as the received msg */
01584 static int w_t_relay2( struct sip_msg  *p_msg , char *proxy,
01585                                                                 char *_foo)
01586 {
01587         return _w_t_relay_to(p_msg, (struct proxy_l*) proxy, p_msg->rcv.proto);
01588 }
01589 
01590 
01591 /* relays CANCEL at the beginning of the script */
01592 inline static int w_t_relay_cancel( struct sip_msg  *p_msg ,
01593                                                 char *_foo, char *_bar)
01594 {
01595         if (p_msg->REQ_METHOD!=METHOD_CANCEL)
01596                 return 1;
01597 
01598         /* it makes no sense to use this function without reparse_invite=1 */
01599         if (!cfg_get(tm, tm_cfg, reparse_invite))
01600                 LOG(L_WARN, "WARNING: t_relay_cancel is probably used with "
01601                         "wrong configuration, check the readme for details\n");
01602 
01603         return t_relay_cancel(p_msg);
01604 }
01605 
01606 /* set fr_inv_timeout & or fr_timeout; 0 means: use the default value */
01607 static int t_set_fr_all(struct sip_msg* msg, char* p1, char* p2)
01608 {
01609     int fr, fr_inv;
01610 
01611     if (get_int_fparam(&fr_inv, msg, (fparam_t*)p1) < 0) return -1;
01612     if (p2) {
01613         if (get_int_fparam(&fr, msg, (fparam_t*)p2) < 0) return -1;
01614     } else {
01615         fr = 0;
01616     }
01617 
01618     return t_set_fr(msg, fr_inv, fr);
01619 }
01620 
01621 static int t_set_fr_inv(struct sip_msg* msg, char* fr_inv, char* foo)
01622 {
01623         return t_set_fr_all(msg, fr_inv, (char*)0);
01624 }
01625 
01626 /* reset fr_timer and fr_inv_timer to the default values */
01627 static int w_t_reset_fr(struct sip_msg* msg, char* foo, char* bar)
01628 {
01629         return t_reset_fr();
01630 }
01631 
01632 /* set retr. intervals per transaction; 0 means: use the default value */
01633 static int w_t_set_retr(struct sip_msg* msg, char* p1, char* p2)
01634 {
01635         int t1, t2;
01636         
01637         if (get_int_fparam(&t1, msg, (fparam_t*)p1) < 0) return -1;
01638         if (p2) {
01639                 if (get_int_fparam(&t2, msg, (fparam_t*)p2) < 0) return -1;
01640         } else {
01641                 t2 = 0;
01642         }
01643 #ifdef TM_DIFF_RT_TIMEOUT
01644         return t_set_retr(msg, t1, t2);
01645 #else
01646         ERR("w_t_set_retr: support for changing retransmission intervals on "
01647                         "the fly not compiled in (re-compile tm with"
01648                         " -DTM_DIFF_RT_TIMEOUT)\n");
01649         return -1;
01650 #endif
01651 }
01652 
01653 /* reset retr. t1 and t2 to the default values */
01654 int w_t_reset_retr(struct sip_msg* msg, char* foo, char* bar)
01655 {
01656 #ifdef TM_DIFF_RT_TIMEOUT
01657         return t_reset_retr();
01658 #else
01659         ERR("w_t_reset_retr: support for changing retransmission intervals on "
01660                         "the fly not compiled in (re-compile tm with"
01661                         " -DTM_DIFF_RT_TIMEOUT)\n");
01662         return -1;
01663 #endif
01664 }
01665 
01666 /* set maximum transaction lifetime for inv & noninv */
01667 static int w_t_set_max_lifetime(struct sip_msg* msg, char* p1, char* p2)
01668 {
01669         int t1, t2;
01670         
01671         if (get_int_fparam(&t1, msg, (fparam_t*)p1) < 0) return -1;
01672         if (p2) {
01673                 if (get_int_fparam(&t2, msg, (fparam_t*)p2) < 0) return -1;
01674         } else {
01675                 t2 = 0;
01676         }
01677         return t_set_max_lifetime(msg, t1, t2);
01678 }
01679 
01680 /* reset maximum invite/non-invite lifetime to the default value */
01681 int w_t_reset_max_lifetime(struct sip_msg* msg, char* foo, char* bar)
01682 {
01683         return t_reset_max_lifetime();
01684 }
01685 
01686 
01687 
01688 /* helper macro, builds a function for setting a cell flag from the script.
01689    e.g. T_SET_FLAG_GEN_FUNC(t_set_foo, T_FOO) =>
01690    static int t_set_foo(struct sip_msg* msg, char*, char* )
01691    that will expect fparam as first param and will set or reset T_FOO
01692    in the current or next to be created transaction. */
01693 #define T_SET_FLAG_GEN_FUNC(fname, T_FLAG_NAME) \
01694 static int fname(struct sip_msg* msg, char* p1, char* p2) \
01695 { \
01696         int state; \
01697         struct cell* t; \
01698         unsigned int set_flags; \
01699         unsigned int reset_flags; \
01700          \
01701         if (get_int_fparam(&state, msg, (fparam_t*)p1) < 0) return -1; \
01702         t=get_t(); \
01703         /* in REPLY_ROUTE and FAILURE_ROUTE T will be set to current transaction; \
01704          * in REQUEST_ROUTE T will be set only if the transaction was already  \
01705          * created; if not -> use the static variables */ \
01706         if (!t || t==T_UNDEFINED ){ \
01707                 set_flags=get_msgid_val(user_cell_set_flags, msg->id, int); \
01708                 reset_flags=get_msgid_val(user_cell_reset_flags, msg->id, int); \
01709                 if (state){ \
01710                         /* set */ \
01711                         set_flags|= T_FLAG_NAME; \
01712                         reset_flags&=~T_FLAG_NAME; \
01713                 }else{ \
01714                         /* reset */ \
01715                         set_flags&=~T_FLAG_NAME; \
01716                         reset_flags|=T_FLAG_NAME; \
01717                 } \
01718                 set_msgid_val(user_cell_set_flags, msg->id, int, set_flags); \
01719                 set_msgid_val(user_cell_reset_flags, msg->id, int, reset_flags); \
01720         }else{ \
01721                 if (state) \
01722                         t->flags|=T_FLAG_NAME; \
01723                 else \
01724                         t->flags&=~T_FLAG_NAME; \
01725         } \
01726         return 1; \
01727 }
01728 
01729 
01730 
01731 /* set automatically sending 100 replies on/off for the current or
01732  * next to be created transaction */
01733 T_SET_FLAG_GEN_FUNC(t_set_auto_inv_100, T_AUTO_INV_100)
01734 
01735 
01736 /* set 6xx handling for the current or next to be created transaction */
01737 T_SET_FLAG_GEN_FUNC(t_set_disable_6xx, T_DISABLE_6xx)
01738 
01739 
01740 /* disable dns failover for the current transaction */
01741 T_SET_FLAG_GEN_FUNC(t_set_disable_failover, T_DISABLE_FAILOVER)
01742 
01743 
01744 #ifdef CANCEL_REASON_SUPPORT
01745 /* disable/enable e2e cancel reason copy for the current transaction */
01746 T_SET_FLAG_GEN_FUNC(t_set_no_e2e_cancel_reason, T_NO_E2E_CANCEL_REASON)
01747 #endif /* CANCEL_REASON_SUPPORT */
01748 
01749 
01750 /* script function, FAILURE_ROUTE only, returns true if the 
01751  * choosed "failure" branch failed because of a timeout, 
01752  * -1 otherwise */
01753 int t_branch_timeout(struct sip_msg* msg, char* foo, char* bar)
01754 {
01755         return (msg->msg_flags & FL_TIMEOUT)?1:-1;
01756 }
01757 
01758 
01759 
01760 /* script function, FAILURE_ROUTE only, returns true if the 
01761  * choosed "failure" branch ever received a reply, -1 otherwise */
01762 int t_branch_replied(struct sip_msg* msg, char* foo, char* bar)
01763 {
01764         return (msg->msg_flags & FL_REPLIED)?1:-1;
01765 }
01766 
01767 
01768 
01769 /* script function, returns: 1 if the transaction was canceled, -1 if not */
01770 int t_is_canceled(struct sip_msg* msg)
01771 {
01772         struct cell *t;
01773         int ret;
01774         
01775         
01776         if (t_check( msg , 0 )==-1) return -1;
01777         t=get_t();
01778         if ((t==0) || (t==T_UNDEFINED)){
01779                 LOG(L_ERR, "ERROR: t_is_canceled: cannot check a message "
01780                         "for which no T-state has been established\n");
01781                 ret=-1;
01782         }else{
01783                 ret=(t->flags & T_CANCELED)?1:-1;
01784         }
01785         return ret;
01786 }
01787 
01788 static int w_t_is_canceled(struct sip_msg* msg, char* foo, char* bar)
01789 {
01790         return t_is_canceled(msg);
01791 }
01792 
01793 /* script function, returns: 1 if the transaction lifetime interval has already elapsed, -1 if not */
01794 int t_is_expired(struct sip_msg* msg, char* foo, char* bar)
01795 {
01796         struct cell *t;
01797         int ret;
01798         
01799         
01800         if (t_check( msg , 0 )==-1) return -1;
01801         t=get_t();
01802         if ((t==0) || (t==T_UNDEFINED)){
01803                 LOG(L_ERR, "ERROR: t_is_expired: cannot check a message "
01804                         "for which no T-state has been established\n");
01805                 ret=-1;
01806         }else{
01807                 ret=(TICKS_GT(t->end_of_life, get_ticks_raw()))?-1:1;
01808         }
01809         return ret;
01810 }
01811 
01812 /* script function, returns: 1 if any of the branches did timeout, -1 if not */
01813 int t_any_timeout(struct sip_msg* msg, char* foo, char* bar)
01814 {
01815         struct cell *t;
01816         int r;
01817         
01818         if (t_check( msg , 0 )==-1) return -1;
01819         t=get_t();
01820         if ((t==0) || (t==T_UNDEFINED)){
01821                 LOG(L_ERR, "ERROR: t_any_timeout: cannot check a message "
01822                         "for which no T-state has been established\n");
01823                 return -1;
01824         }else{
01825                 for (r=0; r<t->nr_of_outgoings; r++){
01826                         if (t->uac[r].request.flags & F_RB_TIMEOUT)
01827                                 return 1;
01828                 }
01829         }
01830         return -1;
01831 }
01832 
01833 
01834 
01835 /* script function, returns: 1 if any of the branches received at leat one
01836  * reply, -1 if not */
01837 int t_any_replied(struct sip_msg* msg, char* foo, char* bar)
01838 {
01839         struct cell *t;
01840         int r;
01841         
01842         if (t_check( msg , 0 )==-1) return -1;
01843         t=get_t();
01844         if ((t==0) || (t==T_UNDEFINED)){
01845                 LOG(L_ERR, "ERROR: t_any_replied: cannot check a message "
01846                         "for which no T-state has been established\n");
01847                 return -1;
01848         }else{
01849                 for (r=0; r<t->nr_of_outgoings; r++){
01850                         if (t->uac[r].request.flags & F_RB_REPLIED)
01851                                 return 1;
01852                 }
01853         }
01854         return -1;
01855 }
01856 
01857 
01858 
01859 /* script function, returns: 1 if any of the branches received the
01860  *  reply code "status" */
01861 int t_grep_status(struct sip_msg* msg, char* status, char* bar)
01862 {
01863         struct cell *t;
01864         int r;
01865         int code;
01866         
01867     if (get_int_fparam(&code, msg, (fparam_t*)status) < 0) return -1;
01868         if (t_check( msg , 0 )==-1) return -1;
01869         t=get_t();
01870         if ((t==0) || (t==T_UNDEFINED)){
01871                 LOG(L_ERR, "ERROR: t_any_replied: cannot check a message "
01872                         "for which no T-state has been established\n");
01873                 return -1;
01874         }else{
01875                 for (r=0; r<t->nr_of_outgoings; r++){
01876                         if ((t->uac[r].last_received==code)  && 
01877                                         (t->uac[r].request.flags & F_RB_REPLIED))
01878                                 return 1;
01879                 }
01880         }
01881         return -1;
01882 }
01883 
01884 /* drop all the existing replies in failure_route to make sure
01885  * that none of them is picked up again */
01886 static int w_t_drop_replies(struct sip_msg* msg, char* foo, char* bar)
01887 {
01888         if(foo==NULL)
01889                 t_drop_replies(1);
01890         else if(*foo=='n')
01891                 t_drop_replies(0);
01892         else if(*foo=='l')
01893                 t_drop_replies(2);
01894         else
01895                 t_drop_replies(1);
01896         return 1;
01897 }
01898 
01899 /* save the message lumps after t_newtran() but before t_relay() */
01900 static int w_t_save_lumps(struct sip_msg* msg, char* foo, char* bar)
01901 {
01902         struct cell *t;
01903 
01904         if (is_route_type(REQUEST_ROUTE)) {
01905                 t=get_t();
01906                 if (!t || t==T_UNDEFINED) {
01907                         LOG(L_ERR, "ERROR: w_t_save_lumps: transaction has not been created yet\n");
01908                         return -1;
01909                 }
01910 
01911                 if (save_msg_lumps(t->uas.request, msg)) {
01912                         LOG(L_ERR, "ERROR: w_t_save_lumps: "
01913                                 "failed to save the message lumps\n");
01914                         return -1;
01915                 }
01916         } /* else nothing to do, the lumps have already been saved */
01917         return 1;
01918 }
01919 
01920 
01921 
01922 /* wrapper function needed after changes in w_t_reply */
01923 int w_t_reply_wrp(struct sip_msg *m, unsigned int code, char *txt)
01924 {
01925         fparam_t c;
01926         fparam_t r;
01927         
01928         c.type = FPARAM_INT;
01929         c.orig = NULL; /* ? */
01930         c.v.i = code;
01931         
01932         r.type = FPARAM_STRING;
01933         r.orig = NULL; /* ? */
01934         r.v.asciiz = txt;
01935 
01936         return w_t_reply(m, (char *)&c, (char*)&r);
01937 }
01938 
01939 
01940 
01951 int t_check_trans(struct sip_msg* msg)
01952 {
01953         struct cell* t;
01954         int branch;
01955         int ret;
01956         
01957         if (msg->first_line.type==SIP_REPLY) {
01958                 branch = 0;
01959                 ret = (t_check_msg( msg , &branch)==1) ? 1 : -1;
01960                 tm_ctx_set_branch_index(branch);
01961                 return ret;
01962         } else if (msg->REQ_METHOD==METHOD_CANCEL) {
01963                 return w_t_lookup_cancel(msg, 0, 0);
01964         } else {
01965                 switch(t_check_msg(msg, 0)){
01966                         case -2: /* possible e2e ack */
01967                                 return 1;
01968                         case 1: /* found */
01969                                 t=get_t();
01970                                 if (msg->REQ_METHOD==METHOD_ACK){
01971                                         /* ack to neg. reply  or ack to local trans.
01972                                            => process it and end the script */
01973                                         /* FIXME: there's no way to distinguish here 
01974                                            between acks to local trans. and neg. acks */
01975                                         if (unlikely(has_tran_tmcbs(t, TMCB_ACK_NEG_IN)))
01976                                                 run_trans_callbacks(TMCB_ACK_NEG_IN, t, msg,
01977                                                                                         0, msg->REQ_METHOD);
01978                                         t_release_transaction(t);
01979                                 } else {
01980                                         /* is a retransmission */
01981                                         if (unlikely(has_tran_tmcbs(t, TMCB_REQ_RETR_IN)))
01982                                                 run_trans_callbacks(TMCB_REQ_RETR_IN, t, msg,
01983                                                                                         0, msg->REQ_METHOD);
01984                                         t_retransmit_reply(t);
01985                                 }
01986                                 /* no need for UNREF(t); set_t(0) - the end-of-script
01987                                    t_unref callback will take care of them */
01988                                 return 0; /* return from the script */
01989                 }
01990                 /* not found or error */
01991         }
01992         return -1;
01993 }
01994 
01995 static int w_t_check_trans(struct sip_msg* msg, char* foo, char* bar)
01996 {
01997         return t_check_trans(msg);
01998 }
01999 
02000 static int hexatoi(str *s, unsigned int* result)
02001 {
02002         int i, xv, fact;
02003 
02004         /* more than 32bit hexa? */
02005         if (s->len>8)
02006                 return -1;
02007 
02008         *result = 0;
02009         fact = 1;
02010 
02011         for(i=s->len-1; i>=0 ;i--)
02012         {
02013                 xv = hex2int(s->s[i]);
02014                 if(xv<0)
02015                         return -1;
02016 
02017                 *result += (xv * fact);
02018                 fact *= 16;
02019         }
02020         return 0;
02021 }
02022 
02023 static int fixup_t_relay_to(void** param, int param_no)
02024 {
02025 
02026         int port;
02027         int proto;
02028         unsigned int flags;
02029         struct proxy_l *proxy;
02030         action_u_t *a;
02031         str s;
02032         str host;
02033 
02034         s.s = (char*)*param;
02035         s.len = strlen(s.s);
02036         LM_DBG("fixing (%s, %d)\n", s.s, param_no);
02037         if (param_no==1){
02038                 a = fixup_get_param(param, param_no, 2);
02039                 if(a==NULL)
02040                 {
02041                         LM_CRIT("server error for parameter <%s>\n",s.s);
02042                         return E_UNSPEC;
02043                 }
02044                 if(a->u.string!=NULL) {
02045                         /* second parameter set, first should be proxy addr */
02046                         if (parse_phostport(s.s, &host.s, &host.len, &port, &proto)!=0){
02047                                 LM_CRIT("invalid proxy addr parameter <%s>\n",s.s);
02048                                 return E_UNSPEC;
02049                         }
02050 
02051                         proxy = mk_proxy(&host, port, proto);
02052                         if (proxy==0) {
02053                                 LM_ERR("failed to build proxy structure for <%.*s>\n", host.len, host.s );
02054                                 return E_UNSPEC;
02055                         }
02056                         *(param)=proxy;
02057                         return 0;
02058                 } else {
02059                         /* no second parameter, then is proxy addr or flags */
02060                         flags = 0;
02061                         if (s.len>2 && s.s[0]=='0' && s.s[1]=='x') {
02062                                 s.s += 2;
02063                                 s.len -= 2;
02064                                 if(hexatoi(&s, &flags)<0)
02065                                 {
02066                                         LM_CRIT("invalid hexa flags <%s>\n", s.s);
02067                                         return E_UNSPEC;
02068                                 }
02069                                 a->u.data = (void*)(unsigned long int)flags;
02070                                 *(param)= 0;
02071                                 return 0;
02072                         } else {
02073                                 if(str2int(&s, &flags)==0)
02074                                 {
02075                                         a->u.data = (void*)(unsigned long int)flags;
02076                                         *(param)= 0;
02077                                         return 0;
02078                                 } else {
02079                                         /* try proxy */
02080                                         if (parse_phostport(s.s, &host.s, &host.len, &port, &proto)!=0){
02081                                                 LM_CRIT("invalid proxy addr parameter <%s>\n",s.s);
02082                                                 return E_UNSPEC;
02083                                         }
02084 
02085                                         proxy = mk_proxy(&host, port, proto);
02086                                         if (proxy==0) {
02087                                                 LM_ERR("failed to build proxy structure for <%.*s>\n", host.len, host.s );
02088                                                 return E_UNSPEC;
02089                                         }
02090                                         *(param)=proxy;
02091                                         return 0;
02092                                 }
02093                         }
02094                 }
02095         } else if (param_no==2) {
02096                 /* flags */
02097                 flags = 0;
02098                 if (s.len>2 && s.s[0]=='0' && s.s[1]=='x') {
02099                         s.s += 2;
02100                         s.len -= 2;
02101                         if(hexatoi(&s, &flags)<0)
02102                         {
02103                                 LM_CRIT("invalid hexa flags <%s>\n", s.s);
02104                                 return E_UNSPEC;
02105                         }
02106                         *(param) = (void*)(unsigned long int)flags;
02107                         return 0;
02108                 } else {
02109                         if(str2int(&s, &flags)==0)
02110                         {
02111                                 *(param) = (void*)(unsigned long int)flags;
02112                                 return 0;
02113                         } else {
02114                                 LM_CRIT("invalid flags <%s>\n", s.s);
02115                                 return E_UNSPEC;
02116                         }
02117                 }
02118         } else {
02119                 LM_ERR("invalid parameter number %d\n", param_no);
02120                 return E_BUG;
02121         }
02122 }
02123 
02124 
02125 inline static int w_t_relay_to(struct sip_msg *msg, char *proxy, char *flags)
02126 {
02127         unsigned int fl;
02128         struct proxy_l *px;
02129         fparam_t param;
02130 
02131         fl = (unsigned int)(long)(void*)flags;
02132         px = (struct proxy_l*)proxy;
02133 
02134         if(flags!=0)
02135         {
02136                 memset(&param, 0, sizeof(fparam_t));
02137                 param.type = FPARAM_INT;
02138                 /* no auto 100 trying */
02139                 if(fl&1) {
02140                         param.v.i = 0;
02141                         t_set_auto_inv_100(msg, (char*)(&param), 0);
02142                 }
02143                 /* no auto negative reply - not implemented */
02144                 /*
02145                 if(fl&2) {
02146                         param.v.i = 1;
02147                         t_set_disable_internal_reply(msg, (char*)param, 0);
02148                 }
02149                 */
02150                 /* no dns failover */
02151                 if(fl&4) {
02152                         param.v.i = 1;
02153                         t_set_disable_failover(msg, (char*)(&param), 0);
02154                 }
02155         }
02156         return _w_t_relay_to(msg, px, PROTO_NONE);
02157 }
02158 
02159 
02160 
02161 /* rpc docs */
02162 
02163 static const char* rpc_cancel_doc[2] = {
02164         "Cancel a pending transaction",
02165         0
02166 };
02167 
02168 static const char* rpc_reply_doc[2] = {
02169         "Reply transaction",
02170         0
02171 };
02172 
02173 static const char* tm_rpc_stats_doc[2] = {
02174         "Print transaction statistics.",
02175         0
02176 };
02177 
02178 static const char* tm_rpc_hash_stats_doc[2] = {
02179         "Prints hash table statistics (can be used only if tm is compiled"
02180                 " with -DTM_HASH_STATS).",
02181         0
02182 };
02183 
02184 static const char* rpc_t_uac_start_doc[2] = {
02185         "starts a tm uac using  a list of string parameters: method, ruri, dst_uri"
02186                 ", send_sock, headers (CRLF separated) and body (optional)",
02187         0
02188 };
02189 
02190 static const char* rpc_t_uac_wait_doc[2] = {
02191         "starts a tm uac and waits for the final reply, using a list of string "
02192                 "parameters: method, ruri, dst_uri send_sock, headers (CRLF separated)"
02193                 " and body (optional)",
02194         0
02195 };
02196 
02197 
02198 /* rpc exports */
02199 static rpc_export_t tm_rpc[] = {
02200         {"tm.cancel", rpc_cancel,   rpc_cancel_doc,   0},
02201         {"tm.reply",  rpc_reply,    rpc_reply_doc,    0},
02202         {"tm.stats",  tm_rpc_stats, tm_rpc_stats_doc, 0},
02203         {"tm.hash_stats",  tm_rpc_hash_stats, tm_rpc_hash_stats_doc, 0},
02204         {"tm.t_uac_start", rpc_t_uac_start, rpc_t_uac_start_doc, 0 },
02205         {"tm.t_uac_wait",  rpc_t_uac_wait,  rpc_t_uac_wait_doc, RET_ARRAY},
02206         {0, 0, 0, 0}
02207 };
02208