mirror of https://github.com/sipwise/kamailio.git
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
189 lines
5.4 KiB
189 lines
5.4 KiB
From 642f096ed2ba9ea5b53696197f863a7e586b88c6 Mon Sep 17 00:00:00 2001
|
|
From: Daniel-Constantin Mierla <miconda@gmail.com>
|
|
Date: Wed, 26 Apr 2017 15:23:24 +0200
|
|
Subject: [PATCH] dialog: more safety checks to detect if dialog is gone after
|
|
event route execution
|
|
|
|
- avoid execution of script callbacks for event route
|
|
- related to GH #1059 and #1069
|
|
- backport of a8b7f94a5c305e14313d5528792f9ca6518d5969
|
|
|
|
(cherry picked from commit d95f09670a0d3d0c997c7f1c94eb66bdd4c4da0f)
|
|
---
|
|
modules/dialog/dlg_handlers.c | 43 +++++++++++++++++++++++++++++++++++--------
|
|
modules/dialog/dlg_hash.h | 2 +-
|
|
modules/dialog/dlg_profile.c | 4 ++++
|
|
modules/dialog/dlg_var.c | 12 ++++++++++++
|
|
4 files changed, 52 insertions(+), 9 deletions(-)
|
|
|
|
--- a/modules/dialog/dlg_handlers.c
|
|
+++ b/modules/dialog/dlg_handlers.c
|
|
@@ -455,7 +455,11 @@ static void dlg_onreply(struct cell* t,
|
|
event = DLG_EVENT_RPL3xx;
|
|
|
|
next_state_dlg( dlg, event, &old_state, &new_state, &unref);
|
|
- dlg_run_event_route(dlg, (rpl==FAKED_REPLY)?NULL:rpl, old_state, new_state);
|
|
+ if(dlg_run_event_route(dlg, (rpl==FAKED_REPLY)?NULL:rpl, old_state,
|
|
+ new_state)<0) {
|
|
+ /* dialog is gone */
|
|
+ return;
|
|
+ }
|
|
|
|
if (new_state==DLG_STATE_EARLY) {
|
|
run_dlg_callbacks(DLGCB_EARLY, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
|
|
@@ -1315,7 +1319,10 @@ void dlg_onroute(struct sip_msg* req, st
|
|
CURR_DLG_LIFETIME = (unsigned int)(time(0))-dlg->start_ts;
|
|
CURR_DLG_STATUS = new_state;
|
|
|
|
- dlg_run_event_route(dlg, req, old_state, new_state);
|
|
+ if(dlg_run_event_route(dlg, req, old_state, new_state)<0) {
|
|
+ /* dialog is gone */
|
|
+ return;
|
|
+ }
|
|
|
|
dlg0 = dlg_lookup(h_entry, h_id);
|
|
if (dlg0==0) {
|
|
@@ -1519,7 +1526,10 @@ void dlg_ontimeout(struct dlg_tl *tl)
|
|
timeout_cb = (void *)CONFIRMED_DIALOG_STATE;
|
|
}
|
|
|
|
- dlg_run_event_route(dlg, NULL, old_state, new_state);
|
|
+ if(dlg_run_event_route(dlg, NULL, old_state, new_state)<0) {
|
|
+ /* dialog is gone */
|
|
+ return;
|
|
+ }
|
|
|
|
if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {
|
|
LM_WARN("timeout for dlg with CallID '%.*s' and tags '%.*s' '%.*s'\n",
|
|
@@ -1607,17 +1617,22 @@ int pv_get_dlg_status(struct sip_msg *ms
|
|
/*!
|
|
* \brief Execute event routes based on new state
|
|
*
|
|
+ * - returns: -1 if dialog doesn't exist after event route execution
|
|
+ * 0 if all ok
|
|
*/
|
|
-void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate)
|
|
+int dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate)
|
|
{
|
|
sip_msg_t *fmsg;
|
|
int rt;
|
|
int bkroute;
|
|
+ int h_entry=0;
|
|
+ int h_id=0;
|
|
+ dlg_cell_t *dlg0 = NULL;
|
|
|
|
if(dlg==NULL)
|
|
- return;
|
|
+ return -1;
|
|
if(ostate==nstate)
|
|
- return;
|
|
+ return 0;
|
|
|
|
rt = -1;
|
|
if(nstate==DLG_STATE_CONFIRMED_NA) {
|
|
@@ -1630,7 +1645,7 @@ void dlg_run_event_route(dlg_cell_t *dlg
|
|
}
|
|
|
|
if(rt==-1 || event_rt.rlist[rt]==NULL)
|
|
- return;
|
|
+ return 0;
|
|
|
|
if(msg==NULL)
|
|
fmsg = faked_msg_next();
|
|
@@ -1640,6 +1655,8 @@ void dlg_run_event_route(dlg_cell_t *dlg
|
|
if (exec_pre_script_cb(fmsg, LOCAL_CB_TYPE)>0)
|
|
{
|
|
dlg_ref(dlg, 1);
|
|
+ h_entry = dlg->h_entry;
|
|
+ h_id = dlg->h_id;
|
|
dlg_set_ctx_iuid(dlg);
|
|
LM_DBG("executing event_route %d on state %d\n", rt, nstate);
|
|
bkroute = get_route_type();
|
|
@@ -1647,9 +1664,19 @@ void dlg_run_event_route(dlg_cell_t *dlg
|
|
run_top_route(event_rt.rlist[rt], fmsg, 0);
|
|
dlg_reset_ctx_iuid();
|
|
exec_post_script_cb(fmsg, LOCAL_CB_TYPE);
|
|
- dlg_unref(dlg, 1);
|
|
set_route_type(bkroute);
|
|
+ /* re-lookup the dialog, execution of the route could take long time */
|
|
+ dlg0 = dlg_lookup(h_entry, h_id);
|
|
+ if (dlg0==0) {
|
|
+ LM_ALERT("after event route - dialog not found [%u:%u] (%d/%d) (%p)\n",
|
|
+ h_entry, h_id, ostate, nstate, dlg);
|
|
+ return -1;
|
|
+ } else {
|
|
+ dlg_release(dlg0);
|
|
+ dlg_unref(dlg, 1);
|
|
+ }
|
|
}
|
|
+ return 0;
|
|
}
|
|
|
|
int dlg_manage(sip_msg_t *msg)
|
|
--- a/modules/dialog/dlg_hash.h
|
|
+++ b/modules/dialog/dlg_hash.h
|
|
@@ -582,7 +582,7 @@ static inline int match_downstream_dialo
|
|
/*!
|
|
*
|
|
*/
|
|
-void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate);
|
|
+int dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate);
|
|
|
|
|
|
int dlg_ka_add(dlg_cell_t *dlg);
|
|
--- a/modules/dialog/dlg_profile.c
|
|
+++ b/modules/dialog/dlg_profile.c
|
|
@@ -437,6 +437,10 @@ int profile_cleanup( struct sip_msg *msg
|
|
{
|
|
dlg_cell_t *dlg;
|
|
|
|
+ if(get_route_type()==LOCAL_ROUTE) {
|
|
+ return 1;
|
|
+ }
|
|
+
|
|
current_dlg_msg_id = 0;
|
|
current_dlg_msg_pid = 0;
|
|
dlg = dlg_get_ctx_dialog();
|
|
--- a/modules/dialog/dlg_var.c
|
|
+++ b/modules/dialog/dlg_var.c
|
|
@@ -47,6 +47,9 @@ int msg_id;
|
|
int dlg_cfg_cb(sip_msg_t *msg, unsigned int flags, void *cbp)
|
|
{
|
|
dlg_cell_t *dlg;
|
|
+ if(get_route_type()==LOCAL_ROUTE) {
|
|
+ return 1;
|
|
+ }
|
|
if(flags&POST_SCRIPT_CB) {
|
|
dlg = dlg_get_ctx_dialog();
|
|
if(dlg!=NULL) {
|
|
@@ -76,6 +79,9 @@ int dlg_cfg_cb(sip_msg_t *msg, unsigned
|
|
|
|
int cb_dlg_cfg_reset(sip_msg_t *msg, unsigned int flags, void *cbp)
|
|
{
|
|
+ if(get_route_type()==LOCAL_ROUTE) {
|
|
+ return 1;
|
|
+ }
|
|
memset(&_dlg_ctx, 0, sizeof(dlg_ctx_t));
|
|
|
|
return 1;
|
|
@@ -83,6 +89,9 @@ int cb_dlg_cfg_reset(sip_msg_t *msg, uns
|
|
|
|
int cb_dlg_locals_reset(sip_msg_t *msg, unsigned int flags, void *cbp)
|
|
{
|
|
+ if(get_route_type()==LOCAL_ROUTE) {
|
|
+ return 1;
|
|
+ }
|
|
LM_DBG("resetting the local dialog shortcuts on script callback: %u\n", flags);
|
|
cb_dlg_cfg_reset(msg, flags, cbp);
|
|
cb_profile_reset(msg, flags, cbp);
|
|
@@ -918,6 +927,9 @@ dlg_ctx_t* dlg_get_dlg_ctx(void)
|
|
|
|
int spiral_detect_reset(struct sip_msg *foo, unsigned int flags, void *bar)
|
|
{
|
|
+ if(get_route_type()==LOCAL_ROUTE) {
|
|
+ return 1;
|
|
+ }
|
|
spiral_detected = -1;
|
|
|
|
return 0;
|