diff --git a/src/core/error.h b/src/core/error.h index 829073e5557..8ac763bf2dc 100644 --- a/src/core/error.h +++ b/src/core/error.h @@ -48,6 +48,7 @@ #define E_Q_EMPTY -16 /* Empty q */ #define E_Q_TOO_BIG -17 /* q too big (> 1) */ #define E_Q_DEC_MISSING -18 /* Decimal part missing */ +#define E_DROP -19 /* Dropped in script */ diff --git a/src/modules/tm/uac.c b/src/modules/tm/uac.c index 1478853d3d5..1112d7758c1 100644 --- a/src/modules/tm/uac.c +++ b/src/modules/tm/uac.c @@ -239,6 +239,8 @@ static inline int t_run_local_req( msg_ctx_id_t backup_ctxid; int refresh_shortcuts = 0; sr_kemi_eng_t *keng = NULL; + run_act_ctx_t ra_ctx; + run_act_ctx_t *bctx; str evname = str_init("tm:local-request"); LM_DBG("executing event_route[tm:local-request]\n"); @@ -271,18 +273,24 @@ static inline int t_run_local_req( tm_global_ctx_id.msgid=lreq.id; tm_global_ctx_id.pid=lreq.pid; set_t(new_cell, T_BR_UNDEFINED); + + init_run_actions_ctx(&ra_ctx); + if(goto_on_local_req>=0) { - run_top_route(event_rt.rlist[goto_on_local_req], &lreq, 0); + run_top_route(event_rt.rlist[goto_on_local_req], &lreq, &ra_ctx); } else { keng = sr_kemi_eng_get(); if(keng==NULL) { LM_WARN("event callback (%s) set, but no cfg engine\n", tm_event_callback.s); } else { + bctx = sr_kemi_act_ctx_get(); + sr_kemi_act_ctx_set(&ra_ctx); if(sr_kemi_route(keng, &lreq, EVENT_ROUTE, &tm_event_callback, &evname)<0) { LM_ERR("error running event route kemi callback\n"); } + sr_kemi_act_ctx_set(bctx); } } /* restore original environment */ @@ -296,6 +304,12 @@ static inline int t_run_local_req( tm_xdata_swap(new_cell, &backup_xd, 1); setsflagsval(sflag_bk); + if (unlikely(ra_ctx.run_flags&DROP_R_F)) { + LM_DBG("tm:local-request dropped msg. to %.*s\n", + lreq.dst_uri.len, lreq.dst_uri.s); + refresh_shortcuts = E_DROP; + goto clean; + } /* rebuild the new message content */ if(lreq.force_send_socket != uac_r->dialog->send_sock) { LM_DBG("Send socket updated to: %.*s", @@ -350,6 +364,7 @@ static inline int t_run_local_req( } } +clean: /* clean local msg structure */ if (unlikely(lreq.new_uri.s)) { @@ -514,6 +529,10 @@ static inline int t_uac_prepare(uac_req_t *uac_r, #ifdef WITH_EVENT_LOCAL_REQUEST if (unlikely(goto_on_local_req>=0 || tm_event_callback.len>0)) { refresh_shortcuts = t_run_local_req(&buf, &buf_len, uac_r, new_cell, request); + if (unlikely(refresh_shortcuts==E_DROP)) { + ret=E_DROP; + goto error1; + } } #endif @@ -605,6 +624,7 @@ static inline int t_uac_prepare(uac_req_t *uac_r, int prepare_req_within(uac_req_t *uac_r, struct retr_buf **dst_req) { + int ret = -1; if (!uac_r || !uac_r->method || !uac_r->dialog) { LM_ERR("Invalid parameter value\n"); goto err; @@ -619,13 +639,17 @@ int prepare_req_within(uac_req_t *uac_r, if ((uac_r->method->len == 6) && (!memcmp("CANCEL", uac_r->method->s, 6))) goto send; uac_r->dialog->loc_seq.value++; /* Increment CSeq */ send: - return t_uac_prepare(uac_r, dst_req, 0); + ret = t_uac_prepare(uac_r, dst_req, 0); + + if (unlikely(ret < 0 && ret == E_DROP)) { + ret = 0; + } err: /* if (cbp) shm_free(cbp); */ /* !! never free cbp here because if t_uac_prepare fails, cbp is not freed * and thus caller has no chance to discover if it is freed or not !! */ - return -1; + return ret; } static inline int send_prepared_request_impl(struct retr_buf *request, int retransmit, int branch) @@ -711,7 +735,14 @@ int t_uac_with_ids(uac_req_t *uac_r, branch_bm_t added_branches = 1; ret = t_uac_prepare(uac_r, &request, &cell); - if (ret < 0) return ret; + + if (ret < 0) { + if (unlikely(ret == E_DROP)) { + ret = 0; + } + return ret; + } + is_ack = (uac_r->method->len == 3) && (memcmp("ACK", uac_r->method->s, 3)==0) ? 1 : 0; /* equivalent loop to the one in t_forward_nonack */