static gboolean check_metric_settings (struct rspamd_task *task, struct metric *metric, double *score) { const ucl_object_t *mobj, *reject, *act; double val; if (task->settings == NULL) { return FALSE; } mobj = ucl_object_find_key (task->settings, metric->name); if (mobj != NULL) { act = ucl_object_find_key (mobj, "actions"); if (act != NULL) { reject = ucl_object_find_key (act, rspamd_action_to_str (METRIC_ACTION_REJECT)); if (reject != NULL && ucl_object_todouble_safe (reject, &val)) { *score = val; return TRUE; } } } return FALSE; }
static double get_specific_action_score (const ucl_object_t *metric, struct metric_action *action) { const ucl_object_t *act, *sact; double score; if (metric) { act = ucl_object_find_key (metric, "actions"); if (act) { sact = ucl_object_find_key (act, rspamd_action_to_str (action->action)); if (sact != NULL && ucl_object_todouble_safe (sact, &score)) { return score; } } } return action->score; }
static double get_specific_action_score (struct rspamd_task *task, const ucl_object_t *metric, struct metric_action *action) { const ucl_object_t *act, *sact; const gchar *act_name; double score; if (metric) { act = ucl_object_find_key (metric, "actions"); if (act) { act_name = rspamd_action_to_str (action->action); sact = ucl_object_find_key (act, act_name); if (sact != NULL && ucl_object_todouble_safe (sact, &score)) { msg_debug_task ("found override score %.2f for action %s in settings", score, act_name); return score; } } } return action->score; }
static void insert_metric_result (struct rspamd_task *task, struct metric *metric, const gchar *symbol, double flag, GList * opts, gboolean single) { struct metric_result *metric_res; struct symbol *s; gdouble w, *gr_score = NULL; struct rspamd_symbol_def *sdef; struct rspamd_symbols_group *gr = NULL; const ucl_object_t *mobj, *sobj; metric_res = rspamd_create_metric_result (task, metric->name); sdef = g_hash_table_lookup (metric->symbols, symbol); if (sdef == NULL) { w = 0.0; } else { w = (*sdef->weight_ptr) * flag; gr = sdef->gr; if (gr != NULL) { gr_score = g_hash_table_lookup (metric_res->sym_groups, gr); if (gr_score == NULL) { gr_score = rspamd_mempool_alloc (task->task_pool, sizeof (gdouble)); *gr_score = 0; g_hash_table_insert (metric_res->sym_groups, gr, gr_score); } } } if (task->settings) { mobj = ucl_object_find_key (task->settings, metric->name); if (mobj) { gdouble corr; sobj = ucl_object_find_key (mobj, symbol); if (sobj != NULL && ucl_object_todouble_safe (sobj, &corr)) { msg_debug ("settings: changed weight of symbol %s from %.2f to %.2f", symbol, w, corr); w = corr * flag; } } } /* XXX: does not take grow factor into account */ if (gr != NULL && gr_score != NULL && gr->max_score > 0.0) { if (*gr_score >= gr->max_score) { msg_info ("maximum group score %.2f for group %s has been reached," " ignoring symbol %s with weight %.2f", gr->max_score, gr->name, symbol, w); return; } else if (*gr_score + w > gr->max_score) { w = gr->max_score - *gr_score; } *gr_score += w; } /* Add metric score */ if ((s = g_hash_table_lookup (metric_res->symbols, symbol)) != NULL) { if (sdef && sdef->one_shot) { /* * For one shot symbols we do not need to add them again, so * we just force single behaviour here */ single = TRUE; } if (s->options && opts && opts != s->options) { /* Append new options */ s->options = g_list_concat (s->options, g_list_copy (opts)); /* * Note that there is no need to add new destructor of GList as elements of appended * GList are used directly, so just free initial GList */ } else if (opts) { s->options = g_list_copy (opts); rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_list_free, s->options); } if (!single) { /* Handle grow factor */ if (metric_res->grow_factor && w > 0) { w *= metric_res->grow_factor; metric_res->grow_factor *= metric->grow_factor; } s->score += w; metric_res->score += w; } else { if (fabs (s->score) < fabs (w)) { /* Replace less weight with a bigger one */ metric_res->score = metric_res->score - s->score + w; s->score = w; } } } else { s = rspamd_mempool_alloc (task->task_pool, sizeof (struct symbol)); /* Handle grow factor */ if (metric_res->grow_factor && w > 0) { w *= metric_res->grow_factor; metric_res->grow_factor *= metric->grow_factor; } else if (w > 0) { metric_res->grow_factor = metric->grow_factor; } s->score = w; s->name = symbol; s->def = sdef; metric_res->score += w; if (opts) { s->options = g_list_copy (opts); rspamd_mempool_add_destructor (task->task_pool, (rspamd_mempool_destruct_t) g_list_free, s->options); } else { s->options = NULL; } g_hash_table_insert (metric_res->symbols, (gpointer) symbol, s); } debug_task ("symbol %s, score %.2f, metric %s, factor: %f", symbol, s->score, metric->name, w); }
static struct rspamd_symbol_result * insert_metric_result (struct rspamd_task *task, struct rspamd_metric *metric, const gchar *symbol, double flag, const gchar *opt, gboolean single) { struct rspamd_metric_result *metric_res; struct rspamd_symbol_result *s = NULL; gdouble w, *gr_score = NULL; struct rspamd_symbol *sdef; struct rspamd_symbols_group *gr = NULL; const ucl_object_t *mobj, *sobj; metric_res = rspamd_create_metric_result (task, metric->name); sdef = g_hash_table_lookup (metric->symbols, symbol); if (sdef == NULL) { w = 0.0; } else { w = (*sdef->weight_ptr) * flag; gr = sdef->gr; if (gr != NULL) { gr_score = g_hash_table_lookup (metric_res->sym_groups, gr); if (gr_score == NULL) { gr_score = rspamd_mempool_alloc (task->task_pool, sizeof (gdouble)); *gr_score = 0; g_hash_table_insert (metric_res->sym_groups, gr, gr_score); } } } if (task->settings) { mobj = task->settings; gdouble corr; sobj = ucl_object_lookup (mobj, symbol); if (sobj != NULL && ucl_object_todouble_safe (sobj, &corr)) { msg_debug ("settings: changed weight of symbol %s from %.2f to %.2f", symbol, w, corr); w = corr * flag; } } /* XXX: does not take grow factor into account */ if (gr != NULL && gr_score != NULL && gr->max_score > 0.0) { if (*gr_score >= gr->max_score) { msg_info_task ("maximum group score %.2f for group %s has been reached," " ignoring symbol %s with weight %.2f", gr->max_score, gr->name, symbol, w); return g_hash_table_lookup (metric_res->symbols, symbol); } else if (*gr_score + w > gr->max_score) { w = gr->max_score - *gr_score; } *gr_score += w; } /* Add metric score */ if ((s = g_hash_table_lookup (metric_res->symbols, symbol)) != NULL) { if (sdef && (sdef->flags & RSPAMD_SYMBOL_FLAG_ONESHOT)) { /* * For one shot symbols we do not need to add them again, so * we just force single behaviour here */ single = TRUE; } if (rspamd_task_add_result_option (task, s, opt)) { if (!single) { /* Handle grow factor */ if (metric_res->grow_factor && w > 0) { w *= metric_res->grow_factor; metric_res->grow_factor *= metric->grow_factor; } s->score += w; metric_res->score += w; } else { if (fabs (s->score) < fabs (w)) { /* Replace less weight with a bigger one */ metric_res->score = metric_res->score - s->score + w; s->score = w; } } } } else { s = rspamd_mempool_alloc0 (task->task_pool, sizeof (struct rspamd_symbol_result)); /* Handle grow factor */ if (metric_res->grow_factor && w > 0) { w *= metric_res->grow_factor; metric_res->grow_factor *= metric->grow_factor; } else if (w > 0) { metric_res->grow_factor = metric->grow_factor; } s->score = w; s->name = symbol; s->sym = sdef; metric_res->score += w; rspamd_task_add_result_option (task, s, opt); g_hash_table_insert (metric_res->symbols, (gpointer) symbol, s); } msg_debug ("symbol %s, score %.2f, metric %s, factor: %f", symbol, s->score, metric->name, w); return s; }