From 751aa72492dc13bf89986a04a95b6a7ad9c9f4ec Mon Sep 17 00:00:00 2001 From: Andrei Datcu Date: Wed, 24 Sep 2014 17:43:15 +0300 Subject: [PATCH] [fraud_detection] Added show stats mi command --- modules/fraud_detection/fraud_detection.c | 97 ++++++++++++++++++++--- modules/fraud_detection/frd_events.c | 3 - modules/fraud_detection/frd_stats.c | 25 +++++- modules/fraud_detection/frd_stats.h | 1 + 4 files changed, 108 insertions(+), 18 deletions(-) diff --git a/modules/fraud_detection/fraud_detection.c b/modules/fraud_detection/fraud_detection.c index c0a279c02d1..e434435e325 100644 --- a/modules/fraud_detection/fraud_detection.c +++ b/modules/fraud_detection/fraud_detection.c @@ -29,6 +29,15 @@ extern str concalls_thresh_crit_col; extern str seqcalls_thresh_warn_col; extern str seqcalls_thresh_crit_col; +#define DEF_PARAM_STR_NAME(pname, strname)\ + static str pname ## _name = str_init(strname) + +DEF_PARAM_STR_NAME(cpm, "calls per minute"); +DEF_PARAM_STR_NAME(total_calls, "total calls"); +DEF_PARAM_STR_NAME(concurrent_calls, "concurrent calls"); +DEF_PARAM_STR_NAME(seq_calls, "sequential calls"); +#undef DEF_PARAM_STR_NAME + dr_head_p *dr_head; struct dr_binds drb; @@ -43,12 +52,9 @@ static void destroy(void); static int check_fraud(struct sip_msg *msg, char *user, char *number, char *pid); static int fixup_check_fraud(void **param, int param_no); +static struct mi_root* mi_show_stats(struct mi_root *cmd_tree, void *param); static cmd_export_t cmds[]={ -/* {"get_mapping",(cmd_function)get_mapping,1,fixup_pvar_null, - 0, REQUEST_ROUTE|ONREPLY_ROUTE}, - {"get_mapping",(cmd_function)get_mapping0,0,0, - 0, REQUEST_ROUTE|ONREPLY_ROUTE},*/ {"check_fraud", (cmd_function)check_fraud, 3, fixup_check_fraud, 0, REQUEST_ROUTE | ONREPLY_ROUTE}, {0,0,0,0,0,0} @@ -78,6 +84,8 @@ static param_export_t params[]={ static mi_export_t mi_cmds[] = { //{ "get_maps","return all mappings",mi_get_maps,MI_NO_INPUT_FLAG,0,0}, + {"show_fraud_stats", "print current stats for a particular user", + mi_show_stats, 0, 0, 0}, {0,0,0,0,0,0} }; @@ -277,7 +285,6 @@ static int check_fraud(struct sip_msg *msg, char *_user, char *_number, char *_p str shm_user; frd_stats_entry_t *se = get_stats(user, prefix, &shm_user); - LM_INFO("xxx - matched %u\n", rule->id); /* Check if we need to reset the stats */ struct tm now, then; @@ -342,14 +349,6 @@ static int check_fraud(struct sip_msg *msg, char *_user, char *_number, char *_p int rc = rc_no_rule; -#define DEF_PARAM_STR_NAME(pname, strname)\ - static str pname ## _name = str_init(strname) - - DEF_PARAM_STR_NAME(cpm, "calls per minute"); - DEF_PARAM_STR_NAME(total_calls, "total calls"); - DEF_PARAM_STR_NAME(concurrent_calls, "concurrent calls"); - DEF_PARAM_STR_NAME(seq_calls, "sequential calls"); - frd_thresholds_t *thr = (frd_thresholds_t*)rule->attrs.s; #define CHECK_AND_RAISE(pname, type) \ @@ -368,6 +367,8 @@ static int check_fraud(struct sip_msg *msg, char *_user, char *_number, char *_p else if CHECK_AND_RAISE(concurrent_calls, warning) else if CHECK_AND_RAISE(seq_calls, warning); +#undef CHECK_AND_RAISE + lock_release(&se->lock); /* Set dialog callback to check call duration */ @@ -409,3 +410,73 @@ static int check_fraud(struct sip_msg *msg, char *_user, char *_number, char *_p return rc; } + +static struct mi_root* mi_show_stats(struct mi_root *cmd_tree, void *param) +{ + /* User, number, pid */ + + struct mi_node *node = cmd_tree->node.kids; + str user, prefix; + unsigned int pid; + + if (node == NULL) + return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); + + user = node->value; + node = node->next; + + if (node == NULL) + return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); + + prefix = node->value; + node = node->next; + + if (node == NULL) + return init_mi_tree(400, MI_MISSING_PARM_S, MI_MISSING_PARM_LEN); + + if (str2int(&node->value, &pid) != 0) { + LM_WARN("Wrong value for profile id. Token <%.*s>\n", node->value.len, + node->value.s); + return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); + } + + if (!stats_exist(user, prefix)) { + LM_WARN("There is no data for user<%.*s> and prefix=<%.*s>\n", + user.len, user.s, prefix.len, prefix.s); + return init_mi_tree(400, MI_BAD_PARM_S, MI_BAD_PARM_LEN); + } + + + struct mi_root* rpl_tree = init_mi_tree(200, MI_OK_S, MI_OK_LEN); + if (rpl_tree == NULL) + return 0; + rpl_tree->node.flags |= MI_IS_ARRAY; + + frd_stats_entry_t *se = get_stats(user, prefix, NULL); + lock_get(&se->lock); + +#define ADD_STAT_CHILD(pname, pval) do {\ + int val_len;\ + char *cval = int2str(pval, &val_len);\ + LM_INFO("xxx - %u <%.*s>\n", pval, val_len,cval);\ + if (add_mi_node_child(&rpl_tree->node, MI_DUP_VALUE,\ + pname ## _name.s, pname ## _name.len, cval, val_len) == 0)\ + goto add_error;\ +} while (0) + + ADD_STAT_CHILD(cpm, se->stats.cpm); + ADD_STAT_CHILD(total_calls, se->stats.total_calls); + ADD_STAT_CHILD(concurrent_calls, se->stats.concurrent_calls); + ADD_STAT_CHILD(seq_calls, se->stats.seq_calls); + +#undef ADD_STAT_CHILD + + lock_release(&se->lock); + return rpl_tree; + +add_error: + lock_release(&se->lock); + LM_ERR("failed to add node\n"); + free_mi_tree(rpl_tree); + return 0; +} diff --git a/modules/fraud_detection/frd_events.c b/modules/fraud_detection/frd_events.c index 97260f0fae3..8e52bac921f 100644 --- a/modules/fraud_detection/frd_events.c +++ b/modules/fraud_detection/frd_events.c @@ -96,9 +96,6 @@ static void raise_event(event_id_t e, SET_PARAM(ruleid, int); #undef SET_PARAM - //extern struct qm_block* shm_block;*/ - qm_mem_check(mem_block); - qm_mem_check(shm_block); if (evi_raise_event(e, event_params) < 0) LM_ERR("cannot raise event\n"); } diff --git a/modules/fraud_detection/frd_stats.c b/modules/fraud_detection/frd_stats.c index 80308a2ad25..21d01c2a7d6 100644 --- a/modules/fraud_detection/frd_stats.c +++ b/modules/fraud_detection/frd_stats.c @@ -56,7 +56,8 @@ frd_stats_entry_t* get_stats(str user, str prefix, str *shm_user) } } - *shm_user = (*hm)->user; + if (shm_user) + *shm_user = (*hm)->user; frd_stats_entry_t **stats_entry = (frd_stats_entry_t**)get_item(&(*hm)->numbers_hm, prefix); @@ -80,6 +81,24 @@ frd_stats_entry_t* get_stats(str user, str prefix, str *shm_user) return *stats_entry; } + +int stats_exist(str user, str prefix) +{ + /* First go one level below using the user key */ + frd_users_map_item_t **hm = + (frd_users_map_item_t **)get_item(&stats_table, user); + + if (*hm == NULL) + return 0; + + frd_stats_entry_t **stats_entry = + (frd_stats_entry_t**)get_item(&(*hm)->numbers_hm, prefix); + if (*stats_entry == NULL) + return 0; + + return 1; +} + /* * Functions for freeing the stats hash table */ @@ -92,7 +111,9 @@ static void destroy_stats_entry(void *e) static void destroy_users(void *u) { - free_hash_map(&((frd_users_map_item_t*)u)->numbers_hm, destroy_stats_entry); + frd_users_map_item_t *hm = (frd_users_map_item_t*)u; + free_hash_map(&hm->numbers_hm, destroy_stats_entry); + shm_free(hm->user.s); shm_free(u); } diff --git a/modules/fraud_detection/frd_stats.h b/modules/fraud_detection/frd_stats.h index f41a3804427..3c6e7dda1f7 100644 --- a/modules/fraud_detection/frd_stats.h +++ b/modules/fraud_detection/frd_stats.h @@ -27,6 +27,7 @@ typedef struct _frd_hash_item { int init_stats_table(void); frd_stats_entry_t* get_stats(str user, str prefix, str *shm_user); +int stats_exist(str user, str prefix); void free_stats_table(void);