[sr-dev] git:master: dialog: timeout route executed only for confirmed dialogs
Daniel-Constantin Mierla
miconda at gmail.com
Fri Feb 17 09:37:45 CET 2012
Module: sip-router
Branch: master
Commit: 29036bcc8fe90ab3281be95b4b69beff61f0cf0d
URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=29036bcc8fe90ab3281be95b4b69beff61f0cf0d
Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date: Thu Feb 16 12:18:44 2012 +0100
dialog: timeout route executed only for confirmed dialogs
- avoid some extra conditions when it is not the case
- use dlg internal id to lookup dialog in callbacks for replies of generated BYEs
---
modules_k/dialog/dlg_handlers.c | 50 +++++++++++++++++++-----------------
modules_k/dialog/dlg_handlers.h | 10 +++++++
modules_k/dialog/dlg_hash.c | 3 +-
modules_k/dialog/dlg_hash.h | 5 +++
modules_k/dialog/dlg_req_within.c | 26 +++++++++++++------
5 files changed, 61 insertions(+), 33 deletions(-)
diff --git a/modules_k/dialog/dlg_handlers.c b/modules_k/dialog/dlg_handlers.c
index fe6c104..a2208bb 100644
--- a/modules_k/dialog/dlg_handlers.c
+++ b/modules_k/dialog/dlg_handlers.c
@@ -107,8 +107,6 @@ static unsigned int CURR_DLG_ID = 0xffffffff; /*!< current dialog id */
/*! separator inside the record-route paramter */
#define DLG_SEPARATOR '.'
-void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate);
-
int dlg_set_tm_callbacks(tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg,
int mode);
@@ -314,7 +312,7 @@ dlg_iuid_t *dlg_get_iuid_shm_clone(dlg_cell_t *dlg)
/*!
* \brief Free dialog internal unique id stored in shared memory
*/
-static void dlg_iuid_sfree(void *iuid)
+void dlg_iuid_sfree(void *iuid)
{
if(iuid)
shm_free(iuid);
@@ -1251,31 +1249,35 @@ void dlg_ontimeout(struct dlg_tl *tl)
dlg = ((struct dlg_cell*)((char *)(tl) -
(unsigned long)(&((struct dlg_cell*)0)->tl)));
- if(dlg->toroute>0 && dlg->toroute<main_rt.entries
- && main_rt.rlist[dlg->toroute]!=NULL)
+ if(dlg->state==DLG_STATE_CONFIRMED_NA
+ || dlg->state==DLG_STATE_CONFIRMED)
{
- fmsg = faked_msg_next();
- if (exec_pre_script_cb(fmsg, REQUEST_CB_TYPE)>0)
+ if(dlg->toroute>0 && dlg->toroute<main_rt.entries
+ && main_rt.rlist[dlg->toroute]!=NULL)
{
- dlg_ref(dlg, 1);
- dlg_set_ctx_iuid(dlg);
- LM_DBG("executing route %d on timeout\n", dlg->toroute);
- set_route_type(REQUEST_ROUTE);
- run_top_route(main_rt.rlist[dlg->toroute], fmsg, 0);
- dlg_reset_ctx_iuid();
- exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
- dlg_unref(dlg, 1);
+ fmsg = faked_msg_next();
+ if (exec_pre_script_cb(fmsg, REQUEST_CB_TYPE)>0)
+ {
+ dlg_ref(dlg, 1);
+ dlg_set_ctx_iuid(dlg);
+ LM_DBG("executing route %d on timeout\n", dlg->toroute);
+ set_route_type(REQUEST_ROUTE);
+ run_top_route(main_rt.rlist[dlg->toroute], fmsg, 0);
+ dlg_reset_ctx_iuid();
+ exec_post_script_cb(fmsg, REQUEST_CB_TYPE);
+ dlg_unref(dlg, 1);
+ }
}
- }
- if ((dlg->dflags&DLG_FLAG_TOBYE)
- && (dlg->state==DLG_STATE_CONFIRMED_NA
- || dlg->state==DLG_STATE_CONFIRMED))
- {
- dlg_bye_all(dlg, NULL);
- dlg_unref(dlg, 1);
- if_update_stat(dlg_enable_stats, expired_dlgs, 1);
- return;
+ if(dlg->dflags&DLG_FLAG_TOBYE)
+ {
+ dlg_bye_all(dlg, NULL);
+ /* run event route for end of dlg */
+ dlg_run_event_route(dlg, NULL, dlg->state, DLG_STATE_DELETED);
+ dlg_unref(dlg, 1);
+ if_update_stat(dlg_enable_stats, expired_dlgs, 1);
+ return;
+ }
}
next_state_dlg( dlg, DLG_EVENT_REQBYE, &old_state, &new_state, &unref);
diff --git a/modules_k/dialog/dlg_handlers.h b/modules_k/dialog/dlg_handlers.h
index 0f45ce9..1149241 100644
--- a/modules_k/dialog/dlg_handlers.h
+++ b/modules_k/dialog/dlg_handlers.h
@@ -167,4 +167,14 @@ void dlg_tmcb_dummy(tm_cell_t *t, int type, struct tmcb_params *param);
*/
dlg_cell_t *dlg_get_msg_dialog(sip_msg_t *msg);
+/*!
+ * \brief Clone dialog internal unique id to shared memory
+ */
+dlg_iuid_t *dlg_get_iuid_shm_clone(dlg_cell_t *dlg);
+
+/*!
+ * \brief Free dialog internal unique id stored in shared memory
+ */
+void dlg_iuid_sfree(void *iuid);
+
#endif
diff --git a/modules_k/dialog/dlg_hash.c b/modules_k/dialog/dlg_hash.c
index e9ea0a0..23930e7 100644
--- a/modules_k/dialog/dlg_hash.c
+++ b/modules_k/dialog/dlg_hash.c
@@ -162,7 +162,7 @@ int init_dlg_table(unsigned int size)
for( i=0 ; i<size; i++ ) {
memset( &(d_table->entries[i]), 0, sizeof(struct dlg_entry) );
- d_table->entries[i].next_id = rand();
+ d_table->entries[i].next_id = rand() % (3*size);
d_table->entries[i].lock_idx = i % d_table->locks_no;
}
@@ -572,6 +572,7 @@ void link_dlg(struct dlg_cell *dlg, int n)
/* keep id 0 for special cases */
dlg->h_id = 1 + d_entry->next_id++;
+ LM_DBG("linking dialog [%u:%u]\n", dlg->h_entry, dlg->h_id);
if (d_entry->first==0) {
d_entry->first = d_entry->last = dlg;
} else {
diff --git a/modules_k/dialog/dlg_hash.h b/modules_k/dialog/dlg_hash.h
index dae6e02..f262c72 100644
--- a/modules_k/dialog/dlg_hash.h
+++ b/modules_k/dialog/dlg_hash.h
@@ -503,6 +503,11 @@ static inline int match_downstream_dialog(dlg_cell_t *dlg, str *callid, str *fta
return 1;
}
+/*!
+ *
+ */
+void dlg_run_event_route(dlg_cell_t *dlg, sip_msg_t *msg, int ostate, int nstate);
+
/*!
* \brief Output a dialog via the MI interface
diff --git a/modules_k/dialog/dlg_req_within.c b/modules_k/dialog/dlg_req_within.c
index f5e3c90..20f254f 100644
--- a/modules_k/dialog/dlg_req_within.c
+++ b/modules_k/dialog/dlg_req_within.c
@@ -40,6 +40,7 @@
#include "../../lib/kcore/kstats_wrapper.h"
#include "dlg_timer.h"
#include "dlg_hash.h"
+#include "dlg_handlers.h"
#include "dlg_req_within.h"
#include "dlg_db_handler.h"
@@ -131,6 +132,7 @@ void bye_reply_cb(struct cell* t, int type, struct tmcb_params* ps){
struct dlg_cell* dlg;
int event, old_state, new_state, unref, ret;
+ dlg_iuid_t *iuid = NULL;
if(ps->param == NULL || *ps->param == NULL){
LM_ERR("invalid parameter\n");
@@ -144,11 +146,14 @@ void bye_reply_cb(struct cell* t, int type, struct tmcb_params* ps){
LM_DBG("receiving a final reply %d\n",ps->code);
- dlg = (struct dlg_cell *)(*(ps->param));
+ iuid = (dlg_iuid_t*)(*ps->param);
+ dlg = dlg_get_by_iuid(iuid);
+ if(dlg==0)
+ return;
+
event = DLG_EVENT_REQBYE;
next_state_dlg(dlg, event, &old_state, &new_state, &unref);
-
if(new_state == DLG_STATE_DELETED && old_state != DLG_STATE_DELETED){
LM_DBG("removing dialog with h_entry %u and h_id %u\n",
@@ -192,7 +197,7 @@ void bye_reply_cb(struct cell* t, int type, struct tmcb_params* ps){
/* force delete from mem */
dlg_unref(dlg, 1);
}
-
+ dlg_iuid_sfree(iuid);
}
@@ -240,6 +245,8 @@ static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs)
dlg_t* dialog_info;
str met = {"BYE", 3};
int result;
+ dlg_iuid_t *iuid = NULL;
+
/* do not send BYE request for non-confirmed dialogs (not supported) */
if (cell->state != DLG_STATE_CONFIRMED_NA && cell->state != DLG_STATE_CONFIRMED) {
LM_ERR("terminating non-confirmed dialogs not supported\n");
@@ -255,16 +262,21 @@ static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs)
LM_DBG("sending BYE to %s\n", (dir==DLG_CALLER_LEG)?"caller":"callee");
- dlg_ref(cell, 1);
+ iuid = dlg_get_iuid_shm_clone(cell);
+ if(iuid==NULL)
+ {
+ LM_ERR("failed to create dialog unique id clone\n");
+ goto err;
+ }
memset(&uac_r,'\0', sizeof(uac_req_t));
set_uac_req(&uac_r, &met, hdrs, NULL, dialog_info, TMCB_LOCAL_COMPLETED,
- bye_reply_cb, (void*)cell);
+ bye_reply_cb, (void*)iuid);
result = d_tmb.t_request_within(&uac_r);
if(result < 0){
LM_ERR("failed to send the BYE request\n");
- goto err1;
+ goto err;
}
free_tm_dlg(dialog_info);
@@ -272,8 +284,6 @@ static inline int send_bye(struct dlg_cell * cell, int dir, str *hdrs)
LM_DBG("BYE sent to %s\n", (dir==0)?"caller":"callee");
return 0;
-err1:
- dlg_unref(cell, 1);
err:
if(dialog_info)
free_tm_dlg(dialog_info);
More information about the sr-dev
mailing list