Module: sip-router Branch: master Commit: 97781390e663116f9e5d11f5644e1145487b6cfb URL: http://git.sip-router.org/cgi-bin/gitweb.cgi/sip-router/?a=commit;h=97781390...
Author: Daniel-Constantin Mierla miconda@gmail.com Committer: Daniel-Constantin Mierla miconda@gmail.com Date: Fri Jul 5 09:23:32 2013 +0200
dialog: added timer process to clean unconfirmed dialogs older than 5min
- timer runs every 90sec (customization to be added in the future) - safety procedure for cleaning dialog list
---
modules/dialog/dialog.c | 29 ++++++++++++++++++++++++----- modules/dialog/dlg_hash.c | 33 +++++++++++++++++++++++++++++++++ modules/dialog/dlg_hash.h | 3 +++ 3 files changed, 60 insertions(+), 5 deletions(-)
diff --git a/modules/dialog/dialog.c b/modules/dialog/dialog.c index e560b4e..ae105d4 100644 --- a/modules/dialog/dialog.c +++ b/modules/dialog/dialog.c @@ -138,6 +138,7 @@ int dlg_db_mode_param = DB_MODE_NONE; str dlg_xavp_cfg = {0}; int dlg_ka_timer = 0; int dlg_ka_interval = 0; +int dlg_clean_timer = 90;
/* db stuff */ static str db_url = str_init(DEFAULT_DB_URL); @@ -147,6 +148,7 @@ static int pv_get_dlg_count( struct sip_msg *msg, pv_param_t *param, pv_value_t *res);
void dlg_ka_timer_exec(unsigned int ticks, void* param); +void dlg_clean_timer_exec(unsigned int ticks, void* param);
/* commands wrappers and fixups */ static int fixup_profile(void** param, int param_no); @@ -697,9 +699,14 @@ static int mod_init(void) }
destroy_dlg_callbacks( DLGCB_LOADED ); + + /* timer process to send keep alive requests */ if(dlg_ka_timer>0 && dlg_ka_interval>0) register_sync_timers(1);
+ /* timer process to clean old unconfirmed dialogs */ + register_sync_timers(1); + return 0; }
@@ -708,11 +715,18 @@ static int child_init(int rank) { dlg_db_mode = dlg_db_mode_param;
- if(rank==PROC_MAIN && dlg_ka_timer>0 && dlg_ka_interval>0) - { - if(fork_sync_timer(PROC_TIMER, "Dialog KA Timer", 1 /*socks flag*/, - dlg_ka_timer_exec, NULL, dlg_ka_timer /*sec*/)<0) { - LM_ERR("failed to start ka timer routine as process\n"); + if(rank==PROC_MAIN) { + if(dlg_ka_timer>0 && dlg_ka_interval>0) { + if(fork_sync_timer(PROC_TIMER, "Dialog KA Timer", 1 /*socks flag*/, + dlg_ka_timer_exec, NULL, dlg_ka_timer /*sec*/)<0) { + LM_ERR("failed to start ka timer routine as process\n"); + return -1; /* error */ + } + } + + if(fork_sync_timer(PROC_TIMER, "Dialog Clean Timer", 1 /*socks flag*/, + dlg_clean_timer_exec, NULL, dlg_clean_timer /*sec*/)<0) { + LM_ERR("failed to start clean timer routine as process\n"); return -1; /* error */ } } @@ -1221,6 +1235,11 @@ void dlg_ka_timer_exec(unsigned int ticks, void* param) dlg_ka_run(ticks); }
+void dlg_clean_timer_exec(unsigned int ticks, void* param) +{ + dlg_clean_run(ticks); +} + static int fixup_dlg_bye(void** param, int param_no) { char *val; diff --git a/modules/dialog/dlg_hash.c b/modules/dialog/dlg_hash.c index bba619a..6f944e1 100644 --- a/modules/dialog/dlg_hash.c +++ b/modules/dialog/dlg_hash.c @@ -223,6 +223,38 @@ int dlg_ka_run(ticks_t ti) return 0; }
+/** + * clean old unconfirmed dialogs + * + */ +int dlg_clean_run(ticks_t ti) +{ + unsigned int i; + unsigned int tm; + dlg_cell_t *dlg; + dlg_cell_t *tdlg; + + tm = (unsigned int)time(NULL); + for(i=0; i<d_table->size; i++) + { + lock_set_get(d_table->locks, d_table->entries[i].lock_idx); + dlg = d_table->entries[i].first; + while (dlg) { + tdlg = dlg; + dlg = dlg->next; + if(tdlg->state==DLG_STATE_UNCONFIRMED && tdlg->init_ts<tm-300) { + /* dialog in early state older than 5min */ + LM_NOTICE("dialog in early state is too old (%p ref %d)\n", + tdlg, tdlg->ref); + unlink_unsafe_dlg(&d_table->entries[i], tdlg); + destroy_dlg(tdlg); + } + } + lock_set_release(d_table->locks, d_table->entries[i].lock_idx); + } + return 0; +} + /*! * \brief Initialize the global dialog table * \param size size of the table @@ -434,6 +466,7 @@ struct dlg_cell* build_new_dlg( str *callid, str *from_uri, str *to_uri,
memset( dlg, 0, len); dlg->state = DLG_STATE_UNCONFIRMED; + dlg->init_ts = (unsigned int)time(NULL);
dlg->h_entry = core_hash( callid, 0, d_table->size); LM_DBG("new dialog on hash %u\n",dlg->h_entry); diff --git a/modules/dialog/dlg_hash.h b/modules/dialog/dlg_hash.h index ed295cc..4bfc911 100644 --- a/modules/dialog/dlg_hash.h +++ b/modules/dialog/dlg_hash.h @@ -114,6 +114,7 @@ typedef struct dlg_cell unsigned int h_entry; /*!< index of hash table entry (the slot number) */ unsigned int state; /*!< dialog state */ unsigned int lifetime; /*!< dialog lifetime */ + unsigned int init_ts; /*!< init (creation) time (absolute UNIX ts)*/ unsigned int start_ts; /*!< start time (absolute UNIX ts)*/ unsigned int dflags; /*!< internal dialog memory flags */ unsigned int iflags; /*!< internal dialog persistent flags */ @@ -527,6 +528,8 @@ int dlg_ka_add(dlg_cell_t *dlg);
int dlg_ka_run(ticks_t ti);
+int dlg_clean_run(ticks_t ti); + /*! * \brief Update dialog lifetime - for internal callers. */