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
00067 #include "comp_defs.h"
00068
00069 #include "action.h"
00070 #include "config.h"
00071 #include "error.h"
00072 #include "dprint.h"
00073 #include "proxy.h"
00074 #include "forward.h"
00075 #include "udp_server.h"
00076 #include "route.h"
00077 #include "parser/msg_parser.h"
00078 #include "parser/parse_uri.h"
00079 #include "ut.h"
00080 #include "lvalue.h"
00081 #include "sr_module.h"
00082 #include "select_buf.h"
00083 #include "mem/mem.h"
00084 #include "globals.h"
00085 #include "dset.h"
00086 #include "onsend.h"
00087 #include "resolve.h"
00088 #ifdef USE_TCP
00089 #include "tcp_server.h"
00090 #endif
00091 #ifdef USE_SCTP
00092 #include "sctp_server.h"
00093 #endif
00094 #include "switch.h"
00095 #include "events.h"
00096 #include "cfg/cfg_struct.h"
00097
00098 #include <sys/types.h>
00099 #include <sys/socket.h>
00100 #include <netdb.h>
00101 #include <stdlib.h>
00102 #include <netinet/in.h>
00103 #include <arpa/inet.h>
00104 #include <string.h>
00105
00106
00107 #ifdef DEBUG_DMALLOC
00108 #include <dmalloc.h>
00109 #endif
00110
00111 int _last_returned_code = 0;
00112 struct onsend_info* p_onsend=0;
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 #define MODF_HANDLE_RETCODE(h, ret) \
00123 do { \
00124 \
00125 (h)->run_flags |= EXIT_R_F & (((ret) != 0) -1); \
00126 (h)->last_retcode=(ret); \
00127 _last_returned_code = (h)->last_retcode; \
00128 } while(0)
00129
00130
00131
00132
00133
00134
00135
00136
00137 #define MODF_RVE_PARAM_FREE(cmd, src, dst) \
00138 for (i=0; i < (dst)[1].u.number; i++) { \
00139 if ((src)[i+2].type == RVE_ST && (dst)[i+2].u.data) { \
00140 if ((dst)[i+2].type == RVE_FREE_FIXUP_ST) {\
00141
00142 \
00143 call_fixup((cmd)->free_fixup, &(dst)[i+2].u.data, i+1); \
00144 } else if ((dst)[i+2].type == FPARAM_DYN_ST) {\
00145 \
00146 fparam_free_restore(&(dst)[i+2].u.data); \
00147 } \
00148 \
00149 pkg_free((dst)[i+2].u.data); \
00150 (dst)[i+2].u.data = 0; \
00151 } \
00152 }
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162 #define MODF_RVE_PARAM_CONVERT(h, msg, cmd, src, dst) \
00163 do { \
00164 (dst)[1]=(src)[1]; \
00165 for (i=0; i < (src)[1].u.number; i++) { \
00166 if ((src)[2+i].type == RVE_ST) { \
00167 rv=rval_expr_eval((h), (msg), (src)[i+2].u.data); \
00168 if (unlikely(rv == 0 || \
00169 rval_get_str((h), (msg), &s, rv, 0) < 0)) { \
00170 rval_destroy(rv); \
00171 ERR("failed to convert RVE to string\n"); \
00172 (dst)[1].u.number = i; \
00173 MODF_RVE_PARAM_FREE(cmd, src, dst); \
00174 goto error; \
00175 } \
00176 (dst)[i+2].type = STRING_RVE_ST; \
00177 (dst)[i+2].u.string = s.s; \
00178 (dst)[i+2].u.str.len = s.len; \
00179 rval_destroy(rv); \
00180 if ((cmd)->fixup) {\
00181 if ((cmd)->free_fixup) {\
00182 if (likely( call_fixup((cmd)->fixup, \
00183 &(dst)[i+2].u.data, i+1) >= 0) ) { \
00184 \
00185 if (likely((dst)[i+2].u.data != s.s)) \
00186 (dst)[i+2].type = RVE_FREE_FIXUP_ST; \
00187 } else { \
00188
00189 \
00190 (dst)[1].u.number = i; \
00191 ERR("runtime fixup failed for %s param %d\n", \
00192 (cmd)->name, i+1); \
00193 MODF_RVE_PARAM_FREE(cmd, src, dst); \
00194 goto error; \
00195 } \
00196 } else if ((cmd)->fixup_flags & FIXUP_F_FPARAM_RVE) { \
00197 if (likely( call_fixup((cmd)->fixup, \
00198 &(dst)[i+2].u.data, i+1) >= 0)) { \
00199 if ((dst)[i+2].u.data != s.s) \
00200 (dst)[i+2].type = FPARAM_DYN_ST; \
00201 } else { \
00202
00203 \
00204 (dst)[1].u.number = i; \
00205 ERR("runtime fixup failed for %s param %d\n", \
00206 (cmd)->name, i+1); \
00207 MODF_RVE_PARAM_FREE(cmd, src, dst); \
00208 goto error; \
00209 }\
00210 } \
00211 } \
00212 } else \
00213 (dst)[i+2]=(src)[i+2]; \
00214 } \
00215 } while(0)
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 #ifdef __SUNPRO_C
00232 #define MODF_CALL(f_type, h, msg, src, ...) \
00233 do { \
00234 cmd=(src)[0].u.data; \
00235 ret=((f_type)cmd->function)((msg), __VAR_ARGS__); \
00236 MODF_HANDLE_RETCODE(h, ret); \
00237 } while (0)
00238 #else
00239 #define MODF_CALL(f_type, h, msg, src, params...) \
00240 do { \
00241 cmd=(src)[0].u.data; \
00242 ret=((f_type)cmd->function)((msg), ## params ); \
00243 MODF_HANDLE_RETCODE(h, ret); \
00244 } while (0)
00245 #endif
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264 #ifdef __SUNPRO_C
00265 #define MODF_RVE_CALL(f_type, h, msg, src, dst, ...) \
00266 do { \
00267 cmd=(src)[0].u.data; \
00268 MODF_RVE_PARAM_CONVERT(h, msg, cmd, src, dst); \
00269 ret=((f_type)cmd->function)((msg), __VAR_ARGS__); \
00270 MODF_HANDLE_RETCODE(h, ret); \
00271 \
00272 MODF_RVE_PARAM_FREE(cmd, src, dst); \
00273 } while (0)
00274 #else
00275 #define MODF_RVE_CALL(f_type, h, msg, src, dst, params...) \
00276 do { \
00277 cmd=(src)[0].u.data; \
00278 MODF_RVE_PARAM_CONVERT(h, msg, cmd, src, dst); \
00279 ret=((f_type)cmd->function)((msg), ## params ); \
00280 MODF_HANDLE_RETCODE(h, ret); \
00281 \
00282 MODF_RVE_PARAM_FREE(cmd, src, dst); \
00283 } while (0)
00284 #endif
00285
00286
00287
00288
00289
00290 int do_action(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
00291 {
00292 int ret;
00293 int v;
00294 struct dest_info dst;
00295 char* tmp;
00296 char *new_uri, *end, *crt;
00297 sr31_cmd_export_t* cmd;
00298 int len;
00299 int user;
00300 struct sip_uri uri, next_hop;
00301 struct sip_uri *u;
00302 unsigned short port;
00303 str* dst_host;
00304 int i, flags;
00305 avp_t* avp;
00306 struct search_state st;
00307 struct switch_cond_table* sct;
00308 struct switch_jmp_table* sjt;
00309 struct rval_expr* rve;
00310 struct match_cond_table* mct;
00311 struct rvalue* rv;
00312 struct rvalue* rv1;
00313 struct rval_cache c1;
00314 str s;
00315 void *srevp[2];
00316
00317
00318
00319
00320
00321
00322 static action_u_t mod_f_params[MAX_ACTIONS];
00323
00324
00325
00326
00327
00328 prev_ser_error=ser_error;
00329 ser_error=E_UNSPEC;
00330
00331
00332 if(unlikely(sr_event_enabled(SREV_CFG_RUN_ACTION)))
00333 {
00334 srevp[0] = (void*)a;
00335 srevp[1] = (void*)msg;
00336 sr_event_exec(SREV_CFG_RUN_ACTION, (void*)srevp);
00337 }
00338
00339 ret=E_BUG;
00340 switch ((unsigned char)a->type){
00341 case DROP_T:
00342 switch(a->val[0].type){
00343 case NUMBER_ST:
00344 ret=(int) a->val[0].u.number;
00345 break;
00346 case RVE_ST:
00347 rve=(struct rval_expr*)a->val[0].u.data;
00348 rval_expr_eval_int(h, msg, &ret, rve);
00349 break;
00350 case RETCODE_ST:
00351 ret=h->last_retcode;
00352 break;
00353 default:
00354 BUG("unexpected subtype %d in DROP_T\n",
00355 a->val[0].type);
00356 ret=0;
00357 goto error;
00358 }
00359 h->run_flags|=(unsigned int)a->val[1].u.number;
00360 break;
00361 case FORWARD_T:
00362 #ifdef USE_TCP
00363 case FORWARD_TCP_T:
00364 #endif
00365 #ifdef USE_TLS
00366 case FORWARD_TLS_T:
00367 #endif
00368 #ifdef USE_SCTP
00369 case FORWARD_SCTP_T:
00370 #endif
00371 case FORWARD_UDP_T:
00372
00373 init_dest_info(&dst);
00374 if (a->type==FORWARD_UDP_T) dst.proto=PROTO_UDP;
00375 #ifdef USE_TCP
00376 else if (a->type==FORWARD_TCP_T) dst.proto= PROTO_TCP;
00377 #endif
00378 #ifdef USE_TLS
00379 else if (a->type==FORWARD_TLS_T) dst.proto= PROTO_TLS;
00380 #endif
00381 #ifdef USE_SCTP
00382 else if (a->type==FORWARD_SCTP_T) dst.proto=PROTO_SCTP;
00383 #endif
00384 else dst.proto=PROTO_NONE;
00385 if (a->val[0].type==URIHOST_ST){
00386
00387
00388 if (msg->dst_uri.len) {
00389 ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
00390 &next_hop);
00391 u = &next_hop;
00392 } else {
00393 ret = parse_sip_msg_uri(msg);
00394 u = &msg->parsed_uri;
00395 }
00396
00397 if (ret<0) {
00398 LOG(L_ERR, "ERROR: do_action: forward: bad_uri "
00399 " dropping packet\n");
00400 goto error;
00401 }
00402
00403 switch (a->val[1].type){
00404 case URIPORT_ST:
00405 port=u->port_no;
00406 break;
00407 case NUMBER_ST:
00408 port=a->val[1].u.number;
00409 break;
00410 default:
00411 LOG(L_CRIT, "BUG: do_action bad forward 2nd"
00412 " param type (%d)\n", a->val[1].type);
00413 ret=E_UNSPEC;
00414 goto error_fwd_uri;
00415 }
00416 if (dst.proto == PROTO_NONE){
00417
00418 switch(u->proto){
00419 case PROTO_NONE:
00420
00421
00422 break;
00423 case PROTO_UDP:
00424 #ifdef USE_TCP
00425 case PROTO_TCP:
00426 #endif
00427 #ifdef USE_TLS
00428 case PROTO_TLS:
00429 #endif
00430 #ifdef USE_SCTP
00431 case PROTO_SCTP:
00432 #endif
00433 dst.proto=u->proto;
00434 break;
00435 default:
00436 LOG(L_ERR,"ERROR: do action: forward: bad uri"
00437 " transport %d\n", u->proto);
00438 ret=E_BAD_PROTO;
00439 goto error_fwd_uri;
00440 }
00441 #ifdef USE_TLS
00442 if (u->type==SIPS_URI_T){
00443 if (u->proto==PROTO_UDP){
00444 LOG(L_ERR, "ERROR: do_action: forward: secure uri"
00445 " incompatible with transport %d\n",
00446 u->proto);
00447 ret=E_BAD_PROTO;
00448 goto error_fwd_uri;
00449 }
00450 dst.proto=PROTO_TLS;
00451 }
00452 #endif
00453 }
00454
00455 #ifdef HONOR_MADDR
00456 if (u->maddr_val.s && u->maddr_val.len)
00457 dst_host=&u->maddr_val;
00458 else
00459 #endif
00460 dst_host=&u->host;
00461 #ifdef USE_COMP
00462 dst.comp=u->comp;
00463 #endif
00464 ret=forward_request(msg, dst_host, port, &dst);
00465 if (ret>=0){
00466 ret=1;
00467 }
00468 }else if ((a->val[0].type==PROXY_ST) && (a->val[1].type==NUMBER_ST)){
00469 if (dst.proto==PROTO_NONE)
00470 dst.proto=msg->rcv.proto;
00471 proxy2su(&dst.to, (struct proxy_l*)a->val[0].u.data);
00472 ret=forward_request(msg, 0, 0, &dst);
00473 if (ret>=0){
00474 ret=1;
00475 proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
00476 }else if (ser_error!=E_OK){
00477 proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
00478 }
00479 }else{
00480 LOG(L_CRIT, "BUG: do_action: bad forward() types %d, %d\n",
00481 a->val[0].type, a->val[1].type);
00482 ret=E_BUG;
00483 goto error;
00484 }
00485 break;
00486 case SEND_T:
00487 case SEND_TCP_T:
00488 if (a->val[0].type==URIHOST_ST){
00489
00490 if (msg->dst_uri.len) {
00491 ret = parse_uri(msg->dst_uri.s, msg->dst_uri.len,
00492 &next_hop);
00493 u = &next_hop;
00494 } else {
00495 ret = parse_sip_msg_uri(msg);
00496 u = &msg->parsed_uri;
00497 }
00498
00499 if (ret<0) {
00500 LM_ERR("send() - bad_uri dropping packet\n");
00501 ret=E_BUG;
00502 goto error;
00503 }
00504
00505 init_dest_info(&dst);
00506 ret = sip_hostport2su(&dst.to, &u->host, u->port_no,
00507 &dst.proto);
00508 if(ret!=0) {
00509 LM_ERR("failed to resolve [%.*s]\n", u->host.len,
00510 ZSW(u->host.s));
00511 ret=E_BUG;
00512 goto error;
00513 }
00514 } else {
00515 if ((a->val[0].type!= PROXY_ST)|(a->val[1].type!=NUMBER_ST)){
00516 LOG(L_CRIT, "BUG: do_action: bad send() types %d, %d\n",
00517 a->val[0].type, a->val[1].type);
00518 ret=E_BUG;
00519 goto error;
00520 }
00521
00522 init_dest_info(&dst);
00523 ret=proxy2su(&dst.to, (struct proxy_l*)a->val[0].u.data);
00524 if(ret==0)
00525 proxy_mark((struct proxy_l*)a->val[0].u.data, ret);
00526 }
00527 if (ret==0){
00528 if (p_onsend){
00529 tmp=p_onsend->buf;
00530 len=p_onsend->len;
00531 }else{
00532 tmp=msg->buf;
00533 len=msg->len;
00534 }
00535 if (a->type==SEND_T){
00536
00537 dst.proto=PROTO_UDP;
00538 dst.send_sock=get_send_socket(msg, &dst.to, PROTO_UDP);
00539 if (dst.send_sock!=0){
00540 ret=udp_send(&dst, tmp, len);
00541 }else{
00542 ret=-1;
00543 }
00544 }
00545 #ifdef USE_TCP
00546 else{
00547
00548 dst.proto=PROTO_TCP;
00549 dst.id=0;
00550 ret=tcp_send(&dst, 0, tmp, len);
00551 }
00552 #endif
00553 }else{
00554 ret=E_BUG;
00555 goto error;
00556 }
00557 if (ret>=0) ret=1;
00558
00559 break;
00560 case LOG_T:
00561 if ((a->val[0].type!=NUMBER_ST)|(a->val[1].type!=STRING_ST)){
00562 LOG(L_CRIT, "BUG: do_action: bad log() types %d, %d\n",
00563 a->val[0].type, a->val[1].type);
00564 ret=E_BUG;
00565 goto error;
00566 }
00567 LOG_(DEFAULT_FACILITY, a->val[0].u.number, "<script>: ", "%s",
00568 a->val[1].u.string);
00569 ret=1;
00570 break;
00571
00572
00573 case APPEND_BRANCH_T:
00574 if (unlikely(a->val[0].type!=STR_ST)) {
00575 LOG(L_CRIT, "BUG: do_action: bad append_branch_t %d\n",
00576 a->val[0].type );
00577 ret=E_BUG;
00578 goto error;
00579 }
00580 getbflagsval(0, (flag_t*)&flags);
00581 ret=append_branch(msg, &a->val[0].u.str, &msg->dst_uri,
00582 &msg->path_vec, a->val[1].u.number,
00583 (flag_t)flags, msg->force_send_socket);
00584
00585
00586 if ((a->val[0].u.str.s == 0 || a->val[0].u.str.len == 0) &&
00587 a->val[1].u.number == Q_UNSPECIFIED)
00588 ruri_mark_consumed();
00589 break;
00590
00591
00592 case REMOVE_BRANCH_T:
00593 if (a->val[0].type!=NUMBER_ST) {
00594 ret=drop_sip_branch(0) ? -1 : 1;
00595 } else {
00596 ret=drop_sip_branch(a->val[0].u.number) ? -1 : 1;
00597 }
00598 break;
00599
00600
00601 case CLEAR_BRANCHES_T:
00602 clear_branches();
00603 ret=1;
00604 break;
00605
00606
00607 case LEN_GT_T:
00608 if (a->val[0].type!=NUMBER_ST) {
00609 LOG(L_CRIT, "BUG: do_action: bad len_gt type %d\n",
00610 a->val[0].type );
00611 ret=E_BUG;
00612 goto error;
00613 }
00614
00615
00616 ret = msg->len >= a->val[0].u.number ? 1 : -1;
00617 break;
00618
00619
00620
00621
00622 case SETFLAG_T:
00623 if (a->val[0].type!=NUMBER_ST) {
00624 LOG(L_CRIT, "BUG: do_action: bad setflag() type %d\n",
00625 a->val[0].type );
00626 ret=E_BUG;
00627 goto error;
00628 }
00629 if (!flag_in_range( a->val[0].u.number )) {
00630 ret=E_CFG;
00631 goto error;
00632 }
00633 setflag( msg, a->val[0].u.number );
00634 ret=1;
00635 break;
00636
00637 case RESETFLAG_T:
00638 if (a->val[0].type!=NUMBER_ST) {
00639 LOG(L_CRIT, "BUG: do_action: bad resetflag() type %d\n",
00640 a->val[0].type );
00641 ret=E_BUG;
00642 goto error;
00643 }
00644 if (!flag_in_range( a->val[0].u.number )) {
00645 ret=E_CFG;
00646 goto error;
00647 }
00648 resetflag( msg, a->val[0].u.number );
00649 ret=1;
00650 break;
00651
00652 case ISFLAGSET_T:
00653 if (a->val[0].type!=NUMBER_ST) {
00654 LOG(L_CRIT, "BUG: do_action: bad isflagset() type %d\n",
00655 a->val[0].type );
00656 ret=E_BUG;
00657 goto error;
00658 }
00659 if (!flag_in_range( a->val[0].u.number )) {
00660 ret=E_CFG;
00661 goto error;
00662 }
00663 ret=isflagset( msg, a->val[0].u.number );
00664 break;
00665
00666
00667 case AVPFLAG_OPER_T:
00668 ret = 0;
00669 if ((a->val[0].u.attr->type & AVP_INDEX_ALL) == AVP_INDEX_ALL ||
00670 (a->val[0].u.attr->type & AVP_NAME_RE)!=0) {
00671 for (avp=search_first_avp(a->val[0].u.attr->type,
00672 a->val[0].u.attr->name, NULL, &st);
00673 avp;
00674 avp = search_next_avp(&st, NULL)) {
00675 switch (a->val[2].u.number) {
00676
00677 case 0:
00678 avp->flags &= ~(avp_flags_t)a->val[1].u.number;
00679 break;
00680 case 1:
00681 avp->flags |= (avp_flags_t)a->val[1].u.number;
00682 break;
00683 default:;
00684 }
00685 ret = ret ||
00686 ((avp->flags & (avp_flags_t)a->val[1].u.number) != 0);
00687 }
00688 } else {
00689 avp = search_avp_by_index(a->val[0].u.attr->type,
00690 a->val[0].u.attr->name, NULL,
00691 a->val[0].u.attr->index);
00692 if (avp) {
00693 switch (a->val[2].u.number) {
00694
00695 case 0:
00696 avp->flags &= ~(avp_flags_t)a->val[1].u.number;
00697 break;
00698 case 1:
00699 avp->flags |= (avp_flags_t)a->val[1].u.number;
00700 break;
00701 default:;
00702 }
00703 ret = (avp->flags & (avp_flags_t)a->val[1].u.number) != 0;
00704 }
00705 }
00706 if (ret==0)
00707 ret = -1;
00708 break;
00709 case ERROR_T:
00710 if ((a->val[0].type!=STRING_ST)|(a->val[1].type!=STRING_ST)){
00711 LOG(L_CRIT, "BUG: do_action: bad error() types %d, %d\n",
00712 a->val[0].type, a->val[1].type);
00713 ret=E_BUG;
00714 goto error;
00715 }
00716 LOG(L_NOTICE, "WARNING: do_action: error(\"%s\", \"%s\") "
00717 "not implemented yet\n", a->val[0].u.string, a->val[1].u.string);
00718 ret=1;
00719 break;
00720 case ROUTE_T:
00721 if (likely(a->val[0].type == NUMBER_ST))
00722 i = a->val[0].u.number;
00723 else if (a->val[0].type == RVE_ST) {
00724 rv = rval_expr_eval(h, msg, a->val[0].u.data);
00725 rval_cache_init(&c1);
00726 if (unlikely(rv == 0 ||
00727 rval_get_tmp_str(h, msg, &s, rv, 0, &c1) < 0)) {
00728 rval_destroy(rv);
00729 rval_cache_clean(&c1);
00730 ERR("failed to convert RVE to string\n");
00731 ret = E_UNSPEC;
00732 goto error;
00733 }
00734 i = route_lookup(&main_rt, s.s);
00735 if (unlikely(i < 0)) {
00736 ERR("route \"%s\" not found at %s:%d\n",
00737 s.s, (a->cfile)?a->cfile:"line", a->cline);
00738 rval_destroy(rv);
00739 rval_cache_clean(&c1);
00740 s.s = 0;
00741 ret = E_SCRIPT;
00742 goto error;
00743 }
00744 rval_destroy(rv);
00745 rval_cache_clean(&c1);
00746 s.s = 0;
00747 } else {
00748 LOG(L_CRIT, "BUG: do_action: bad route() type %d\n",
00749 a->val[0].type);
00750 ret=E_BUG;
00751 goto error;
00752 }
00753 if (unlikely((i>=main_rt.idx)||(i<0))){
00754 LOG(L_ERR, "ERROR: invalid routing table number in"
00755 "route(%lu) at %s:%d\n", a->val[0].u.number,
00756 (a->cfile)?a->cfile:"line", a->cline);
00757 ret=E_CFG;
00758 goto error;
00759 }
00760
00761 ret=run_actions(h, main_rt.rlist[i], msg);
00762 h->last_retcode=ret;
00763 _last_returned_code = h->last_retcode;
00764 h->run_flags&=~(RETURN_R_F|BREAK_R_F);
00765 break;
00766 case EXEC_T:
00767 if (a->val[0].type!=STRING_ST){
00768 LOG(L_CRIT, "BUG: do_action: bad exec() type %d\n",
00769 a->val[0].type);
00770 ret=E_BUG;
00771 goto error;
00772 }
00773 LOG(L_NOTICE, "WARNING: exec(\"%s\") not fully implemented,"
00774 " using dumb version...\n", a->val[0].u.string);
00775 ret=system(a->val[0].u.string);
00776 if (ret!=0){
00777 LOG(L_NOTICE, "WARNING: exec() returned %d\n", ret);
00778 }
00779 ret=1;
00780 break;
00781 case REVERT_URI_T:
00782 if (msg->new_uri.s) {
00783 pkg_free(msg->new_uri.s);
00784 msg->new_uri.len=0;
00785 msg->new_uri.s=0;
00786 msg->parsed_uri_ok=0;
00787 ruri_mark_new();
00788 };
00789 ret=1;
00790 break;
00791 case SET_HOST_T:
00792 case SET_HOSTPORT_T:
00793 case SET_HOSTPORTTRANS_T:
00794 case SET_HOSTALL_T:
00795 case SET_USER_T:
00796 case SET_USERPASS_T:
00797 case SET_PORT_T:
00798 case SET_URI_T:
00799 case PREFIX_T:
00800 case STRIP_T:
00801 case STRIP_TAIL_T:
00802 case SET_USERPHONE_T:
00803 user=0;
00804 if (a->type==STRIP_T || a->type==STRIP_TAIL_T) {
00805 if (a->val[0].type!=NUMBER_ST) {
00806 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
00807 a->val[0].type);
00808 ret=E_BUG;
00809 goto error;
00810 }
00811 } else if (a->type!=SET_USERPHONE_T) {
00812 if (a->val[0].type!=STRING_ST) {
00813 LOG(L_CRIT, "BUG: do_action: bad set*() type %d\n",
00814 a->val[0].type);
00815 ret=E_BUG;
00816 goto error;
00817 }
00818 }
00819 if (a->type==SET_URI_T){
00820 if (msg->new_uri.s) {
00821 pkg_free(msg->new_uri.s);
00822 msg->new_uri.len=0;
00823 }
00824 msg->parsed_uri_ok=0;
00825 len=strlen(a->val[0].u.string);
00826 msg->new_uri.s=pkg_malloc(len+1);
00827 if (msg->new_uri.s==0){
00828 LOG(L_ERR, "ERROR: do_action: memory allocation"
00829 " failure\n");
00830 ret=E_OUT_OF_MEM;
00831 goto error;
00832 }
00833 memcpy(msg->new_uri.s, a->val[0].u.string, len);
00834 msg->new_uri.s[len]=0;
00835 msg->new_uri.len=len;
00836 ruri_mark_new();
00837
00838 ret=1;
00839 break;
00840 }
00841 if (msg->parsed_uri_ok==0) {
00842 if (msg->new_uri.s) {
00843 tmp=msg->new_uri.s;
00844 len=msg->new_uri.len;
00845 }else{
00846 tmp=msg->first_line.u.request.uri.s;
00847 len=msg->first_line.u.request.uri.len;
00848 }
00849 if (parse_uri(tmp, len, &uri)<0){
00850 LOG(L_ERR, "ERROR: do_action: bad uri <%s>, dropping"
00851 " packet\n", tmp);
00852 ret=E_UNSPEC;
00853 goto error;
00854 }
00855 } else {
00856 uri=msg->parsed_uri;
00857 }
00858
00859
00860
00861 if ((a->type==SET_USERPHONE_T)
00862 && ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T)
00863 || ((uri.user_param_val.len==5) && (memcmp(uri.user_param_val.s, "phone", 5)==0)))
00864 ) {
00865 ret=1;
00866 break;
00867 }
00868
00869 if ((a->type==SET_PORT_T)
00870 && ((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
00871 && ((uri.flags & URI_SIP_USER_PHONE)==0)
00872 ) {
00873 LOG(L_ERR, "ERROR: do_action: port number of a tel: URI cannot be set\n");
00874 ret=E_UNSPEC;
00875 goto error;
00876 }
00877
00878 new_uri=pkg_malloc(MAX_URI_SIZE);
00879 if (new_uri==0){
00880 LOG(L_ERR, "ERROR: do_action: memory allocation "
00881 " failure\n");
00882 ret=E_OUT_OF_MEM;
00883 goto error;
00884 }
00885 end=new_uri+MAX_URI_SIZE;
00886 crt=new_uri;
00887
00888
00889
00890 switch (uri.type) {
00891 case SIP_URI_T:
00892 len=s_sip.len;
00893 tmp=s_sip.s;
00894 break;
00895
00896 case SIPS_URI_T:
00897 len=s_sips.len;
00898 tmp=s_sips.s;
00899 break;
00900
00901 case TEL_URI_T:
00902 if ((uri.flags & URI_SIP_USER_PHONE)
00903 || (a->type==SET_HOST_T)
00904 || (a->type==SET_HOSTPORT_T)
00905 || (a->type==SET_HOSTPORTTRANS_T)
00906 ) {
00907 len=s_sip.len;
00908 tmp=s_sip.s;
00909 break;
00910 }
00911 len=s_tel.len;
00912 tmp=s_tel.s;
00913 break;
00914
00915 case TELS_URI_T:
00916 if ((uri.flags & URI_SIP_USER_PHONE)
00917 || (a->type==SET_HOST_T)
00918 || (a->type==SET_HOSTPORT_T)
00919 || (a->type==SET_HOSTPORTTRANS_T)
00920 ) {
00921 len=s_sips.len;
00922 tmp=s_sips.s;
00923 break;
00924 }
00925 len=s_tels.len;
00926 tmp=s_tels.s;
00927 break;
00928
00929 default:
00930 LOG(L_ERR, "ERROR: Unsupported URI scheme (%d), "
00931 "reverted to sip:\n",
00932 uri.type);
00933 len=s_sip.len;
00934 tmp=s_sip.s;
00935 }
00936 if(crt+len+1 >end) goto error_uri;
00937 memcpy(crt,tmp,len);crt+=len;
00938 *crt=':'; crt++;
00939
00940
00941
00942
00943 if (a->type==PREFIX_T) {
00944 tmp=a->val[0].u.string;
00945 len=strlen(tmp); if(crt+len>end) goto error_uri;
00946 memcpy(crt,tmp,len);crt+=len;
00947
00948
00949 user=1;
00950 }
00951
00952 if ((a->type==SET_USER_T)||(a->type==SET_USERPASS_T)) {
00953 tmp=a->val[0].u.string;
00954 len=strlen(tmp);
00955 } else if (a->type==STRIP_T) {
00956 if (a->val[0].u.number>uri.user.len) {
00957 LOG(L_WARN, "Error: too long strip asked; "
00958 " deleting username: %lu of <%.*s>\n",
00959 a->val[0].u.number, uri.user.len, uri.user.s );
00960 len=0;
00961 } else if (a->val[0].u.number==uri.user.len) {
00962 len=0;
00963 } else {
00964 tmp=uri.user.s + a->val[0].u.number;
00965 len=uri.user.len - a->val[0].u.number;
00966 }
00967 } else if (a->type==STRIP_TAIL_T) {
00968 if (a->val[0].u.number>uri.user.len) {
00969 LOG(L_WARN, "WARNING: too long strip_tail asked; "
00970 " deleting username: %lu of <%.*s>\n",
00971 a->val[0].u.number, uri.user.len, uri.user.s );
00972 len=0;
00973 } else if (a->val[0].u.number==uri.user.len) {
00974 len=0;
00975 } else {
00976 tmp=uri.user.s;
00977 len=uri.user.len - a->val[0].u.number;
00978 }
00979 } else {
00980 tmp=uri.user.s;
00981 len=uri.user.len;
00982 }
00983
00984 if (len){
00985 if(crt+len>end) goto error_uri;
00986 memcpy(crt,tmp,len);crt+=len;
00987 user=1;
00988 }
00989
00990 if (a->type==SET_USERPASS_T) tmp=0;
00991 else tmp=uri.passwd.s;
00992
00993 if (tmp){
00994 len=uri.passwd.len; if(crt+len+1>end) goto error_uri;
00995 *crt=':'; crt++;
00996 memcpy(crt,tmp,len);crt+=len;
00997 }
00998
00999 if ((uri.type==TEL_URI_T)
01000 || (uri.type==TELS_URI_T)
01001 ) {
01002 tmp=uri.params.s;
01003 if (tmp){
01004 len=uri.params.len; if(crt+len+1>end) goto error_uri;
01005 *crt=';'; crt++;
01006 memcpy(crt,tmp,len);crt+=len;
01007 }
01008 }
01009
01010 if ((a->type==SET_HOST_T)
01011 || (a->type==SET_HOSTPORT_T)
01012 || (a->type==SET_HOSTALL_T)
01013 || (a->type==SET_HOSTPORTTRANS_T)
01014 ) {
01015 tmp=a->val[0].u.string;
01016 if (tmp) len = strlen(tmp);
01017 else len=0;
01018 } else if ((uri.type==SIP_URI_T)
01019 || (uri.type==SIPS_URI_T)
01020 || (uri.flags & URI_SIP_USER_PHONE)
01021 ) {
01022 tmp=uri.host.s;
01023 len=uri.host.len;
01024 } else {
01025 tmp=0;
01026 }
01027 if (tmp){
01028 if (user) {
01029 if(crt+1>end) goto error_uri;
01030 *crt='@'; crt++;
01031 }
01032 if(crt+len>end) goto error_uri;
01033 memcpy(crt,tmp,len);crt+=len;
01034 }
01035 if(a->type==SET_HOSTALL_T)
01036 goto done_seturi;
01037
01038 if ((a->type==SET_HOSTPORT_T)
01039 || (a->type==SET_HOSTPORTTRANS_T))
01040 tmp=0;
01041 else if (a->type==SET_PORT_T) {
01042 tmp=a->val[0].u.string;
01043 if (tmp) {
01044 len = strlen(tmp);
01045 if(len==0) tmp = 0;
01046 } else len = 0;
01047 } else {
01048 tmp=uri.port.s;
01049 len = uri.port.len;
01050 }
01051 if (tmp){
01052 if(crt+len+1>end) goto error_uri;
01053 *crt=':'; crt++;
01054 memcpy(crt,tmp,len);crt+=len;
01055 }
01056
01057 if ((a->type==SET_HOSTPORTTRANS_T)
01058 && uri.sip_params.s
01059 && uri.transport.s
01060 ) {
01061
01062 if (uri.sip_params.s < uri.transport.s) {
01063
01064 len = uri.transport.s - uri.sip_params.s - 1;
01065
01066 if (crt+len+1>end) goto error_uri;
01067 *crt=';'; crt++;
01068 memcpy(crt,uri.sip_params.s,len);crt+=len;
01069 }
01070 len = (uri.sip_params.s + uri.sip_params.len) -
01071 (uri.transport.s + uri.transport.len);
01072 if (len > 0) {
01073
01074 if (crt+len>end) goto error_uri;
01075 tmp = uri.transport.s + uri.transport.len;
01076 memcpy(crt,tmp,len);crt+=len;
01077 }
01078 } else {
01079 tmp=uri.sip_params.s;
01080 if (tmp){
01081 len=uri.sip_params.len; if(crt+len+1>end) goto error_uri;
01082 *crt=';'; crt++;
01083 memcpy(crt,tmp,len);crt+=len;
01084 }
01085 }
01086
01087
01088
01089
01090 if (((((uri.type==TEL_URI_T) || (uri.type==TELS_URI_T))
01091 && ((uri.flags & URI_SIP_USER_PHONE)==0))
01092 && ((a->type==SET_HOST_T)
01093 || (a->type==SET_HOSTPORT_T)
01094 || (a->type==SET_HOSTPORTTRANS_T)))
01095 || (a->type==SET_USERPHONE_T)
01096 ) {
01097 tmp=";user=phone";
01098 len=strlen(tmp);
01099 if(crt+len>end) goto error_uri;
01100 memcpy(crt,tmp,len);crt+=len;
01101 }
01102
01103 tmp=uri.headers.s;
01104 if (tmp){
01105 len=uri.headers.len; if(crt+len+1>end) goto error_uri;
01106 *crt='?'; crt++;
01107 memcpy(crt,tmp,len);crt+=len;
01108 }
01109 done_seturi:
01110 *crt=0;
01111
01112 if (msg->new_uri.s) pkg_free(msg->new_uri.s);
01113 msg->new_uri.s=new_uri;
01114 msg->new_uri.len=crt-new_uri;
01115 msg->parsed_uri_ok=0;
01116 ruri_mark_new();
01117 ret=1;
01118 break;
01119 case IF_T:
01120 rve=(struct rval_expr*)a->val[0].u.data;
01121 if (unlikely(rval_expr_eval_int(h, msg, &v, rve) != 0)){
01122 ERR("if expression evaluation failed (%d,%d-%d,%d)\n",
01123 rve->fpos.s_line, rve->fpos.s_col,
01124 rve->fpos.e_line, rve->fpos.e_col);
01125 v=0;
01126 }
01127 if (unlikely(h->run_flags & EXIT_R_F)){
01128 ret=0;
01129 break;
01130 }
01131 h->run_flags &= ~(RETURN_R_F|BREAK_R_F);
01132
01133 ret=1;
01134 if (v>0) {
01135 if ((a->val[1].type==ACTIONS_ST)&&a->val[1].u.data){
01136 ret=run_actions(h,
01137 (struct action*)a->val[1].u.data, msg);
01138 }
01139 }else if ((a->val[2].type==ACTIONS_ST)&&a->val[2].u.data){
01140 ret=run_actions(h,
01141 (struct action*)a->val[2].u.data, msg);
01142 }
01143 break;
01144 case MODULE0_T:
01145 MODF_CALL(cmd_function, h, msg, a->val, 0, 0);
01146 break;
01147
01148
01149
01150 case MODULE1_T:
01151 MODF_CALL(cmd_function, h, msg, a->val,
01152 (char*)a->val[2].u.data,
01153 0
01154 );
01155 break;
01156 case MODULE2_T:
01157 MODF_CALL(cmd_function, h, msg, a->val,
01158 (char*)a->val[2].u.data,
01159 (char*)a->val[3].u.data
01160 );
01161 break;
01162 case MODULE3_T:
01163 MODF_CALL(cmd_function3, h, msg, a->val,
01164 (char*)a->val[2].u.data,
01165 (char*)a->val[3].u.data,
01166 (char*)a->val[4].u.data
01167 );
01168 break;
01169 case MODULE4_T:
01170 MODF_CALL(cmd_function4, h, msg, a->val,
01171 (char*)a->val[2].u.data,
01172 (char*)a->val[3].u.data,
01173 (char*)a->val[4].u.data,
01174 (char*)a->val[5].u.data
01175 );
01176 break;
01177 case MODULE5_T:
01178 MODF_CALL(cmd_function5, h, msg, a->val,
01179 (char*)a->val[2].u.data,
01180 (char*)a->val[3].u.data,
01181 (char*)a->val[4].u.data,
01182 (char*)a->val[5].u.data,
01183 (char*)a->val[6].u.data
01184 );
01185 break;
01186 case MODULE6_T:
01187 MODF_CALL(cmd_function6, h, msg, a->val,
01188 (char*)a->val[2].u.data,
01189 (char*)a->val[3].u.data,
01190 (char*)a->val[4].u.data,
01191 (char*)a->val[5].u.data,
01192 (char*)a->val[6].u.data,
01193 (char*)a->val[7].u.data
01194 );
01195 break;
01196 case MODULEX_T:
01197 MODF_CALL(cmd_function_var, h, msg, a->val,
01198 a->val[1].u.number, &a->val[2]);
01199 break;
01200 case MODULE1_RVE_T:
01201 MODF_RVE_CALL(cmd_function, h, msg, a->val, mod_f_params,
01202 (char*)mod_f_params[2].u.data,
01203 0
01204 );
01205 break;
01206 case MODULE2_RVE_T:
01207 MODF_RVE_CALL(cmd_function, h, msg, a->val, mod_f_params,
01208 (char*)mod_f_params[2].u.data,
01209 (char*)mod_f_params[3].u.data
01210 );
01211 break;
01212 case MODULE3_RVE_T:
01213 MODF_RVE_CALL(cmd_function3, h, msg, a->val, mod_f_params,
01214 (char*)mod_f_params[2].u.data,
01215 (char*)mod_f_params[3].u.data,
01216 (char*)mod_f_params[4].u.data
01217 );
01218 break;
01219 case MODULE4_RVE_T:
01220 MODF_RVE_CALL(cmd_function4, h, msg, a->val, mod_f_params,
01221 (char*)mod_f_params[2].u.data,
01222 (char*)mod_f_params[3].u.data,
01223 (char*)mod_f_params[4].u.data,
01224 (char*)mod_f_params[5].u.data
01225 );
01226 break;
01227 case MODULE5_RVE_T:
01228 MODF_RVE_CALL(cmd_function5, h, msg, a->val, mod_f_params,
01229 (char*)mod_f_params[2].u.data,
01230 (char*)mod_f_params[3].u.data,
01231 (char*)mod_f_params[4].u.data,
01232 (char*)mod_f_params[5].u.data,
01233 (char*)mod_f_params[6].u.data
01234 );
01235 break;
01236 case MODULE6_RVE_T:
01237 MODF_RVE_CALL(cmd_function6, h, msg, a->val, mod_f_params,
01238 (char*)mod_f_params[2].u.data,
01239 (char*)mod_f_params[3].u.data,
01240 (char*)mod_f_params[4].u.data,
01241 (char*)mod_f_params[5].u.data,
01242 (char*)mod_f_params[6].u.data,
01243 (char*)mod_f_params[7].u.data
01244 );
01245 break;
01246 case MODULEX_RVE_T:
01247 MODF_RVE_CALL(cmd_function_var, h, msg, a->val, mod_f_params,
01248 a->val[1].u.number, &mod_f_params[2]);
01249 break;
01250 case EVAL_T:
01251
01252
01253 rval_expr_eval_int(h, msg, &v,
01254 (struct rval_expr*)a->val[0].u.data);
01255 if (h->run_flags & EXIT_R_F){
01256 ret=0;
01257 break;
01258 }
01259 h->run_flags &= ~RETURN_R_F|BREAK_R_F;
01260
01261 ret=1;
01262 break;
01263 case SWITCH_COND_T:
01264 sct=(struct switch_cond_table*)a->val[1].u.data;
01265 if (unlikely( rval_expr_eval_int(h, msg, &v,
01266 (struct rval_expr*)a->val[0].u.data) <0)){
01267
01268 ret=-1;
01269 goto sw_cond_def;
01270 }
01271 if (h->run_flags & EXIT_R_F){
01272 ret=0;
01273 break;
01274 }
01275 h->run_flags &= ~(RETURN_R_F|BREAK_R_F);
01276
01277 ret=1;
01278 for(i=0; i<sct->n; i++)
01279 if (sct->cond[i]==v){
01280 if (likely(sct->jump[i])){
01281 ret=run_actions(h, sct->jump[i], msg);
01282 h->run_flags &= ~BREAK_R_F;
01283
01284 }
01285 goto skip;
01286 }
01287 sw_cond_def:
01288 if (sct->def){
01289 ret=run_actions(h, sct->def, msg);
01290 h->run_flags &= ~BREAK_R_F;
01291
01292 }
01293 break;
01294 case SWITCH_JT_T:
01295 sjt=(struct switch_jmp_table*)a->val[1].u.data;
01296 if (unlikely( rval_expr_eval_int(h, msg, &v,
01297 (struct rval_expr*)a->val[0].u.data) <0)){
01298
01299 ret=-1;
01300 goto sw_jt_def;
01301 }
01302 if (h->run_flags & EXIT_R_F){
01303 ret=0;
01304 break;
01305 }
01306 h->run_flags &= ~(RETURN_R_F|BREAK_R_F);
01307
01308 ret=1;
01309 if (likely(v >= sjt->first && v <= sjt->last)){
01310 if (likely(sjt->tbl[v - sjt->first])){
01311 ret=run_actions(h, sjt->tbl[v - sjt->first], msg);
01312 h->run_flags &= ~BREAK_R_F;
01313
01314 }
01315 break;
01316 }else{
01317 for(i=0; i<sjt->rest.n; i++)
01318 if (sjt->rest.cond[i]==v){
01319 if (likely(sjt->rest.jump[i])){
01320 ret=run_actions(h, sjt->rest.jump[i], msg);
01321 h->run_flags &= ~BREAK_R_F;
01322
01323 }
01324 goto skip;
01325 }
01326 }
01327
01328 sw_jt_def:
01329 if (sjt->rest.def){
01330 ret=run_actions(h, sjt->rest.def, msg);
01331 h->run_flags &= ~BREAK_R_F;
01332
01333 }
01334 break;
01335 case BLOCK_T:
01336 if (likely(a->val[0].u.data)){
01337 ret=run_actions(h, (struct action*)a->val[0].u.data, msg);
01338 h->run_flags &= ~BREAK_R_F;
01339
01340 }
01341 break;
01342 case MATCH_COND_T:
01343 mct=(struct match_cond_table*)a->val[1].u.data;
01344 rval_cache_init(&c1);
01345 rv=0;
01346 rv1=0;
01347 ret=rval_expr_eval_rvint(h, msg, &rv, &v,
01348 (struct rval_expr*)a->val[0].u.data, &c1);
01349
01350 if (unlikely( ret<0)){
01351
01352 ret=-1;
01353 goto match_cond_def;
01354 }
01355 if (h->run_flags & EXIT_R_F){
01356 ret=0;
01357 break;
01358 }
01359 h->run_flags &= ~(RETURN_R_F|BREAK_R_F);
01360
01361 if (likely(rv)){
01362 rv1=rval_convert(h, msg, RV_STR, rv, &c1);
01363 if (unlikely(rv1==0)){
01364 ret=-1;
01365 goto match_cond_def;
01366 }
01367 s=rv1->v.s;
01368 }else{
01369
01370 rval_cache_clean(&c1);
01371 s.s=sint2str(v, &s.len);
01372 }
01373 ret=1;
01374 for(i=0; i<mct->n; i++)
01375 if (( mct->match[i].type==MATCH_STR &&
01376 mct->match[i].l.s.len==s.len &&
01377 memcmp(mct->match[i].l.s.s, s.s, s.len) == 0 ) ||
01378 ( mct->match[i].type==MATCH_RE &&
01379 regexec(mct->match[i].l.regex, s.s, 0, 0, 0) == 0)
01380 ){
01381 if (likely(mct->jump[i])){
01382
01383
01384 if (rv1){
01385 rval_destroy(rv1);
01386 rval_destroy(rv);
01387 rval_cache_clean(&c1);
01388 }else if (rv){
01389 rval_destroy(rv);
01390 rval_cache_clean(&c1);
01391 }
01392 ret=run_actions(h, mct->jump[i], msg);
01393 h->run_flags &= ~BREAK_R_F;
01394
01395 goto skip;
01396 }
01397 goto match_cleanup;
01398 }
01399 match_cond_def:
01400 if (mct->def){
01401
01402
01403 if (rv1){
01404 rval_destroy(rv1);
01405 rval_destroy(rv);
01406 rval_cache_clean(&c1);
01407 }else if (rv){
01408 rval_destroy(rv);
01409 rval_cache_clean(&c1);
01410 }
01411 ret=run_actions(h, mct->def, msg);
01412 h->run_flags &= ~BREAK_R_F;
01413
01414 break;
01415 }
01416 match_cleanup:
01417 if (rv1){
01418 rval_destroy(rv1);
01419 rval_destroy(rv);
01420 rval_cache_clean(&c1);
01421 }else if (rv){
01422 rval_destroy(rv);
01423 rval_cache_clean(&c1);
01424 }
01425 break;
01426 case WHILE_T:
01427 i=0;
01428 flags=0;
01429 rve=(struct rval_expr*)a->val[0].u.data;
01430 ret=1;
01431 while(!(flags & (BREAK_R_F|RETURN_R_F|EXIT_R_F)) &&
01432 (rval_expr_eval_int(h, msg, &v, rve) == 0) && v){
01433 if (cfg_get(core, core_cfg, max_while_loops) > 0)
01434 i++;
01435
01436 if (unlikely(i > cfg_get(core, core_cfg, max_while_loops))){
01437 LOG(L_ERR, "ERROR: runaway while (%d, %d): more then"
01438 " %d loops\n",
01439 rve->fpos.s_line, rve->fpos.s_col,
01440 cfg_get(core, core_cfg, max_while_loops));
01441 ret=-1;
01442 goto error;
01443 }
01444 if (likely(a->val[1].u.data)){
01445 ret=run_actions(h, (struct action*)a->val[1].u.data, msg);
01446 flags|=h->run_flags;
01447 h->run_flags &= ~BREAK_R_F;
01448
01449 }
01450 }
01451 break;
01452 case FORCE_RPORT_T:
01453 msg->msg_flags|=FL_FORCE_RPORT;
01454 ret=1;
01455 break;
01456 case ADD_LOCAL_RPORT_T:
01457 msg->msg_flags|=FL_ADD_LOCAL_RPORT;
01458 ret=1;
01459 break;
01460 case UDP_MTU_TRY_PROTO_T:
01461 msg->msg_flags|= (unsigned int)a->val[0].u.number & FL_MTU_FB_MASK;
01462 ret=1;
01463 break;
01464 case SET_ADV_ADDR_T:
01465 if (a->val[0].type!=STR_ST){
01466 LOG(L_CRIT, "BUG: do_action: bad set_advertised_address() "
01467 "type %d\n", a->val[0].type);
01468 ret=E_BUG;
01469 goto error;
01470 }
01471 msg->set_global_address=*((str*)a->val[0].u.data);
01472 ret=1;
01473 break;
01474 case SET_ADV_PORT_T:
01475 if (a->val[0].type!=STR_ST){
01476 LOG(L_CRIT, "BUG: do_action: bad set_advertised_port() "
01477 "type %d\n", a->val[0].type);
01478 ret=E_BUG;
01479 goto error;
01480 }
01481 msg->set_global_port=*((str*)a->val[0].u.data);
01482 ret=1;
01483 break;
01484 #ifdef USE_TCP
01485 case FORCE_TCP_ALIAS_T:
01486 if ( msg->rcv.proto==PROTO_TCP
01487 #ifdef USE_TLS
01488 || msg->rcv.proto==PROTO_TLS
01489 #endif
01490 ){
01491
01492 if (a->val[0].type==NOSUBTYPE) port=msg->via1->port;
01493 else if (a->val[0].type==NUMBER_ST) port=(int)a->val[0].u.number;
01494 else{
01495 LOG(L_CRIT, "BUG: do_action: bad force_tcp_alias"
01496 " port type %d\n", a->val[0].type);
01497 ret=E_BUG;
01498 goto error;
01499 }
01500
01501 if (tcpconn_add_alias(msg->rcv.proto_reserved1, port,
01502 msg->rcv.proto)!=0){
01503 LOG(L_ERR, " ERROR: receive_msg: tcp alias failed\n");
01504 ret=E_UNSPEC;
01505 goto error;
01506 }
01507 }
01508 #endif
01509 ret=1;
01510 break;
01511 case FORCE_SEND_SOCKET_T:
01512 if (a->val[0].type!=SOCKETINFO_ST){
01513 LOG(L_CRIT, "BUG: do_action: bad force_send_socket argument"
01514 " type: %d\n", a->val[0].type);
01515 ret=E_BUG;
01516 goto error;
01517 }
01518 set_force_socket(msg, (struct socket_info*)a->val[0].u.data);
01519 ret=1;
01520 break;
01521
01522 case ADD_T:
01523 case ASSIGN_T:
01524 v=lval_assign(h, msg, (struct lvalue*)a->val[0].u.data,
01525 (struct rval_expr*)a->val[1].u.data);
01526 if (likely(v>=0))
01527 ret = 1;
01528 else if (unlikely (v == EXPR_DROP))
01529 ret=0;
01530 else
01531 ret=v;
01532 break;
01533 case SET_FWD_NO_CONNECT_T:
01534 msg->fwd_send_flags.f|= SND_F_FORCE_CON_REUSE;
01535 ret=1;
01536 break;
01537 case SET_RPL_NO_CONNECT_T:
01538 msg->rpl_send_flags.f|= SND_F_FORCE_CON_REUSE;
01539 ret=1;
01540 break;
01541 case SET_FWD_CLOSE_T:
01542 msg->fwd_send_flags.f|= SND_F_CON_CLOSE;
01543 ret=1;
01544 break;
01545 case SET_RPL_CLOSE_T:
01546 msg->rpl_send_flags.f|= SND_F_CON_CLOSE;
01547 ret=1;
01548 break;
01549 case CFG_SELECT_T:
01550 if (a->val[0].type != CFG_GROUP_ST) {
01551 BUG("unsupported parameter in CFG_SELECT_T: %d\n",
01552 a->val[0].type);
01553 ret=-1;
01554 goto error;
01555 }
01556 switch(a->val[1].type) {
01557 case NUMBER_ST:
01558 v=(int)a->val[1].u.number;
01559 break;
01560 case RVE_ST:
01561 if (rval_expr_eval_int(h, msg, &v, (struct rval_expr*)a->val[1].u.data) < 0) {
01562 ret=-1;
01563 goto error;
01564 }
01565 break;
01566 default:
01567 BUG("unsupported group id type in CFG_SELECT_T: %d\n",
01568 a->val[1].type);
01569 ret=-1;
01570 goto error;
01571 }
01572 ret=(cfg_select((cfg_group_t*)a->val[0].u.data, v) == 0) ? 1 : -1;
01573 break;
01574 case CFG_RESET_T:
01575 if (a->val[0].type != CFG_GROUP_ST) {
01576 BUG("unsupported parameter in CFG_RESET_T: %d\n",
01577 a->val[0].type);
01578 ret=-1;
01579 goto error;
01580 }
01581 ret=(cfg_reset((cfg_group_t*)a->val[0].u.data) == 0) ? 1 : -1;
01582 break;
01583
01584
01585
01586
01587 }
01588 skip:
01589 return ret;
01590
01591 error_uri:
01592 LOG(L_ERR, "ERROR: do_action: set*: uri too long\n");
01593 if (new_uri) pkg_free(new_uri);
01594 LM_ERR("run action error at: %s:%d\n", (a->cfile)?a->cfile:"", a->cline);
01595 return E_UNSPEC;
01596 error_fwd_uri:
01597
01598 error:
01599 LM_ERR("run action error at: %s:%d\n", (a->cfile)?a->cfile:"", a->cline);
01600 return ret;
01601 }
01602
01603
01604
01605
01606
01607 int run_actions(struct run_act_ctx* h, struct action* a, struct sip_msg* msg)
01608 {
01609 struct action* t;
01610 int ret;
01611 struct sr_module *mod;
01612 unsigned int ms = 0;
01613
01614 ret=E_UNSPEC;
01615 h->rec_lev++;
01616 if (unlikely(h->rec_lev>ROUTE_MAX_REC_LEV)){
01617 LOG(L_ERR, "WARNING: too many recursive routing table lookups (%d)"
01618 " giving up!\n", h->rec_lev);
01619 ret=E_UNSPEC;
01620 goto error;
01621 }
01622 if (unlikely(h->rec_lev==1)){
01623 h->run_flags=0;
01624 h->last_retcode=0;
01625 _last_returned_code = h->last_retcode;
01626 #ifdef USE_LONGJMP
01627 if (unlikely(setjmp(h->jmp_env))){
01628 h->rec_lev=0;
01629 ret=h->last_retcode;
01630 goto end;
01631 }
01632 #endif
01633 }
01634
01635 if (unlikely(a==0)){
01636 DBG("DEBUG: run_actions: null action list (rec_level=%d)\n",
01637 h->rec_lev);
01638 ret=1;
01639 }
01640
01641 for (t=a; t!=0; t=t->next){
01642 if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0))
01643 ms = TICKS_TO_MS(get_ticks_raw());
01644 ret=do_action(h, t, msg);
01645 if(unlikely(cfg_get(core, core_cfg, latency_limit_action)>0)) {
01646 ms = TICKS_TO_MS(get_ticks_raw()) - ms;
01647 if(ms >= cfg_get(core, core_cfg, latency_limit_action)) {
01648 LOG(cfg_get(core, core_cfg, latency_log),
01649 "alert - action [%s (%d)]"
01650 " cfg [%s:%d] took too long [%u ms]\n",
01651 is_mod_func(t) ?
01652 ((cmd_export_common_t*)(t->val[0].u.data))->name
01653 : "corefunc",
01654 t->type, (t->cfile)?t->cfile:"", t->cline, ms);
01655 }
01656 }
01657
01658
01659 if (unlikely(h->run_flags & (BREAK_R_F|RETURN_R_F|EXIT_R_F))){
01660 if (unlikely(h->run_flags & EXIT_R_F)) {
01661 h->last_retcode=ret;
01662 _last_returned_code = h->last_retcode;
01663 #ifdef USE_LONGJMP
01664 longjmp(h->jmp_env, ret);
01665 #endif
01666 }
01667 break;
01668 }
01669
01670 }
01671
01672 h->rec_lev--;
01673 end:
01674
01675 if (unlikely(h->rec_lev==0 && ret==0 &&
01676 !(h->run_flags & IGNORE_ON_BREAK_R_F)))
01677 for (mod=modules;mod;mod=mod->next)
01678 if (unlikely(mod->exports.onbreak_f)) {
01679 mod->exports.onbreak_f( msg );
01680 }
01681 return ret;
01682
01683
01684 error:
01685 h->rec_lev--;
01686 return ret;
01687 }
01688
01689
01690
01691 #ifdef USE_LONGJMP
01692
01696 int run_actions_safe(struct run_act_ctx* h, struct action* a,
01697 struct sip_msg* msg)
01698 {
01699 struct run_act_ctx ctx;
01700 int ret;
01701 int ign_on_break;
01702
01703
01704 init_run_actions_ctx(&ctx);
01705 ctx.last_retcode = h->last_retcode;
01706 ign_on_break = h->run_flags & IGNORE_ON_BREAK_R_F;
01707 ctx.run_flags = h->run_flags | IGNORE_ON_BREAK_R_F;
01708 ret = run_actions(&ctx, a, msg);
01709 h->last_retcode = ctx.last_retcode;
01710 h->run_flags = (ctx.run_flags & ~IGNORE_ON_BREAK_R_F) | ign_on_break;
01711 return ret;
01712 }
01713 #endif
01714
01715
01716
01717 int run_top_route(struct action* a, sip_msg_t* msg, struct run_act_ctx *c)
01718 {
01719 struct run_act_ctx ctx;
01720 struct run_act_ctx *p;
01721 int ret;
01722 flag_t sfbk;
01723
01724 p = (c)?c:&ctx;
01725 sfbk = getsflags();
01726 setsflagsval(0);
01727 reset_static_buffer();
01728 init_run_actions_ctx(p);
01729 ret = run_actions(p, a, msg);
01730 setsflagsval(sfbk);
01731 return ret;
01732 }