[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