TT#14953 dialog: more safety checks

Change-Id: I22e8c4ad135777147438e79128d816a30fdcf844
changes/53/12853/5
Victor Seva 9 years ago
parent 1e2115a9d1
commit e55372f63e

@ -19,6 +19,7 @@ upstream/0037-tls-do-kerberos-and-zlib-init-checks-only-for-libssl.patch
upstream/pv-new-function-pv_evalx-dst-fmt.patch
upstream/pv_trans_cfg_line.patch
upstream/dialog-check-if-dialog-exists-after-event-route-exec.patch
upstream/dialog-more-safety-checks-to-detect-if-dialog-is-gon.patch
#
##
no_lib64_on_64_bits.patch

@ -0,0 +1,188 @@
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;
Loading…
Cancel
Save