Module: sip-router
Branch: master
Commit: 53ec53db6b2e164dbdd6d6162c547d064a4cbe34
URL:
http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=53ec53d…
Author: Daniel-Constantin Mierla <miconda(a)gmail.com>
Committer: Daniel-Constantin Mierla <miconda(a)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