Module: sip-router Branch: master Commit: 3537c2d8c27617023cb9f9a569435483748fef1f URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=3537c2d8...
Author: Timo Reimann timo.reimann@1und1.de Committer: Timo Reimann timo.reimann@1und1.de Date: Mon Jun 28 10:50:05 2010 +0200
modules_k/dialog: Delay dialog deletion to absorb late in-dialog requests
- When a dialog's state transitions to DLG_STATE_DELETED, register a tm callback for TMCB_DESTROY to absorb late in-dialog requests (no more "unable to find dialog for <REQUEST TYPE>" log messages). - On callback, unreference and, in consequence, destroy the dialog.
---
modules_k/dialog/dlg_handlers.c | 25 +++++++++++++++++++++++++ 1 files changed, 25 insertions(+), 0 deletions(-)
diff --git a/modules_k/dialog/dlg_handlers.c b/modules_k/dialog/dlg_handlers.c index ad892b6..19b53e9 100644 --- a/modules_k/dialog/dlg_handlers.c +++ b/modules_k/dialog/dlg_handlers.c @@ -764,6 +764,20 @@ static void unreference_dialog(void *dialog)
/*! + * \brief Unreference a dialog from tm callback (another wrapper) + * \param t transaction, unused + * \param type type of the entered callback + * \param param saved dialog structure in the callback + */ +static void unref_dlg_from_cb(struct cell* t, int type, struct tmcb_params *param) +{ + struct dlg_cell *dlg = (struct dlg_cell *)(*param->param); + + unref_dlg(dlg, 1); +} + + +/*! * \brief Function that is registered as RR callback for dialog tracking * * Function that is registered as RR callback for dialog tracking. It @@ -886,6 +900,17 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param) set_current_dialog( req, dlg); _dlg_ctx.dlg = dlg;
+ /* delay deletion of dialog until transaction has died off in order + * to absorb in-air messages */ + if (new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) { + if ( d_tmb.register_tmcb(req, NULL, TMCB_DESTROY, + unref_dlg_from_cb, (void*)dlg, NULL)<0 ) { + LM_ERR("failed to register deletion delay function\n"); + } else { + ref_dlg(dlg, 1); + } + } + /* run actions for the transition */ if (event==DLG_EVENT_REQBYE && new_state==DLG_STATE_DELETED && old_state!=DLG_STATE_DELETED) {