diff --git a/src/modules/dialog/dlg_handlers.c b/src/modules/dialog/dlg_handlers.c index 0640c6ee674..dbef1c2b91f 100644 --- a/src/modules/dialog/dlg_handlers.c +++ b/src/modules/dialog/dlg_handlers.c @@ -452,7 +452,11 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param) 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); @@ -1359,7 +1363,10 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param) 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; + } /* delay deletion of dialog until transaction has died off in order * to absorb in-air messages */ @@ -1558,7 +1565,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", @@ -1650,17 +1660,22 @@ int pv_get_dlg_status(struct sip_msg *msg, pv_param_t *param, pv_value_t *res) /*! * \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) { @@ -1673,7 +1688,7 @@ void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate } if(rt==-1 || event_rt.rlist[rt]==NULL) - return; + return 0; if(msg==NULL) fmsg = faked_msg_next(); @@ -1683,6 +1698,8 @@ void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate 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(); @@ -1690,9 +1707,19 @@ void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate 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) diff --git a/src/modules/dialog/dlg_hash.h b/src/modules/dialog/dlg_hash.h index 63e64d53e8c..f66d8f48f19 100644 --- a/src/modules/dialog/dlg_hash.h +++ b/src/modules/dialog/dlg_hash.h @@ -561,7 +561,7 @@ static inline int match_downstream_dialog(dlg_cell_t *dlg, str *callid, str *fta /*! * */ -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); diff --git a/src/modules/dialog/dlg_profile.c b/src/modules/dialog/dlg_profile.c index fa3d2e857c7..ebc04b25c99 100644 --- a/src/modules/dialog/dlg_profile.c +++ b/src/modules/dialog/dlg_profile.c @@ -437,6 +437,10 @@ int profile_cleanup( struct sip_msg *msg, unsigned int flags, void *param ) { 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(); diff --git a/src/modules/dialog/dlg_var.c b/src/modules/dialog/dlg_var.c index 33f48c57622..10c0f05e238 100644 --- a/src/modules/dialog/dlg_var.c +++ b/src/modules/dialog/dlg_var.c @@ -48,6 +48,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) { @@ -77,6 +80,9 @@ int dlg_cfg_cb(sip_msg_t *msg, unsigned int flags, void *cbp) 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; @@ -84,6 +90,9 @@ int cb_dlg_cfg_reset(sip_msg_t *msg, unsigned int flags, void *cbp) 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); @@ -919,6 +928,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;