From 6128df70d334fa1fd4e808f8fcef1fc549d040bd Mon Sep 17 00:00:00 2001 From: Liviu Chircu Date: Thu, 10 Feb 2022 12:44:33 +0200 Subject: [PATCH] fraud_detection: Fix the 'call duration' events The 'call duration' events were not being raised anymore since commit a0fcf857ddb, due to the mismatching callback type check in dialog_terminate_CB(). Also rework commit a0fcf857ddb, where instead of switching the decrement operation on the DLGCB_DESTROY callback (to guarantee it only gets called one time), we just store and use a boolean marker, thus achieving the same effect but while using the optimal callbacks! (cherry picked from commit 7aa272aec749702627404c0d518b4b4fada5ec93) --- modules/fraud_detection/fraud_detection.c | 2 +- modules/fraud_detection/frd_events.c | 30 ++++++++++++++--------- modules/fraud_detection/frd_events.h | 2 ++ 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/modules/fraud_detection/fraud_detection.c b/modules/fraud_detection/fraud_detection.c index ae76a633141..1ba95fbb152 100644 --- a/modules/fraud_detection/fraud_detection.c +++ b/modules/fraud_detection/fraud_detection.c @@ -434,7 +434,7 @@ static int check_fraud(struct sip_msg *msg, str *user, str *number, int *pid) param->calldur_crit = thr->call_duration_thr.critical; param->interval_id = se->interval_id; - if (dlgb.register_dlgcb(dlgc, DLGCB_DESTROY, + if (dlgb.register_dlgcb(dlgc, DLGCB_FAILED|DLGCB_TERMINATED|DLGCB_EXPIRED, dialog_terminate_CB, param, free_dialog_CB_param) != 0) { LM_ERR("failed to register dialog terminated callback\n"); shm_free(param->number.s); diff --git a/modules/fraud_detection/frd_events.c b/modules/fraud_detection/frd_events.c index f8036fbb7a5..95fa95408f7 100644 --- a/modules/fraud_detection/frd_events.c +++ b/modules/fraud_detection/frd_events.c @@ -151,18 +151,24 @@ void dialog_terminate_CB(struct dlg_cell *dlg, int type, extern str call_dur_name; frd_dlg_param *frdparam = (frd_dlg_param*) *(params->param); - if (type & (DLGCB_TERMINATED|DLGCB_EXPIRED)) { - unsigned int duration = time(NULL) - dlg->start_ts; - if (frdparam->calldur_crit && duration >= frdparam->calldur_crit) - raise_critical_event(&call_dur_name, &duration, - &frdparam->calldur_crit, - &frdparam->user, &frdparam->number, &frdparam->ruleid); - - else if (frdparam->calldur_warn && duration >= frdparam->calldur_warn) - raise_warning_event(&call_dur_name, &duration, - &frdparam->calldur_warn, - &frdparam->user, &frdparam->number, &frdparam->ruleid); - } + if (frdparam->dlg_terminated || + !(type & (DLGCB_FAILED|DLGCB_TERMINATED|DLGCB_EXPIRED))) + return; + frdparam->dlg_terminated = 1; + + unsigned int duration = time(NULL) - dlg->start_ts; + LM_DBG("call-duration: %u sec (warn: %u, crit: %u), dlgcb: %d\n", + duration, frdparam->calldur_warn, frdparam->calldur_crit, type); + + if (frdparam->calldur_crit && duration >= frdparam->calldur_crit) + raise_critical_event(&call_dur_name, &duration, + &frdparam->calldur_crit, + &frdparam->user, &frdparam->number, &frdparam->ruleid); + + else if (frdparam->calldur_warn && duration >= frdparam->calldur_warn) + raise_warning_event(&call_dur_name, &duration, + &frdparam->calldur_warn, + &frdparam->user, &frdparam->number, &frdparam->ruleid); lock_get(&frdparam->stats->lock); if (frdparam->interval_id == frdparam->stats->interval_id) diff --git a/modules/fraud_detection/frd_events.h b/modules/fraud_detection/frd_events.h index 4b85e59a372..049ac4b97d1 100644 --- a/modules/fraud_detection/frd_events.h +++ b/modules/fraud_detection/frd_events.h @@ -48,6 +48,8 @@ typedef struct { unsigned int calldur_warn; unsigned int calldur_crit; + + int dlg_terminated; } frd_dlg_param; void dialog_terminate_CB(struct dlg_cell *dlgc, int type,