Skip to content

Commit 0c26f91

Browse files
author
ionutrazvanionita
committed
fix calls per minute for fraud_detection module
Now the calls per minute parameter is build as consisting of an initial time(t0) and a 60 seconds window(as was before). Each window slot holds the calls received in that second(as before). The difference is that now these parameters are updated based on three conditions: * we receive the call between [t0; t0 + WINDOW_SIZE(60s)] - we only update the number of calls for that slot(t0 + current time) and the calls per minute parameter * we receive the call in the interval of [t0+WINDOW_SIZE; t0+2*WINDOW_SIZE] - we do the following: move t0 in current call time - WINDOW_SIZE, invalidate all the calls we knew of from t0 to current t0 (current call time - WINDOW_SIZE) * we receive a call after 2 * WINDOW_SIZE(60 seconds) + t0 - this invalidates all the calls we knew of since the window is not does not contains calls newer than the last 60 seconds; (cherry picked from commit dd25c63)
1 parent bd3751b commit 0c26f91

File tree

1 file changed

+21
-6
lines changed

1 file changed

+21
-6
lines changed

modules/fraud_detection/fraud_detection.c

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,27 +358,42 @@ static int check_fraud(struct sip_msg *msg, char *_user, char *_number, char *_p
358358
++se->stats.total_calls;
359359

360360
/* Calls per FRD_SECS_PER_WINDOW */
361-
if (nowt - se->stats.last_matched_time >= FRD_SECS_PER_WINDOW) {
361+
if (nowt - se->stats.last_matched_time >= 2 * FRD_SECS_PER_WINDOW) {
362+
/* outside the range of t0 + 2*WINDOW_SIZE; we can't use any of the
363+
* data since they are too old */
362364
se->stats.cpm = 0;
363365
memset(se->stats.calls_window, 0,
364366
sizeof(unsigned short) * FRD_SECS_PER_WINDOW);
365367
se->stats.calls_window[nowt % FRD_SECS_PER_WINDOW] = 1;
368+
se->stats.last_matched_time = nowt;
366369
}
367-
else {
368-
unsigned int i = nowt % FRD_SECS_PER_WINDOW;
369-
unsigned int j = (se->stats.last_matched_time + 1) % FRD_SECS_PER_WINDOW;
370+
else if (nowt - se->stats.last_matched_time >= FRD_SECS_PER_WINDOW) {
371+
/* more than t0 + WINDOW_SIZE but less than 2 * WINDOW_SIZE
372+
* we can consider calls from t0 + (now - WINDOW_SIZE)
373+
* all cals from t0 to t0 + (now - WINDOW_SIZE) shall be invalidated */
374+
unsigned int old_matched_time = se->stats.last_matched_time;
375+
376+
se->stats.last_matched_time = nowt - FRD_SECS_PER_WINDOW + 1;
377+
378+
/*interval [old_last_matched_time; current_last_matched_time) shall
379+
* be invalidated */
380+
unsigned int i = (se->stats.last_matched_time - 1) % FRD_SECS_PER_WINDOW;
381+
unsigned int j = (old_matched_time - 1) % FRD_SECS_PER_WINDOW;
370382
for (;i != j; i = (i - 1 + FRD_SECS_PER_WINDOW) % FRD_SECS_PER_WINDOW) {
371383
se->stats.cpm -= se->stats.calls_window[i];
372384
se->stats.calls_window[i] = 0;
373385
}
386+
se->stats.calls_window[nowt%FRD_SECS_PER_WINDOW]++;
387+
} else {
388+
/* less than t0 + WINDOW_SIZE; all we need to do is to increase
389+
* the number of calls for nowt */
390+
se->stats.calls_window[nowt%FRD_SECS_PER_WINDOW]++;
374391
}
375392

376393
++se->stats.cpm;
377394
++se->stats.concurrent_calls;
378-
se->stats.last_matched_time = nowt;
379395

380396
/* Check the thresholds */
381-
382397
int rc = rc_no_rule;
383398

384399
frd_thresholds_t *thr = (frd_thresholds_t*)rule->attrs.s;

0 commit comments

Comments
 (0)