Browse Source

Refactor metric actions handling.

Use array of actions instead of a linked list to speed up processing.
* Removed required_score, reject_score and action in metric config,
now REJECT is the only default action for a metric.
tags/0.6.0
Vsevolod Stakhov 10 years ago
parent
commit
5edc7624ce
12 changed files with 113 additions and 140 deletions
  1. 1
    2
      src/cfg_rcl.c
  2. 5
    3
      src/cfg_utils.c
  3. 14
    7
      src/cfg_xml.c
  4. 3
    0
      src/cfg_xml.h
  5. 28
    59
      src/dynamic_cfg.c
  6. 16
    13
      src/filter.c
  7. 3
    5
      src/filter.h
  8. 4
    3
      src/lua/lua_task.c
  9. 17
    15
      src/protocol.c
  10. 3
    2
      src/roll_history.c
  11. 2
    2
      src/smtp_utils.c
  12. 17
    29
      src/webui.c

+ 1
- 2
src/cfg_rcl.c View File

@@ -328,10 +328,9 @@ rspamd_rcl_metric_handler (struct config_file *cfg, rspamd_cl_object_t *obj,
g_set_error (err, CFG_RCL_ERROR, EINVAL, "invalid action definition: %s", cur->key);
return FALSE;
}
action = memory_pool_alloc (cfg->cfg_pool, sizeof (struct metric_action));
action = &metric->actions[action_value];
action->action = action_value;
action->score = action_score;
metric->actions = g_list_prepend (metric->actions, action);
}
}
else if (new) {

+ 5
- 3
src/cfg_utils.c View File

@@ -729,8 +729,7 @@ post_load_config (struct config_file *cfg)
if ((def_metric = g_hash_table_lookup (cfg->metrics, DEFAULT_METRIC)) == NULL) {
def_metric = check_metric_conf (cfg, NULL);
def_metric->name = DEFAULT_METRIC;
def_metric->required_score = DEFAULT_SCORE;
def_metric->reject_score = DEFAULT_REJECT_SCORE;
def_metric->actions[METRIC_ACTION_REJECT].score = DEFAULT_SCORE;
cfg->metrics_list = g_list_prepend (cfg->metrics_list, def_metric);
g_hash_table_insert (cfg->metrics, DEFAULT_METRIC, def_metric);
}
@@ -858,12 +857,15 @@ check_statfile_conf (struct config_file *cfg, struct statfile *c)
struct metric *
check_metric_conf (struct config_file *cfg, struct metric *c)
{
int i;
if (c == NULL) {
c = memory_pool_alloc0 (cfg->cfg_pool, sizeof (struct metric));
c->action = METRIC_ACTION_REJECT;
c->grow_factor = 1.0;
c->symbols = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
c->descriptions = g_hash_table_new (rspamd_str_hash, rspamd_str_equal);
for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
c->actions[i].score = -1.0;
}
memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func) g_hash_table_destroy, c->symbols);
memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func) g_hash_table_destroy, c->descriptions);
}

+ 14
- 7
src/cfg_xml.c View File

