Hi, we are using the dialog module to limit the duration of users' calls. We recently discovered (well, it's stated in the module doc) that each subsequent in-dialog request resets the dialog timeout. I can understand that this behavior can be useful in some cases, but in our is causing the call duration limitation to not work. I prepared a simple patch to introduce a new parameter to make this behavior configurable (per module). I would like to have it configurable per dialog, via means of an AVP, but this would have implications on the dialog save/restore mechanism and on the db schema, so for the moment I left it simple.
Regards, Federico Cabiddu
From d54bb7f473efe38dc60190974927ac5740cd58d2 Mon Sep 17 00:00:00 2001 From: Federico Cabiddu <[email protected]> Date: Mon, 6 Jan 2014 13:15:39 +0100 Subject: [PATCH] modules/dialog: added parameter to enable/disable dialog timeout reset --- modules/dialog/dialog.c | 49 ++++++++++++++++++++++++------------------- modules/dialog/dlg_handlers.c | 13 ++++++------ 2 files changed, 35 insertions(+), 27 deletions(-) diff --git a/modules/dialog/dialog.c b/modules/dialog/dialog.c index 8d7be33..78ac922 100644 --- a/modules/dialog/dialog.c +++ b/modules/dialog/dialog.c @@ -18,22 +18,22 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * History: * -------- * 2006-04-14 initial version (bogdan) * 2006-11-28 Added statistic support for the number of early and failed - * dialogs. (Jeffrey Magder - SOMA Networks) + * dialogs. (Jeffrey Magder - SOMA Networks) * 2007-04-30 added dialog matching without DID (dialog ID), but based only - * on RFC3261 elements - based on an original patch submitted + * on RFC3261 elements - based on an original patch submitted * by Michel Bensoussan <[email protected]> (bogdan) * 2007-05-15 added saving dialogs' information to database (ancuta) - * 2007-07-04 added saving dialog cseq, contact, record route + * 2007-07-04 added saving dialog cseq, contact, record route * and bind_addresses(sock_info) for caller and callee (ancuta) - * 2008-04-14 added new type of callback to be triggered when dialogs are + * 2008-04-14 added new type of callback to be triggered when dialogs are * loaded from DB (bogdan) * 2010-06-16 added sip-router rpc interface (osas) */ @@ -49,7 +49,7 @@ * from scripts. * The module, via an internal API, also provide the foundation to build * on top of it more complex dialog-based functionalities via other - * Kamailio modules. + * Kamailio modules. */ #include <stdio.h> @@ -123,6 +123,7 @@ int active_dlgs_cnt = 0; int early_dlgs_cnt = 0; int detect_spirals = 1; int dlg_send_bye = 0; +int reset_timeout = 1; stat_var *active_dlgs = 0; stat_var *processed_dlgs = 0; stat_var *expired_dlgs = 0; @@ -169,7 +170,7 @@ static int w_dlg_refer(struct sip_msg*, char*, char*); static int w_dlg_bridge(struct sip_msg*, char*, char*, char*); static int w_dlg_set_timeout(struct sip_msg*, char*, char*, char*); static int w_dlg_set_timeout_by_profile2(struct sip_msg *, char *, char *); -static int w_dlg_set_timeout_by_profile3(struct sip_msg *, char *, char *, +static int w_dlg_set_timeout_by_profile3(struct sip_msg *, char *, char *, char *); static int fixup_dlg_bye(void** param, int param_no); static int fixup_dlg_refer(void** param, int param_no); @@ -216,10 +217,10 @@ static cmd_export_t cmds[]={ 0, ANY_ROUTE }, {"dlg_set_timeout", (cmd_function)w_dlg_set_timeout, 3,fixup_igp_all, 0, ANY_ROUTE }, - {"dlg_set_timeout_by_profile", + {"dlg_set_timeout_by_profile", (cmd_function) w_dlg_set_timeout_by_profile2, 2, fixup_profile, 0, ANY_ROUTE }, - {"dlg_set_timeout_by_profile", + {"dlg_set_timeout_by_profile", (cmd_function) w_dlg_set_timeout_by_profile3, 3, fixup_profile, 0, ANY_ROUTE }, {"dlg_set_property", (cmd_function)w_dlg_set_property,1,fixup_spve_null, @@ -281,6 +282,7 @@ static param_export_t mod_params[]={ { "xavp_cfg", STR_PARAM, &dlg_xavp_cfg.s }, { "ka_timer", INT_PARAM, &dlg_ka_timer }, { "ka_interval", INT_PARAM, &dlg_ka_interval }, + { "reset_timeout", INT_PARAM, &reset_timeout, }, { 0,0,0 } }; @@ -531,7 +533,7 @@ static int mod_init(void) } if (timeout_spec.s) { - if ( pv_parse_spec(&timeout_spec, &timeout_avp)==0 + if ( pv_parse_spec(&timeout_spec, &timeout_avp)==0 && (timeout_avp.type!=PVT_AVP)){ LM_ERR("malformed or non AVP timeout " "AVP definition in '%.*s'\n", timeout_spec.len,timeout_spec.s); @@ -577,6 +579,11 @@ static int mod_init(void) return -1; } + if (reset_timeout != 0 && reset_timeout != 1) { + LM_ERR("invalid value %d for reset_timeout param!!\n",reset_timeout); + return -1; + } + /* if statistics are disabled, prevent their registration to core */ if (dlg_enable_stats==0) exports.stats = 0; @@ -784,7 +791,7 @@ static int w_set_dlg_profile(struct sip_msg *msg, char *profile, char *value) pve = (pv_elem_t *)value; if (((struct dlg_profile_table*)profile)->has_value) { - if ( pve==NULL || pv_printf_s(msg, pve, &val_s)!=0 || + if ( pve==NULL || pv_printf_s(msg, pve, &val_s)!=0 || val_s.len == 0 || val_s.s == NULL) { LM_WARN("cannot get string for value\n"); return -1; @@ -814,7 +821,7 @@ static int w_unset_dlg_profile(struct sip_msg *msg, char *profile, char *value) pve = (pv_elem_t *)value; if (((struct dlg_profile_table*)profile)->has_value) { - if ( pve==NULL || pv_printf_s(msg, pve, &val_s)!=0 || + if ( pve==NULL || pv_printf_s(msg, pve, &val_s)!=0 || val_s.len == 0 || val_s.s == NULL) { LM_WARN("cannot get string for value\n"); return -1; @@ -844,7 +851,7 @@ static int w_is_in_profile(struct sip_msg *msg, char *profile, char *value) pve = (pv_elem_t *)value; if ( pve!=NULL && ((struct dlg_profile_table*)profile)->has_value) { - if ( pv_printf_s(msg, pve, &val_s)!=0 || + if ( pv_printf_s(msg, pve, &val_s)!=0 || val_s.len == 0 || val_s.s == NULL) { LM_WARN("cannot get string for value\n"); return -1; @@ -879,7 +886,7 @@ static int w_get_profile_size3(struct sip_msg *msg, char *profile, sp_dest = (pv_spec_t *)value; } if ( pve!=NULL && ((struct dlg_profile_table*)profile)->has_value) { - if ( pv_printf_s(msg, pve, &val_s)!=0 || + if ( pv_printf_s(msg, pve, &val_s)!=0 || val_s.len == 0 || val_s.s == NULL) { LM_WARN("cannot get string for value\n"); return -1; @@ -1008,7 +1015,7 @@ static int w_dlg_bye(struct sip_msg *msg, char *side, char *s2) dlg = dlg_get_ctx_dialog(); if(dlg==NULL) return -1; - + n = (int)(long)side; if(n==1) { @@ -1043,7 +1050,7 @@ static int w_dlg_refer(struct sip_msg *msg, char *side, char *to) dlg = dlg_get_ctx_dialog(); if(dlg==NULL) return -1; - + n = (int)(long)side; if(fixup_get_svalue(msg, (gparam_p)to, &st)!=0) @@ -1154,7 +1161,7 @@ static int w_dlg_set_timeout(struct sip_msg *msg, char *pto, char *phe, char *ph return -1; } - if(update_dlg_timeout(dlg, to) != 0) + if(update_dlg_timeout(dlg, to) != 0) return -1; return 1; @@ -1202,7 +1209,7 @@ static int w_dlg_set_property(struct sip_msg *msg, char *prop, char *s2) } static int w_dlg_set_timeout_by_profile3(struct sip_msg *msg, char *profile, - char *value, char *timeout_str) + char *value, char *timeout_str) { pv_elem_t *pve = NULL; str val_s; @@ -1210,7 +1217,7 @@ static int w_dlg_set_timeout_by_profile3(struct sip_msg *msg, char *profile, pve = (pv_elem_t *) value; if(pve != NULL && ((struct dlg_profile_table *) profile)->has_value) { - if(pv_printf_s(msg,pve, &val_s) != 0 || + if(pv_printf_s(msg,pve, &val_s) != 0 || !val_s.s || val_s.len == 0) { LM_WARN("cannot get string for value\n"); return -1; @@ -1224,7 +1231,7 @@ static int w_dlg_set_timeout_by_profile3(struct sip_msg *msg, char *profile, return 1; } -static int w_dlg_set_timeout_by_profile2(struct sip_msg *msg, +static int w_dlg_set_timeout_by_profile2(struct sip_msg *msg, char *profile, char *timeout_str) { return w_dlg_set_timeout_by_profile3(msg, profile, NULL, timeout_str); diff --git a/modules/dialog/dlg_handlers.c b/modules/dialog/dlg_handlers.c index 9393d7f..e608a5b 100644 --- a/modules/dialog/dlg_handlers.c +++ b/modules/dialog/dlg_handlers.c @@ -79,9 +79,10 @@ static str rr_param; /*!< record-route parameter for matching */ static int dlg_flag; /*!< flag for dialog tracking */ static pv_spec_t *timeout_avp; /*!< AVP for timeout setting */ static int default_timeout; /*!< default dialog timeout */ -static int seq_match_mode; /*!< dlg_match mode */ +static int seq_match_mode; /*!< dlg_match mode */ static int shutdown_done = 0; /*!< 1 when destroy_dlg_handlers was called */ extern int detect_spirals; +extern int reset_timeout; /*!< reset dialog timeout for each in-dialog message */ extern int initial_cbs_inscript; extern int dlg_send_bye; extern int dlg_event_rt[DLG_EVENTRT_MAX]; @@ -190,7 +191,7 @@ static inline int add_dlg_rr_param(struct sip_msg *req, unsigned int entry, /*! * \brief Parse SIP message and populate leg informations * - * Parse SIP message and populate leg informations. + * Parse SIP message and populate leg informations. * \param dlg the dialog to add cseq, contact & record_route * \param msg sip message * \param t transaction @@ -764,7 +765,7 @@ static void unref_new_dialog(void *iuid) * \param t transaction * \param run_initial_cbs if set zero, initial callbacks are not executed * \return 0 on success, -1 on failure - */ + */ int dlg_new_dialog(sip_msg_t *req, struct cell *t, const int run_initial_cbs) { dlg_cell_t *dlg; @@ -1056,7 +1057,7 @@ dlg_cell_t *dlg_get_msg_dialog(sip_msg_t *msg) dlg = dlg_get_ctx_dialog(); if(dlg!=NULL) return dlg; - + if (pre_match_parse(msg, &callid, &ftag, &ttag, 0)<0) return NULL; dir = DLG_DIR_NONE; @@ -1071,7 +1072,7 @@ dlg_cell_t *dlg_get_msg_dialog(sip_msg_t *msg) /*! * \brief Function that is registered as RR callback for dialog tracking - * + * * Function that is registered as RR callback for dialog tracking. It * sets the appropriate events after the SIP method and run the state * machine to update the dialog state. It updates then the saved @@ -1258,7 +1259,7 @@ void dlg_onroute(struct sip_msg* req, str *route_params, void *param) if (timeout!=default_timeout) { dlg->lifetime = timeout; } - if (new_state!=DLG_STATE_EARLY) { + if ((new_state!=DLG_STATE_EARLY) && (old_state!=DLG_STATE_CONFIRMED || reset_timeout)) { if (update_dlg_timer( &dlg->tl, dlg->lifetime )==-1) { LM_ERR("failed to update dialog lifetime\n"); } else { -- 1.8.3.2
_______________________________________________ sr-dev mailing list [email protected] http://lists.sip-router.org/cgi-bin/mailman/listinfo/sr-dev
