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