@@ -442,14 +442,14 @@ static struct xml_parser_rule grammar[] = {
},
{
"required_score",
xml_handle_double,
G_STRUCT_OFFSET (struct metric, required_score),
xml_handle_deprecated,
0,
NULL
},
{
"reject_score",
xml_handle_double,
G_STRUCT_OFFSET (struct metric, reject_score),
xml_handle_deprecated,
0,
NULL
},
{
@@ -1057,7 +1057,7 @@ handle_metric_action (struct config_file *cfg, struct rspamd_xml_userdata *ctx,
/* First of all check whether we have data with weight (reject:50 for example) */
if ((p = strchr (data, ':')) == NULL) {
if (check_action_str (data, &res)) {
metric->action = res;
/* XXX: no longer needed */
return TRUE;
}
return FALSE;
@@ -1067,7 +1067,7 @@ handle_metric_action (struct config_file *cfg, struct rspamd_xml_userdata *ctx,
return FALSE;
}
else {
action = memory_pool_alloc (cfg->cfg_pool, sizeof (struct metric_action));
action = &metric->actions[res];
action->action = res;
errno = 0;
action->score = strtod (p + 1, &errstr);
@@ -1075,7 +1075,6 @@ handle_metric_action (struct config_file *cfg, struct rspamd_xml_userdata *ctx,
msg_err ("invalid double value: %s", data);
return FALSE;
}
metric->actions = g_list_prepend (metric->actions, action);
}
}

@@ -1797,6 +1796,14 @@ xml_handle_boolean (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GH
return TRUE;
}

gboolean
xml_handle_deprecated (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset)
{

msg_err ("parameter is depreciated: %s", ctx->section_name);
return TRUE;
}

gboolean
xml_handle_double (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset)
{

+ 3
- 0
src/cfg_xml.h View File

@@ -116,6 +116,9 @@ gboolean xml_handle_uint16 (struct config_file *cfg, struct rspamd_xml_userdata
/* Flags */
gboolean xml_handle_boolean (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);

/* For deprecated attributes */
gboolean xml_handle_deprecated (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);

/* Specific params */
/* Options specific */
gboolean options_handle_nameserver (struct config_file *cfg, struct rspamd_xml_userdata *ctx, GHashTable *attrs, gchar *data, gpointer user_data, gpointer dest_struct, gint offset);

+ 28
- 59
src/dynamic_cfg.c View File

@@ -40,7 +40,7 @@ struct dynamic_cfg_action {

struct dynamic_cfg_metric {
GList *symbols;
GList *actions;
struct dynamic_cfg_action actions[METRIC_ACTION_MAX];
gchar *name;
};

@@ -62,7 +62,6 @@ dynamic_cfg_free (GList *conf_metrics)
GList *cur, *cur_elt;
struct dynamic_cfg_metric *metric;
struct dynamic_cfg_symbol *sym;
struct dynamic_cfg_action *act;

if (conf_metrics) {
cur = conf_metrics;
@@ -78,16 +77,6 @@ dynamic_cfg_free (GList *conf_metrics)
}
g_list_free (metric->symbols);
}

if (metric->actions) {
cur_elt = metric->actions;
while (cur_elt) {
act = cur_elt->data;
g_slice_free1 (sizeof (struct dynamic_cfg_symbol), act);
cur_elt = g_list_next (cur_elt);
}
g_list_free (metric->actions);
}
g_slice_free1 (sizeof (struct dynamic_cfg_metric), metric);
cur = g_list_next (cur);
}
@@ -102,13 +91,14 @@ dynamic_cfg_free (GList *conf_metrics)
static void
apply_dynamic_conf (GList *conf_metrics, struct config_file *cfg)
{
GList *cur, *cur_elt, *tmp;
GList *cur, *cur_elt;
struct dynamic_cfg_metric *metric;
struct dynamic_cfg_symbol *sym;
struct dynamic_cfg_action *act;
struct metric *real_metric;
struct metric_action *real_act;
gdouble *w;
gint i, j;

cur = conf_metrics;
while (cur) {
@@ -126,22 +116,21 @@ apply_dynamic_conf (GList *conf_metrics, struct config_file *cfg)
cur_elt = g_list_next (cur_elt);
}

cur_elt = metric->actions;
while (cur_elt) {
act = cur_elt->data;
tmp = real_metric->actions;
while (tmp) {
real_act = tmp->data;
for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
act = &metric->actions[i];
if (act->value < 0) {
continue;
}
for (j = METRIC_ACTION_REJECT; j < METRIC_ACTION_MAX; j ++) {
real_act = &real_metric->actions[j];
if (real_act->action == act->action) {
real_act->score = act->value;
}
/* Update required score accordingly to metric's action */
if (act->action == real_metric->action) {
real_metric->required_score = act->value;
if (act->action == METRIC_ACTION_REJECT) {
real_metric->actions[METRIC_ACTION_REJECT].score = act->value;
}
tmp = g_list_next (tmp);
}
cur_elt = g_list_next (cur_elt);
}
}
cur = g_list_next (cur);
@@ -257,6 +246,9 @@ json_config_fin_cb (memory_pool_t * pool, struct map_cb_data *data)
continue;
}
cur_metric = g_slice_alloc0 (sizeof (struct dynamic_cfg_metric));
for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
cur_metric->actions[i].value = -1.0;
}
cur_metric->name = g_strdup (json_string_value (cur_nm));
cur_nm = json_object_get (cur_elt, "symbols");
/* Parse symbols */
@@ -286,17 +278,14 @@ json_config_fin_cb (memory_pool_t * pool, struct map_cb_data *data)
it_val = json_array_get (cur_nm, j);
if (it_val && json_is_object (it_val)) {
if (json_object_get (it_val, "name") && json_object_get (it_val, "value")) {

cur_action = g_slice_alloc0 (sizeof (struct dynamic_cfg_action));
if (!check_action_str (json_string_value (json_object_get (it_val, "name")), &test_act)) {
msg_err ("unknown action: %s", json_string_value (json_object_get (it_val, "name")));
g_slice_free1 (sizeof (struct dynamic_cfg_action), cur_action);
continue;
}
cur_action = &cur_metric->actions[test_act];
cur_action->action = test_act;
cur_action->value = json_number_value (json_object_get (it_val, "value"));
/* Insert action */
cur_metric->actions = g_list_prepend (cur_metric->actions, cur_action);
}
else {
msg_info ("json symbol object has no mandatory 'name' and 'value' attributes");
@@ -351,6 +340,8 @@ dump_dynamic_list (gint fd, GList *rules)
struct dynamic_cfg_symbol *sym;
struct dynamic_cfg_action *act;
FILE *f;
gint i;
gboolean start = TRUE;

/* Open buffered stream for the descriptor */
if ((f = fdopen (fd, "a+")) == NULL) {
@@ -387,16 +378,16 @@ dump_dynamic_list (gint fd, GList *rules)
}

if (metric->actions) {
cur_elt = metric->actions;
fprintf (f, " \"actions\": [\n");
while (cur_elt) {
act = cur_elt->data;
cur_elt = g_list_next (cur_elt);
if (cur_elt) {
fprintf (f, " {\"name\": \"%s\",\"value\": %.2f},\n", str_action_metric (act->action), act->value);
for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
act = &metric->actions[i];
if (act->value < 0) {
continue;
}
else {
fprintf (f, " {\"name\": \"%s\",\"value\": %.2f}\n", str_action_metric (act->action), act->value);
fprintf (f, " %s{\"name\": \"%s\",\"value\": %.2f}\n",
(start ? "" : ","), str_action_metric (act->action), act->value);
if (start) {
start = FALSE;
}
}
fprintf (f, " ]\n");
@@ -573,7 +564,6 @@ add_dynamic_action (struct config_file *cfg, const gchar *metric_name, guint act
{
GList *cur;
struct dynamic_cfg_metric *metric = NULL;
struct dynamic_cfg_action *act = NULL;

if (cfg->dynamic_conf == NULL) {
msg_info ("dynamic conf is disabled");
@@ -592,33 +582,12 @@ add_dynamic_action (struct config_file *cfg, const gchar *metric_name, guint act

if (metric != NULL) {
/* Search for an action */
cur = metric->actions;
while (cur) {
act = cur->data;
if (act->action == action) {
act->value = value;
msg_debug ("change value of action %d to %.2f", action, value);
break;
}
act = NULL;
cur = g_list_next (cur);
}
if (act == NULL) {
/* Action not found, insert it */
act = g_slice_alloc (sizeof (struct dynamic_cfg_action));
act->action = action;
act->value = value;
metric->actions = g_list_prepend (metric->actions, act);
msg_debug ("create action %d in metric %s", action, metric_name);
}
metric->actions[action].value = value;
}
else {
/* Metric not found, create it */
metric = g_slice_alloc0 (sizeof (struct dynamic_cfg_metric));
act = g_slice_alloc (sizeof (struct dynamic_cfg_action));
act->action = action;
act->value = value;
metric->actions = g_list_prepend (metric->actions, act);
metric->actions[action].value = value;
metric->name = g_strdup (metric_name);
cfg->current_dynamic_conf = g_list_prepend (cfg->current_dynamic_conf, metric);
msg_debug ("create metric %s for action %d", metric_name, action);

+ 16
- 13
src/filter.c View File

@@ -227,7 +227,7 @@ check_metric_is_spam (struct worker_task *task, struct metric *metric)
struct metric_result *res;
double ms, rs;

/* Avoid concurrenting while checking results */
/* Avoid concurrency while checking results */
#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
g_static_mutex_lock (&result_mtx);
#else
@@ -241,9 +241,9 @@ check_metric_is_spam (struct worker_task *task, struct metric *metric)
G_UNLOCK (result_mtx);
#endif
if (!check_metric_settings (res, &ms, &rs)) {
ms = metric->required_score;
ms = metric->actions[METRIC_ACTION_REJECT].score;
}
return res->score >= ms;
return (ms > 0 && res->score >= ms);
}

#if ((GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION <= 30))
@@ -280,7 +280,7 @@ process_filters (struct worker_task *task)
while (cur) {
metric = cur->data;
if (!task->pass_all_filters &&
metric->action == METRIC_ACTION_REJECT &&
metric->actions[METRIC_ACTION_REJECT].score > 0 &&
check_metric_is_spam (task, metric)) {
task->s->wanna_die = TRUE;
check_session_pending (task->s);
@@ -763,9 +763,9 @@ insert_metric_header (gpointer metric_name, gpointer metric_value, gpointer data
rspamd_snprintf (header_name, sizeof (header_name), "X-Spam-%s", metric_res->metric->name);

if (!check_metric_settings (metric_res, &ms, &rs)) {
ms = metric_res->metric->required_score;
ms = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
}
if (metric_res->score >= ms) {
if (ms > 0 && metric_res->score >= ms) {
r += rspamd_snprintf (outbuf + r, sizeof (outbuf) - r, "yes; %.2f/%.2f/%.2f; ", metric_res->score, ms, rs);
}
else {
@@ -835,7 +835,9 @@ str_action_metric (enum rspamd_metric_action action)
case METRIC_ACTION_GREYLIST:
return "greylist";
case METRIC_ACTION_NOACTION:
return "no action";
return "no_action";
case METRIC_ACTION_MAX:
return "invalid max action";
}

return "unknown action";
@@ -844,25 +846,26 @@ str_action_metric (enum rspamd_metric_action action)
gint
check_metric_action (double score, double required_score, struct metric *metric)
{
GList *cur;
struct metric_action *action, *selected_action = NULL;
double max_score = 0;
int i;

if (score >= required_score) {
return metric->action;
return METRIC_ACTION_REJECT;
}
else if (metric->actions == NULL) {
return METRIC_ACTION_NOACTION;
}
else {
cur = metric->actions;
while (cur) {
action = cur->data;
for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
action = &metric->actions[i];
if (action->score < 0) {
continue;
}
if (score >= action->score && action->score > max_score) {
selected_action = action;
max_score = action->score;
}
cur = g_list_next (cur);
}
if (selected_action) {
return selected_action->action;

+ 3
- 5
src/filter.h View File

@@ -42,7 +42,8 @@ enum rspamd_metric_action {
METRIC_ACTION_REWRITE_SUBJECT,
METRIC_ACTION_ADD_HEADER,
METRIC_ACTION_GREYLIST,
METRIC_ACTION_NOACTION
METRIC_ACTION_NOACTION,
METRIC_ACTION_MAX
};

struct metric_action {
@@ -58,12 +59,9 @@ struct metric {
gchar *func_name; /**< name of consolidation function */
metric_cons_func func; /**< c consolidation function */
double grow_factor; /**< grow factor for metric */
double required_score; /**< required score for this metric */
double reject_score; /**< reject score for this metric */
GHashTable *symbols; /**< weights of symbols in metric */
GHashTable *descriptions; /**< descriptions of symbols in metric */
enum rspamd_metric_action action; /**< action to do by this metric by default */
GList *actions; /**< actions that can be performed by this metric */
struct metric_action actions[METRIC_ACTION_MAX]; /**< all actions of the metric */
gchar *subject; /**< subject rewrite string */
};


+ 4
- 3
src/lua/lua_task.c View File

@@ -1552,9 +1552,9 @@ lua_task_get_metric_score (lua_State *L)
lua_newtable (L);
lua_pushnumber (L, metric_res->score);
lua_rawseti (L, -2, 1);
lua_pushnumber (L, metric_res->metric->required_score);
lua_pushnumber (L, metric_res->metric->actions[METRIC_ACTION_REJECT].score);
lua_rawseti (L, -2, 2);
lua_pushnumber (L, metric_res->metric->reject_score);
lua_pushnumber (L, metric_res->metric->actions[METRIC_ACTION_REJECT].score);
lua_rawseti (L, -2, 3);
}
else {
@@ -1578,7 +1578,8 @@ lua_task_get_metric_action (lua_State *L)

if (task && metric_name) {
if ((metric_res = g_hash_table_lookup (task->results, metric_name)) != NULL) {
action = check_metric_action (metric_res->score, metric_res->metric->required_score, metric_res->metric);
action = check_metric_action (metric_res->score,
metric_res->metric->actions[METRIC_ACTION_REJECT].score, metric_res->metric);
lua_pushstring (L, str_action_metric (action));
}
else {

+ 17
- 15
src/protocol.c View File

@@ -113,6 +113,8 @@ str_action_metric_spamc (enum rspamd_metric_action action)
return "greylist";
case METRIC_ACTION_NOACTION:
return "no action";
case METRIC_ACTION_MAX:
return "invalid max action";
}

return "unknown action";
@@ -1210,15 +1212,15 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
}
if (metric_name == NULL || metric_value == NULL) {
m = g_hash_table_lookup (task->cfg->metrics, DEFAULT_METRIC);
default_required_score = m->required_score;
default_required_score = m->actions[METRIC_ACTION_REJECT].score;
default_score = 0;
if (metric_res != NULL && !check_metric_settings (metric_res, &ms, &rs)) {
ms = m->required_score;
rs = m->reject_score;
ms = m->actions[METRIC_ACTION_REJECT].score;
rs = m->actions[METRIC_ACTION_REJECT].score;
}
else if (metric_res == NULL) {
ms = m->required_score;
rs = m->reject_score;
ms = m->actions[METRIC_ACTION_REJECT].score;
rs = m->actions[METRIC_ACTION_REJECT].score;
}

if (!task->is_json) {
@@ -1232,24 +1234,24 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data
if (!task->is_skipped) {
cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
cd->log_size - cd->log_offset,
"(%s: F (no action): [0.00/%.2f/%.2f] [", "default", ms, rs);
"(%s: F (no action): [0.00/%.2f] [", "default", ms);
}
else {
cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
cd->log_size - cd->log_offset, "(%s: S: [0.00/%.2f/%.2f] [",
"default", ms, rs);
cd->log_size - cd->log_offset, "(%s: S: [0.00/%.2f] [",
"default", ms);
}
}
else {
/* XXX: dirty hack */
if (strcmp (metric_res->metric->name, DEFAULT_METRIC) == 0) {
default_required_score = metric_res->metric->required_score;
default_required_score = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
default_score = metric_res->score;
}

if (!check_metric_settings (metric_res, &ms, &rs)) {
ms = metric_res->metric->required_score;
rs = metric_res->metric->reject_score;
ms = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
rs = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
}
if (!check_metric_action_settings (task, metric_res,
metric_res->score, &action)) {
@@ -1273,15 +1275,15 @@ show_metric_result (gpointer metric_name, gpointer metric_value, void *user_data

cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
cd->log_size - cd->log_offset,
"(%s: %c (%s): [%.2f/%.2f/%.2f] [", (gchar *) metric_name,
"(%s: %c (%s): [%.2f/%.2f] [", (gchar *) metric_name,
is_spam ? 'T' : 'F', str_action_metric (action),
metric_res->score, ms, rs);
metric_res->score, ms);
}
else {
cd->log_offset += rspamd_snprintf (cd->log_buf + cd->log_offset,
cd->log_size - cd->log_offset,
"(%s: %c (default): [%.2f/%.2f/%.2f] [",
(gchar *) metric_name, 'S', metric_res->score, ms, rs);
"(%s: %c (default): [%.2f/%.2f] [",
(gchar *) metric_name, 'S', metric_res->score, ms);

}
}

+ 3
- 2
src/roll_history.c View File

@@ -127,8 +127,9 @@ rspamd_roll_history_update (struct roll_history *history, struct worker_task *ta
}
else {
row->score = metric_res->score;
row->required_score = metric_res->metric->required_score;
row->action = check_metric_action (metric_res->score, metric_res->metric->required_score, metric_res->metric);
row->required_score = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
row->action = check_metric_action (metric_res->score,
metric_res->metric->actions[METRIC_ACTION_REJECT].score, metric_res->metric);
cbdata.pos = row->symbols;
cbdata.remain = sizeof (row->symbols);
g_hash_table_foreach (metric_res->symbols, roll_history_symbols_callback, &cbdata);

+ 2
- 2
src/smtp_utils.c View File

@@ -146,8 +146,8 @@ smtp_metric_callback (gpointer key, gpointer value, gpointer ud)
task = cd->session->task;

if (!check_metric_settings (metric_res, &ms, &rs)) {
ms = metric_res->metric->required_score;
rs = metric_res->metric->reject_score;
ms = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
rs = metric_res->metric->actions[METRIC_ACTION_REJECT].score;
}
if (! check_metric_action_settings (task, metric_res, metric_res->score, &action)) {
action = check_metric_action (metric_res->score, ms, metric_res->metric);

+ 17
- 29
src/webui.c View File

@@ -364,9 +364,11 @@ http_scan_task_free (gpointer arg)
"\"required_score\":%.2f,"
"\"action\":\"%s\","
"\"symbols\":[",
mres->score >= mres->metric->required_score ? "true" : "false",
cbdata->task->is_skipped ? "true" : "false", mres->score, mres->metric->required_score,
str_action_metric (check_metric_action (mres->score, mres->metric->required_score, mres->metric)));
mres->score >= mres->metric->actions[METRIC_ACTION_REJECT].score ? "true" : "false",
cbdata->task->is_skipped ? "true" : "false", mres->score,
mres->metric->actions[METRIC_ACTION_REJECT].score,
str_action_metric (
check_metric_action (mres->score, mres->metric->actions[METRIC_ACTION_REJECT].score, mres->metric)));
/* Iterate all symbols */
g_hash_table_foreach (mres->symbols, http_scan_metric_symbols_callback, cbdata);
evbuffer_add (evb, "]}" CRLF, 4);
@@ -670,31 +672,15 @@ http_set_metric_action (struct config_file *cfg,
json_t *jv, struct metric *metric, enum rspamd_metric_action act)
{
gdouble actval;
GList *cur;
struct metric_action *act_found;

if (!json_is_number (jv)) {
msg_err ("json element data error");
return FALSE;
}
actval = json_number_value (jv);
if (metric->action == act && metric->required_score != actval) {
if (metric->actions[act].score != actval) {
return add_dynamic_action (cfg, DEFAULT_METRIC, act, actval);
}

/* Try to search in all metrics */
/* XXX: clarify this code, currently it looks like a crap */
cur = metric->actions;
while (cur) {
act_found = cur->data;
if (act_found->action == act) {
if (act_found->score != actval) {
return add_dynamic_action (cfg, DEFAULT_METRIC, act, actval);
}
}
cur = g_list_next (cur);
}

return TRUE;
}

@@ -838,8 +824,9 @@ http_handle_actions (struct evhttp_request *req, gpointer arg)
struct rspamd_webui_worker_ctx *ctx = arg;
struct evbuffer *evb;
struct metric *metric;
GList *cur;
struct metric_action *act;
gboolean start = TRUE;
gint i;

if (!http_check_password (ctx, req)) {
return;
@@ -858,15 +845,16 @@ http_handle_actions (struct evhttp_request *req, gpointer arg)
/* Get actions for default metric */
metric = g_hash_table_lookup (ctx->cfg->metrics, DEFAULT_METRIC);
if (metric != NULL) {

cur = metric->actions;
while (cur) {
act = cur->data;
cur = g_list_next (cur);
evbuffer_add_printf (evb, "{\"action\":\"%s\",\"value\":%.2f},", str_action_metric (act->action), act->score);
for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i ++) {
act = &metric->actions[i];
if (act->score > 0) {
evbuffer_add_printf (evb, "%s{\"action\":\"%s\",\"value\":%.2f}",
(start ? "" : ","), str_action_metric (act->action), act->score);
if (start) {
start = FALSE;
}
}
}
/* Print default action */
evbuffer_add_printf (evb, "{\"action\":\"%s\",\"value\":%.2f}", str_action_metric (metric->action), metric->required_score);
}

evbuffer_add (evb, "]" CRLF, 3);

Loading…
Cancel
Save