[sr-dev] git:master: dialog(k): option to wait for negative ack

Daniel-Constantin Mierla miconda at gmail.com
Fri Feb 17 09:37:45 CET 2012


Module: sip-router
Branch: master
Commit: 53ec53db6b2e164dbdd6d6162c547d064a4cbe34
URL:    http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=53ec53db6b2e164dbdd6d6162c547d064a4cbe34

Author: Daniel-Constantin Mierla <miconda at gmail.com>
Committer: Daniel-Constantin Mierla <miconda at gmail.com>
Date:   Thu Feb 16 15:46:19 2012 +0100

dialog(k): option to wait for negative ack

- new parameter wait_ack, default 1 (wait for negative ack)
- if set to 0, dlg structure is deleted when the negative reply is sent
  out
- restore functionality existing in previous versions, lost with the
  latest refactoring, reported by Timo Reimann
- negative ACK can trigger a dialog callback, also the dialog profiles
  can stay until this ACK is processed
- configurable as there is no always useful usage, adds some extra
  processing, so it is good to be able to disactivate it

---

 modules_k/dialog/dialog.c       |    2 +
 modules_k/dialog/dlg_handlers.c |   71 ++++++++++++++++++++++++++++++++++++--
 2 files changed, 69 insertions(+), 4 deletions(-)

diff --git a/modules_k/dialog/dialog.c b/modules_k/dialog/dialog.c
index 8c3559d..362fa8c 100644
--- a/modules_k/dialog/dialog.c
+++ b/modules_k/dialog/dialog.c
@@ -105,6 +105,7 @@ static char* profiles_nv_s = NULL;
 str dlg_extra_hdrs = {NULL,0};
 static int db_fetch_rows = 200;
 int initial_cbs_inscript = 1;
+int dlg_wait_ack = 1;
 
 int dlg_event_rt[DLG_EVENTRT_MAX];
 
@@ -247,6 +248,7 @@ static param_export_t mod_params[]={
 	{ "ruri_pvar",             STR_PARAM, &ruri_pvar_param.s        },
 	{ "initial_cbs_inscript",  INT_PARAM, &initial_cbs_inscript     },
 	{ "send_bye",              INT_PARAM, &dlg_send_bye             },
+	{ "wait_ack",              INT_PARAM, &dlg_wait_ack             },
 	{ 0,0,0 }
 };
 
diff --git a/modules_k/dialog/dlg_handlers.c b/modules_k/dialog/dlg_handlers.c
index 6bc3670..06f5584 100644
--- a/modules_k/dialog/dlg_handlers.c
+++ b/modules_k/dialog/dlg_handlers.c
@@ -85,6 +85,7 @@ extern int       detect_spirals;
 extern int       initial_cbs_inscript;
 extern int       dlg_send_bye;
 extern int       dlg_event_rt[DLG_EVENTRT_MAX];
+extern int       dlg_wait_ack;
 int              spiral_detected = -1;
 
 extern struct rr_binds d_rrb;		/*!< binding to record-routing module */
@@ -109,6 +110,7 @@ static unsigned int CURR_DLG_ID  = 0xffffffff;	/*!< current dialog id */
 
 int dlg_set_tm_callbacks(tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg,
 		int mode);
+int dlg_set_tm_waitack(tm_cell_t *t, dlg_cell_t *dlg);
 
 /*!
  * \brief Initialize the dialog handlers
@@ -314,8 +316,12 @@ dlg_iuid_t *dlg_get_iuid_shm_clone(dlg_cell_t *dlg)
  */
 void dlg_iuid_sfree(void *iuid)
 {
-    if(iuid)
+    if(iuid) {
+		LM_DBG("freeing dlg iuid [%u:%u] (%p)\n",
+				((dlg_iuid_t*)iuid)->h_entry,
+				((dlg_iuid_t*)iuid)->h_id, iuid);
 		shm_free(iuid);
+	}
 }
 
 
