00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
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
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
00200 static int mod_init(void);
00201 static int child_init(int rank);
00202
00203
00204
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,
00236 char *_foo );
00237 inline static int w_t_replicate( struct sip_msg *p_msg ,
00238 char *proxy,
00239 char *_foo );
00240 inline static int w_t_replicate_udp( struct sip_msg *p_msg ,
00241 char *proxy,
00242 char *_foo );
00243 #ifdef USE_TCP
00244 inline static int w_t_replicate_tcp( struct sip_msg *p_msg ,
00245 char *proxy,
00246 char *_foo );
00247 #endif
00248 #ifdef USE_TLS
00249 inline static int w_t_replicate_tls( struct sip_msg *p_msg ,
00250 char *proxy,
00251 char *_foo );
00252 #endif
00253 #ifdef USE_SCTP
00254 inline static int w_t_replicate_sctp( struct sip_msg *p_msg ,
00255 char *proxy,
00256 char *_foo );
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
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
00304
00305 static char *fr_timer_param = 0 ;
00306 static char *fr_inv_timer_param = 0 ;
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
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
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
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
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
00535 cmds,
00536 tm_rpc,
00537
00538 params,
00539
00540 mod_init,
00541 (response_function) reply_received,
00542 (destroy_function) tm_shutdown,
00543 0,
00544 child_init
00545 };
00546
00547
00548
00549
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
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);
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
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
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
00683
00684
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
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
00716
00717
00718
00719
00720
00721
00722 t_on_negative( 0 );
00723 t_on_reply(0);
00724 t_on_branch(0);
00725
00726 reset_kr();
00727
00728
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
00741
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
00754 if (!init_hash_table()) {
00755 LOG(L_ERR, "ERROR: mod_init: initializing hash_table failed\n");
00756 return -1;
00757 }
00758
00759
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
00768
00769 if (tm_init_timers()==-1) {
00770 LOG(L_ERR, "ERROR: mod_init: timer init failed\n");
00771 return -1;
00772 }
00773
00774
00775
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
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
00798
00799
00800
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
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;
00845 if (goto_on_local_req>=0)
00846 set_child_rpc_sip_mode();
00847 #endif
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
00858
00859
00860
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
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
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
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
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
00932 status = int2str( t->uas.status, 0);
00933 break;
00934
00935 case TM_ONREPLY_ROUTE:
00936 case CORE_ONREPLY_ROUTE:
00937
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
00945 ret = t_pick_branch( -1, 0, t, &lowest_status);
00946 if (ret == -1) {
00947
00948
00949
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
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
00981
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
00991
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
01018
01019 if (str && (get_int_fparam(&i, msg, (fparam_t*)str)==0) && i)
01020 msg->flags = ret->uas.request->flags;
01021
01022
01023
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))
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
01248
01249
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
01266
01267
01268
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
01328
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
01377
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 );
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,
01395 char *_foo )
01396 {
01397 return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_UDP);
01398 }
01399
01400
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,
01411 char *_foo )
01412 {
01413 return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TCP);
01414 }
01415
01416
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,
01428 char *_foo )
01429 {
01430 return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_TLS);
01431 }
01432
01433
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,
01445 char *_foo )
01446 {
01447 return _w_t_relay_to( p_msg, ( struct proxy_l *) proxy, PROTO_SCTP);
01448 }
01449
01450
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,
01503 char *_foo )
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,
01517 char *_foo )
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,
01524 char *_foo )
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,
01533 char *_foo )
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,
01543 char *_foo )
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,
01553 char *_foo )
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
01583
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
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
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
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
01627 static int w_t_reset_fr(struct sip_msg* msg, char* foo, char* bar)
01628 {
01629 return t_reset_fr();
01630 }
01631
01632
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
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
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
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
01689
01690
01691
01692
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
01704
01705 \
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 \
01711 set_flags|= T_FLAG_NAME; \
01712 reset_flags&=~T_FLAG_NAME; \
01713 }else{ \
01714 \
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
01732
01733 T_SET_FLAG_GEN_FUNC(t_set_auto_inv_100, T_AUTO_INV_100)
01734
01735
01736
01737 T_SET_FLAG_GEN_FUNC(t_set_disable_6xx, T_DISABLE_6xx)
01738
01739
01740
01741 T_SET_FLAG_GEN_FUNC(t_set_disable_failover, T_DISABLE_FAILOVER)
01742
01743
01744 #ifdef CANCEL_REASON_SUPPORT
01745
01746 T_SET_FLAG_GEN_FUNC(t_set_no_e2e_cancel_reason, T_NO_E2E_CANCEL_REASON)
01747 #endif
01748
01749
01750
01751
01752
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
01761
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
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
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
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
01836
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
01860
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
01885
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
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 }
01917 return 1;
01918 }
01919
01920
01921
01922
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:
01967 return 1;
01968 case 1:
01969 t=get_t();
01970 if (msg->REQ_METHOD==METHOD_ACK){
01971
01972
01973
01974
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
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
01987
01988 return 0;
01989 }
01990
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
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
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
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
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
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(¶m, 0, sizeof(fparam_t));
02137 param.type = FPARAM_INT;
02138
02139 if(fl&1) {
02140 param.v.i = 0;
02141 t_set_auto_inv_100(msg, (char*)(¶m), 0);
02142 }
02143
02144
02145
02146
02147
02148
02149
02150
02151 if(fl&4) {
02152 param.v.i = 1;
02153 t_set_disable_failover(msg, (char*)(¶m), 0);
02154 }
02155 }
02156 return _w_t_relay_to(msg, px, PROTO_NONE);
02157 }
02158
02159
02160
02161
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
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