Module: kamailio
Branch: master
Commit: 00f4147a410990d3ebeeef8825329bbdff728d1a
URL:
https://github.com/kamailio/kamailio/commit/00f4147a410990d3ebeeef8825329bb…
Author: Federico Cabiddu <federico.cabiddu(a)gmail.com>
Committer: Federico Cabiddu <federico.cabiddu(a)gmail.com>
Date: 2019-11-25T08:51:30+01:00
tm: add support for dropping messages in local-request event route
---
Modified: src/core/error.h
Modified: src/modules/tm/uac.c
---
Diff:
https://github.com/kamailio/kamailio/commit/00f4147a410990d3ebeeef8825329bb…
Patch:
https://github.com/kamailio/kamailio/commit/00f4147a410990d3ebeeef8825329bb…
---
diff --git a/src/core/error.h b/src/core/error.h
index 829073e555..8ac763bf2d 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 1478853d3d..9af3da951a 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");
@@ -272,17 +274,20 @@ static inline int t_run_local_req(
tm_global_ctx_id.pid=lreq.pid;
set_t(new_cell, T_BR_UNDEFINED);
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 +301,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 +361,7 @@ static inline int t_run_local_req(
}
}
+clean:
/* clean local msg structure */
if (unlikely(lreq.new_uri.s))
{
@@ -514,6 +526,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 +621,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 +636,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 +732,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 */