@@ -398,6 +404,25 @@ static void dlg_terminated(sip_msg_t *req, dlg_cell_t *dlg, unsigned int dir)
 }
 
 /*!
+ * \brief Function that is registered as TM callback and called on T destroy
+ *
+ * - happens when wait_ack==1
+ *
+ */
+static void dlg_ontdestroy(struct cell* t, int type, struct tmcb_params *param)
+{
+	dlg_cell_t *dlg = NULL;
+	dlg_iuid_t *iuid = NULL;
+
+	iuid = (dlg_iuid_t*)(*param->param);
+	dlg = dlg_get_by_iuid(iuid);
+	if(dlg==0)
+		return;
+	/* 1 for callback and 1 for dlg lookup */
+	dlg_unref(dlg, 2);
+}
+
+/*!
  * \brief Function that is registered as TM callback and called on replies
  *
  * Function that is registered as TM callback and called on replies. It
@@ -512,7 +537,9 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
 		goto done;
 	}
 
-	if ( old_state!=DLG_STATE_DELETED && new_state==DLG_STATE_DELETED ) {
+	if ( new_state==DLG_STATE_DELETED
+				&& (old_state==DLG_STATE_UNCONFIRMED
+					|| old_state==DLG_STATE_EARLY) ) {
 		LM_DBG("dialog %p failed (negative reply)\n", dlg);
 		/* dialog setup not completed (3456XX) */
 		run_dlg_callbacks( DLGCB_FAILED, dlg, req, rpl, DLG_DIR_UPSTREAM, 0);
@@ -524,6 +551,8 @@ static void dlg_onreply(struct cell* t, int type, struct tmcb_params *param)
 
 		if_update_stat(dlg_enable_stats, failed_dlgs, 1);
 
+		if(dlg_wait_ack==1)
+			dlg_set_tm_waitack(t, dlg);
 		goto done;
 	}
 
@@ -865,13 +894,13 @@ error:
 int dlg_set_tm_callbacks(tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg,
 		int smode)
 {
-	dlg_iuid_t *iuid;
+	dlg_iuid_t *iuid = NULL;
 	if(t==NULL)
 		return -1;
 
 	if(smode==0) {
 		iuid = dlg_get_iuid_shm_clone(dlg);
-		if(iuid==NULL) 
+		if(iuid==NULL)
 		{
 			LM_ERR("failed to create dialog unique id clone\n");
 			goto error;
@@ -888,9 +917,43 @@ int dlg_set_tm_callbacks(tm_cell_t *t, sip_msg_t *req, dlg_cell_t *dlg,
 
 	return 0;
 error:
+	dlg_iuid_sfree(iuid);
 	return -1;
 }
 
+/*!
+ * \brief add dlg structure to tm callbacks to wait for negative ACK
+ * \param t current transaction
+ * \param dlg current dialog
+ * \return 0 on success, -1 on failure
+ */
+int dlg_set_tm_waitack(tm_cell_t *t, dlg_cell_t *dlg)
+{
+	dlg_iuid_t *iuid = NULL;
+	if(t==NULL)
+		return -1;
+
+	LM_ERR("registering TMCB to wait for negative ACK\n");
+	iuid = dlg_get_iuid_shm_clone(dlg);
+	if(iuid==NULL)
+	{
+		LM_ERR("failed to create dialog unique id clone\n");
+		goto error;
+	}
+	dlg_ref(dlg, 1);
+	if ( d_tmb.register_tmcb( NULL, t,
+			TMCB_DESTROY,
+			dlg_ontdestroy, (void*)iuid, dlg_iuid_sfree)<0 ) {
+		LM_ERR("failed to register TMCB to wait for negative ACK\n");
+		dlg_unref(dlg, 1);
+		goto error;
+	}
+
+	return 0;
+error:
+	dlg_iuid_sfree(iuid);
+	return -1;
+}
 
 /*!
  * \brief Parse the record-route parameter, to get dialog information back




More information about the sr-dev mailing list