diff --git a/modules/fraud_detection/fraud_detection.c b/modules/fraud_detection/fraud_detection.c index 80e8e10c9d7..6923caac481 100644 --- a/modules/fraud_detection/fraud_detection.c +++ b/modules/fraud_detection/fraud_detection.c @@ -433,7 +433,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,