aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/controller.c17
-rw-r--r--src/libmime/filter.c65
-rw-r--r--src/libmime/filter.h54
-rw-r--r--src/libmime/filter_private.h31
-rw-r--r--src/libmime/message.c27
-rw-r--r--src/libserver/cfg_file.h3
-rw-r--r--src/libserver/cfg_file_private.h2
-rw-r--r--src/libserver/cfg_utils.c21
-rw-r--r--src/libserver/events.c1
-rw-r--r--src/libserver/html.c2
-rw-r--r--src/libserver/protocol.c34
-rw-r--r--src/libserver/roll_history.c5
-rw-r--r--src/libserver/task.c30
-rw-r--r--src/lua/lua_task.c106
-rw-r--r--src/worker.c11
15 files changed, 255 insertions, 154 deletions
diff --git a/src/controller.c b/src/controller.c
index ee7e80e20..6a839b4df 100644
--- a/src/controller.c
+++ b/src/controller.c
@@ -15,6 +15,7 @@
*/
#include "config.h"
#include "libserver/dynamic_cfg.h"
+#include "libserver/cfg_file_private.h"
#include "libutil/rrd.h"
#include "libutil/map.h"
#include "libutil/map_helpers.h"
@@ -864,8 +865,7 @@ rspamd_controller_handle_actions (struct rspamd_http_connection_entry *conn_ent,
struct rspamd_http_message *msg)
{
struct rspamd_controller_session *session = conn_ent->ud;
- struct rspamd_action *act;
- gint i;
+ struct rspamd_action *act, *tmp;
ucl_object_t *obj, *top;
if (!rspamd_controller_check_password (conn_ent, session, msg, FALSE)) {
@@ -874,15 +874,14 @@ rspamd_controller_handle_actions (struct rspamd_http_connection_entry *conn_ent,
top = ucl_object_typed_new (UCL_ARRAY);
- /* Get actions for default metric */
- for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) {
- act = &session->cfg->actions[i];
+ HASH_ITER (hh, session->cfg->actions, act, tmp) {
obj = ucl_object_typed_new (UCL_OBJECT);
ucl_object_insert_key (obj,
- ucl_object_fromstring (rspamd_action_to_str (
- act->action)), "action", 0, false);
- ucl_object_insert_key (obj, ucl_object_fromdouble (
- act->threshold), "value", 0, false);
+ ucl_object_fromstring (act->name),
+ "action", 0, false);
+ ucl_object_insert_key (obj,
+ ucl_object_fromdouble (act->threshold),
+ "value", 0, false);
ucl_array_append (top, obj);
}
diff --git a/src/libmime/filter.c b/src/libmime/filter.c
index 2bda47fe7..46a0e5b92 100644
--- a/src/libmime/filter.c
+++ b/src/libmime/filter.c
@@ -19,6 +19,8 @@
#include "rspamd.h"
#include "message.h"
#include "lua/lua_common.h"
+#include "libserver/cfg_file_private.h"
+#include "libmime/filter_private.h"
#include <math.h>
#include "contrib/uthash/utlist.h"
@@ -70,14 +72,22 @@ rspamd_create_metric_result (struct rspamd_task *task)
}
if (task->cfg) {
- for (i = 0; i < METRIC_ACTION_MAX; i++) {
- metric_res->actions_limits[i] = task->cfg->actions[i].threshold;
- }
- }
- else {
- for (i = 0; i < METRIC_ACTION_MAX; i++) {
- metric_res->actions_limits[i] = NAN;
+ struct rspamd_action *act, *tmp;
+
+ metric_res->actions_limits = rspamd_mempool_alloc0 (task->task_pool,
+ sizeof (struct rspamd_action_result) * HASH_COUNT (task->cfg->actions));
+ i = 0;
+
+ HASH_ITER (hh, task->cfg->actions, act, tmp) {
+ if (!(act->flags & RSPAMD_ACTION_NO_THRESHOLD)) {
+ metric_res->actions_limits[i].cur_limit = act->threshold;
+ }
+ metric_res->actions_limits[i].action = act;
+
+ i ++;
}
+
+ metric_res->nactions = i;
}
rspamd_mempool_add_destructor (task->task_pool,
@@ -96,7 +106,7 @@ rspamd_pr_sort (const struct rspamd_passthrough_result *pra,
void
rspamd_add_passthrough_result (struct rspamd_task *task,
- enum rspamd_action_type action,
+ struct rspamd_action *action,
guint priority,
double target_score,
const gchar *message,
@@ -119,13 +129,13 @@ rspamd_add_passthrough_result (struct rspamd_task *task,
if (!isnan (target_score)) {
msg_info_task ("<%s>: set pre-result to %s (%.2f): '%s' from %s(%d)",
- task->message_id, rspamd_action_to_str (action), target_score,
+ task->message_id, action->name, target_score,
message, module, priority);
}
else {
msg_info_task ("<%s>: set pre-result to %s (no score): '%s' from %s(%d)",
- task->message_id, rspamd_action_to_str (action),
+ task->message_id, action->name,
message, module, priority);
}
}
@@ -475,43 +485,50 @@ rspamd_task_add_result_option (struct rspamd_task *task,
return ret;
}
-enum rspamd_action_type
-rspamd_check_action_metric (struct rspamd_task *task, struct rspamd_metric_result *mres)
+struct rspamd_action*
+rspamd_check_action_metric (struct rspamd_task *task)
{
- struct rspamd_action *action, *selected_action = NULL;
+ struct rspamd_action_result *action_lim,
+ *noaction = NULL;
+ struct rspamd_action *selected_action = NULL;
struct rspamd_passthrough_result *pr;
double max_score = -(G_MAXDOUBLE), sc;
int i;
gboolean set_action = FALSE;
+ struct rspamd_metric_result *mres = task->result;
/* We are not certain about the results during processing */
- if (task->result->passthrough_result == NULL) {
- for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_MAX; i++) {
- action = &task->cfg->actions[i];
- sc = mres->actions_limits[i];
+ if (mres->passthrough_result == NULL) {
+ for (i = 0; i < mres->nactions; i++) {
+ action_lim = &mres->actions_limits[i];
+ sc = action_lim->cur_limit;
+
+ if (action_lim->action->action_type == METRIC_ACTION_NOACTION) {
+ noaction = action_lim;
+ }
if (isnan (sc)) {
continue;
}
if (mres->score >= sc && sc > max_score) {
- selected_action = action;
+ selected_action = action_lim->action;
max_score = sc;
}
}
if (set_action && selected_action == NULL) {
- selected_action = &task->cfg->actions[METRIC_ACTION_NOACTION];
+ selected_action = noaction->action;
}
}
else {
/* Peek the highest priority result */
- pr = task->result->passthrough_result;
+ pr = mres->passthrough_result;
sc = pr->target_score;
- selected_action = &task->cfg->actions[pr->action];
+ selected_action = pr->action;
if (!isnan (sc)) {
- if (pr->action == METRIC_ACTION_NOACTION) {
+ if (pr->action->action_type == METRIC_ACTION_NOACTION) {
mres->score = MIN (sc, mres->score);
}
else {
@@ -521,10 +538,10 @@ rspamd_check_action_metric (struct rspamd_task *task, struct rspamd_metric_resul
}
if (selected_action) {
- return selected_action->action;
+ return selected_action;
}
- return METRIC_ACTION_NOACTION;
+ return noaction ? noaction->action : NULL;
}
struct rspamd_symbol_result*
diff --git a/src/libmime/filter.h b/src/libmime/filter.h
index 73f8269fa..7ee0f1163 100644
--- a/src/libmime/filter.h
+++ b/src/libmime/filter.h
@@ -9,7 +9,6 @@
#include "config.h"
#include "rspamd_symcache.h"
#include "task.h"
-#include "khash.h"
struct rspamd_task;
struct rspamd_settings;
@@ -25,14 +24,14 @@ enum rspamd_symbol_result_flags {
RSPAMD_SYMBOL_RESULT_IGNORED = (1 << 0)
};
+struct kh_rspamd_options_hash_s;
+
/**
* Rspamd symbol
*/
-
-KHASH_MAP_INIT_STR (rspamd_options_hash, struct rspamd_symbol_option *);
struct rspamd_symbol_result {
double score; /**< symbol's score */
- khash_t(rspamd_options_hash) *options; /**< list of symbol's options */
+ struct kh_rspamd_options_hash_s *options; /**< list of symbol's options */
struct rspamd_symbol_option *opts_head; /**< head of linked list of options */
const gchar *name;
struct rspamd_symbol *sym; /**< symbol configuration */
@@ -40,24 +39,6 @@ struct rspamd_symbol_result {
enum rspamd_symbol_result_flags flags;
};
-/**
- * Result of metric processing
- */
-KHASH_MAP_INIT_STR (rspamd_symbols_hash, struct rspamd_symbol_result);
-#if UINTPTR_MAX <= UINT_MAX
-/* 32 bit */
-#define rspamd_ptr_hash_func(key) (khint32_t)(((uintptr_t)(key))>>1)
-#else
-/* likely 64 bit */
-#define rspamd_ptr_hash_func(key) (khint32_t)(((uintptr_t)(key))>>3)
-#endif
-#define rspamd_ptr_equal_func(a, b) ((a) == (b))
-KHASH_INIT (rspamd_symbols_group_hash,
- void *,
- double,
- 1,
- rspamd_ptr_hash_func,
- rspamd_ptr_equal_func);
#define RSPAMD_PASSTHROUGH_NORMAL 1
#define RSPAMD_PASSTHROUGH_LOW 0
@@ -65,7 +46,7 @@ KHASH_INIT (rspamd_symbols_group_hash,
#define RSPAMD_PASSTHROUGH_CRITICAL 3
struct rspamd_passthrough_result {
- enum rspamd_action_type action;
+ struct rspamd_action *action;
guint priority;
double target_score;
const gchar *message;
@@ -73,6 +54,15 @@ struct rspamd_passthrough_result {
struct rspamd_passthrough_result *prev, *next;
};
+struct rspamd_action_result {
+ gdouble cur_limit;
+ struct rspamd_action *action;
+};
+
+struct kh_rspamd_symbols_hash_s;
+struct kh_rspamd_symbols_group_hash_s;
+
+
struct rspamd_metric_result {
double score; /**< total score */
double grow_factor; /**< current grow factor */
@@ -81,9 +71,10 @@ struct rspamd_metric_result {
guint nnegative;
double positive_score;
double negative_score;
- khash_t(rspamd_symbols_hash) *symbols; /**< symbols of metric */
- khash_t(rspamd_symbols_group_hash) *sym_groups; /**< groups of symbols */
- gdouble actions_limits[METRIC_ACTION_MAX]; /**< set of actions for this metric */
+ struct kh_rspamd_symbols_hash_s *symbols; /**< symbols of metric */
+ struct kh_rspamd_symbols_group_hash_s *sym_groups; /**< groups of symbols */
+ struct rspamd_action_result *actions_limits;
+ guint nactions;
};
/**
@@ -103,7 +94,7 @@ struct rspamd_metric_result * rspamd_create_metric_result (struct rspamd_task *t
* @param module
*/
void rspamd_add_passthrough_result (struct rspamd_task *task,
- enum rspamd_action_type action,
+ struct rspamd_action *action,
guint priority,
double target_score,
const gchar *message,
@@ -175,10 +166,11 @@ double rspamd_factor_consolidation_func (struct rspamd_task *task,
const gchar *unused);
-/*
- * Get action for specific metric
+/**
+ * Check thresholds and return action for a task
+ * @param task
+ * @return
*/
-enum rspamd_action_type rspamd_check_action_metric (struct rspamd_task *task,
- struct rspamd_metric_result *mres);
+struct rspamd_action* rspamd_check_action_metric (struct rspamd_task *task);
#endif
diff --git a/src/libmime/filter_private.h b/src/libmime/filter_private.h
new file mode 100644
index 000000000..82322a6bb
--- /dev/null
+++ b/src/libmime/filter_private.h
@@ -0,0 +1,31 @@
+//
+// Created by Vsevolod Stakhov on 2019-01-14.
+//
+
+#ifndef RSPAMD_FILTER_PRIVATE_H
+#define RSPAMD_FILTER_PRIVATE_H
+
+#include "filter.h"
+#include "contrib/libucl/khash.h"
+
+KHASH_MAP_INIT_STR (rspamd_options_hash, struct rspamd_symbol_option *);
+/**
+ * Result of metric processing
+ */
+KHASH_MAP_INIT_STR (rspamd_symbols_hash, struct rspamd_symbol_result);
+#if UINTPTR_MAX <= UINT_MAX
+/* 32 bit */
+#define rspamd_ptr_hash_func(key) (khint32_t)(((uintptr_t)(key))>>1)
+#else
+/* likely 64 bit */
+#define rspamd_ptr_hash_func(key) (khint32_t)(((uintptr_t)(key))>>3)
+#endif
+#define rspamd_ptr_equal_func(a, b) ((a) == (b))
+KHASH_INIT (rspamd_symbols_group_hash,
+ void *,
+ double,
+ 1,
+ rspamd_ptr_hash_func,
+ rspamd_ptr_equal_func);
+
+#endif //RSPAMD_FILTER_PRIVATE_H
diff --git a/src/libmime/message.c b/src/libmime/message.c
index a07cb6c8d..cb85a512b 100644
--- a/src/libmime/message.c
+++ b/src/libmime/message.c
@@ -34,6 +34,7 @@
#include <math.h>
#include <unicode/uchar.h>
+#include <src/libserver/cfg_file_private.h>
#define GTUBE_SYMBOL "GTUBE"
@@ -883,23 +884,23 @@ rspamd_message_process_text_part_maybe (struct rspamd_task *task,
act = rspamd_check_gtube (task, text_part);
if (act != METRIC_ACTION_NOACTION) {
- struct rspamd_metric_result *mres = task->result;
+ struct rspamd_action *action;
gdouble score = NAN;
- if (act == METRIC_ACTION_REJECT) {
- score = rspamd_task_get_required_score (task, mres);
- }
- else {
- score = mres->actions_limits[act];
- }
+ action = rspamd_config_get_action_by_type (task->cfg, act);
- rspamd_add_passthrough_result (task, act, RSPAMD_PASSTHROUGH_CRITICAL,
- score, "Gtube pattern", "GTUBE");
+ if (action) {
+ score = action->threshold;
- if (ucl_object_lookup (task->messages, "smtp_message") == NULL) {
- ucl_object_replace_key (task->messages,
- ucl_object_fromstring ("Gtube pattern"), "smtp_message", 0,
- false);
+ rspamd_add_passthrough_result (task, action,
+ RSPAMD_PASSTHROUGH_CRITICAL,
+ score, "Gtube pattern", "GTUBE");
+
+ if (ucl_object_lookup (task->messages, "smtp_message") == NULL) {
+ ucl_object_replace_key (task->messages,
+ ucl_object_fromstring ("Gtube pattern"),
+ "smtp_message", 0, false);
+ }
}
rspamd_task_insert_result (task, GTUBE_SYMBOL, 0, NULL);
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h
index 0557f4487..5c245a31b 100644
--- a/src/libserver/cfg_file.h
+++ b/src/libserver/cfg_file.h
@@ -708,6 +708,9 @@ gboolean rspamd_config_radix_from_ucl (struct rspamd_config *cfg,
struct rspamd_action * rspamd_config_get_action (struct rspamd_config *cfg,
const gchar *name);
+struct rspamd_action * rspamd_config_get_action_by_type (struct rspamd_config *cfg,
+ enum rspamd_action_type type);
+
#define msg_err_config(...) rspamd_default_log_function (G_LOG_LEVEL_CRITICAL, \
cfg->cfg_pool->tag.tagname, cfg->checksum, \
G_STRFUNC, \
diff --git a/src/libserver/cfg_file_private.h b/src/libserver/cfg_file_private.h
index 03f735efe..94cb9aa08 100644
--- a/src/libserver/cfg_file_private.h
+++ b/src/libserver/cfg_file_private.h
@@ -26,7 +26,7 @@
* Action config definition
*/
struct rspamd_action {
- enum rspamd_action_type action;
+ enum rspamd_action_type action_type;
enum rspamd_action_flags flags;
guint priority;
gint lua_handler_ref; /* If special handling is needed */
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c
index 1ab2ff054..26bf4e4b0 100644
--- a/src/libserver/cfg_utils.c
+++ b/src/libserver/cfg_utils.c
@@ -141,7 +141,7 @@ rspamd_config_new (enum rspamd_config_init_flags flags)
action->threshold = NAN;
action->name = rspamd_mempool_strdup (cfg->cfg_pool,
rspamd_action_to_str (i));
- action->action = i;
+ action->action_type = i;
if (i == METRIC_ACTION_SOFT_REJECT) {
action->flags |= RSPAMD_ACTION_NO_THRESHOLD;
@@ -1946,10 +1946,10 @@ rspamd_config_action_from_ucl (struct rspamd_config *cfg,
act->flags = flags;
if (rspamd_action_from_str (act->name, &std_act)) {
- act->action = std_act;
+ act->action_type = std_act;
}
else {
- act->action = METRIC_ACTION_CUSTOM;
+ act->action_type = METRIC_ACTION_CUSTOM;
}
rspamd_actions_sort (cfg);
@@ -2060,6 +2060,21 @@ rspamd_config_get_action (struct rspamd_config *cfg, const gchar *name)
return res;
}
+struct rspamd_action *
+rspamd_config_get_action_by_type (struct rspamd_config *cfg,
+ enum rspamd_action_type type)
+{
+ struct rspamd_action *cur, *tmp;
+
+ HASH_ITER (hh, cfg->actions, cur, tmp) {
+ if (cur->action_type == type) {
+ return cur;
+ }
+ }
+
+ return NULL;
+}
+
gboolean
rspamd_config_radix_from_ucl (struct rspamd_config *cfg,
const ucl_object_t *obj,
diff --git a/src/libserver/events.c b/src/libserver/events.c
index 2fd0c55ff..3f6d47112 100644
--- a/src/libserver/events.c
+++ b/src/libserver/events.c
@@ -16,6 +16,7 @@
#include "config.h"
#include "rspamd.h"
#include "contrib/uthash/utlist.h"
+#include "contrib/libucl/khash.h"
#include "events.h"
#include "cryptobox.h"
diff --git a/src/libserver/html.c b/src/libserver/html.c
index 2568d4c2a..8ebb3862e 100644
--- a/src/libserver/html.c
+++ b/src/libserver/html.c
@@ -22,6 +22,8 @@
#include "html_colors.h"
#include "html_entities.h"
#include "url.h"
+#include "contrib/libucl/khash.h"
+
#include <unicode/uversion.h>
#include <unicode/ucnv.h>
#if U_ICU_VERSION_MAJOR_NUM >= 46
diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c
index 35463be52..713c54499 100644
--- a/src/libserver/protocol.c
+++ b/src/libserver/protocol.c
@@ -19,6 +19,8 @@
#include "utlist.h"
#include "http_private.h"
#include "worker_private.h"
+#include "libserver/cfg_file_private.h"
+#include "libmime/filter_private.h"
#include "contrib/zstd/zstd.h"
#include "lua/lua_common.h"
#include "unix-std.h"
@@ -922,12 +924,12 @@ rspamd_metric_result_ucl (struct rspamd_task *task,
{
struct rspamd_symbol_result *sym;
gboolean is_spam;
- enum rspamd_action_type action = METRIC_ACTION_NOACTION;
+ struct rspamd_action *action;
ucl_object_t *obj = NULL, *sobj;
const gchar *subject;
- action = rspamd_check_action_metric (task, mres);
- is_spam = (action < METRIC_ACTION_GREYLIST);
+ action = rspamd_check_action_metric (task);
+ is_spam = !(action->flags & RSPAMD_ACTION_HAM);
if (task->cmd != CMD_CHECK_V2) {
obj = ucl_object_typed_new (UCL_OBJECT);
@@ -955,10 +957,10 @@ rspamd_metric_result_ucl (struct rspamd_task *task,
ucl_object_fromdouble (rspamd_task_get_required_score (task, mres)),
"required_score", 0, false);
ucl_object_insert_key (obj,
- ucl_object_fromstring (rspamd_action_to_str (action)),
+ ucl_object_fromstring (action->name),
"action", 0, false);
- if (action == METRIC_ACTION_REWRITE_SUBJECT) {
+ if (action->action_type == METRIC_ACTION_REWRITE_SUBJECT) {
subject = rspamd_protocol_rewrite_subject (task);
if (subject) {
@@ -1253,7 +1255,8 @@ rspamd_protocol_http_reply (struct rspamd_http_message *msg,
gpointer h, v;
ucl_object_t *top = NULL;
rspamd_fstring_t *reply;
- gint action, flags = RSPAMD_PROTOCOL_DEFAULT;
+ gint flags = RSPAMD_PROTOCOL_DEFAULT;
+ struct rspamd_action *action;
/* Write custom headers */
g_hash_table_iter_init (&hiter, task->reply_headers);
@@ -1376,19 +1379,24 @@ end:
if (metric_res != NULL) {
- action = rspamd_check_action_metric (task, metric_res);
+ action = rspamd_check_action_metric (task);
- if (action == METRIC_ACTION_SOFT_REJECT &&
+ /* TODO: handle custom actions in stats */
+ if (action->action_type == METRIC_ACTION_SOFT_REJECT &&
(task->flags & RSPAMD_TASK_FLAG_GREYLISTED)) {
/* Set stat action to greylist to display greylisted messages */
- action = METRIC_ACTION_GREYLIST;
+#ifndef HAVE_ATOMIC_BUILTINS
+ task->worker->srv->stat->actions_stat[METRIC_ACTION_GREYLIST]++;
+#else
+ __atomic_add_fetch (&task->worker->srv->stat->actions_stat[METRIC_ACTION_GREYLIST],
+ 1, __ATOMIC_RELEASE);
+#endif
}
-
- if (action < METRIC_ACTION_MAX) {
+ else if (action->action_type < METRIC_ACTION_MAX) {
#ifndef HAVE_ATOMIC_BUILTINS
- task->worker->srv->stat->actions_stat[action]++;
+ task->worker->srv->stat->actions_stat[action->action_type]++;
#else
- __atomic_add_fetch (&task->worker->srv->stat->actions_stat[action],
+ __atomic_add_fetch (&task->worker->srv->stat->actions_stat[action->action_type],
1, __ATOMIC_RELEASE);
#endif
}
diff --git a/src/libserver/roll_history.c b/src/libserver/roll_history.c
index 3df597816..c9367409d 100644
--- a/src/libserver/roll_history.c
+++ b/src/libserver/roll_history.c
@@ -17,6 +17,7 @@
#include "rspamd.h"
#include "lua/lua_common.h"
#include "unix-std.h"
+#include "cfg_file_private.h"
static const gchar rspamd_history_magic_old[] = {'r', 's', 'h', '1'};
@@ -101,6 +102,7 @@ rspamd_roll_history_update (struct roll_history *history,
struct roll_history_row *row;
struct rspamd_metric_result *metric_res;
struct history_metric_callback_data cbdata;
+ struct rspamd_action *action;
if (history->disabled) {
return;
@@ -155,7 +157,8 @@ rspamd_roll_history_update (struct roll_history *history,
}
else {
row->score = metric_res->score;
- row->action = rspamd_check_action_metric (task, metric_res);
+ action = rspamd_check_action_metric (task);
+ row->action = action->action_type;
row->required_score = rspamd_task_get_required_score (task, metric_res);
cbdata.pos = row->symbols;
cbdata.remain = sizeof (row->symbols);
diff --git a/src/libserver/task.c b/src/libserver/task.c
index eaa379361..df1a561cb 100644
--- a/src/libserver/task.c
+++ b/src/libserver/task.c
@@ -26,7 +26,10 @@
#include "utlist.h"
#include "contrib/zstd/zstd.h"
#include "libserver/mempool_vars_internal.h"
+#include "libserver/cfg_file_private.h"
#include "libmime/lang_detection.h"
+#include "libmime/filter_private.h"
+
#include <math.h>
/*
@@ -1072,11 +1075,11 @@ rspamd_task_log_metric_res (struct rspamd_task *task,
rspamd_fstring_t *symbuf;
struct rspamd_symbol_result *sym;
GPtrArray *sorted_symbols;
- enum rspamd_action_type act;
+ struct rspamd_action *act;
guint i, j;
mres = task->result;
- act = rspamd_check_action_metric (task, mres);
+ act = rspamd_check_action_metric (task);
if (mres != NULL) {
switch (lf->type) {
@@ -1084,7 +1087,7 @@ rspamd_task_log_metric_res (struct rspamd_task *task,
if (RSPAMD_TASK_IS_SKIPPED (task)) {
res.begin = "S";
}
- else if (act == METRIC_ACTION_REJECT) {
+ else if (!(act->flags & RSPAMD_ACTION_HAM)) {
res.begin = "T";
}
else {
@@ -1094,7 +1097,7 @@ rspamd_task_log_metric_res (struct rspamd_task *task,
res.len = 1;
break;
case RSPAMD_LOG_ACTION:
- res.begin = rspamd_action_to_str (act);
+ res.begin = act->name;
res.len = strlen (res.begin);
break;
case RSPAMD_LOG_SCORES:
@@ -1441,14 +1444,17 @@ rspamd_task_log_variable (struct rspamd_task *task,
if (!isnan (pr->target_score)) {
var.len = rspamd_snprintf (numbuf, sizeof (numbuf),
"%s \"%s\"; score=%.2f (set by %s)",
- rspamd_action_to_str (pr->action),
- pr->message, pr->target_score, pr->module);
+ pr->action->name,
+ pr->message,
+ pr->target_score,
+ pr->module);
}
else {
var.len = rspamd_snprintf (numbuf, sizeof (numbuf),
"%s \"%s\"; score=nan (set by %s)",
- rspamd_action_to_str (pr->action),
- pr->message, pr->module);
+ pr->action->name,
+ pr->message,
+ pr->module);
}
var.begin = numbuf;
}
@@ -1536,7 +1542,7 @@ rspamd_task_write_log (struct rspamd_task *task)
gdouble
rspamd_task_get_required_score (struct rspamd_task *task, struct rspamd_metric_result *m)
{
- guint i;
+ gint i;
if (m == NULL) {
m = task->result;
@@ -1546,9 +1552,9 @@ rspamd_task_get_required_score (struct rspamd_task *task, struct rspamd_metric_r
}
}
- for (i = METRIC_ACTION_REJECT; i < METRIC_ACTION_NOACTION; i ++) {
- if (!isnan (m->actions_limits[i])) {
- return m->actions_limits[i];
+ for (i = m->nactions - 1; i >= 0; i --) {
+ if (!isnan (m->actions_limits[i].cur_limit)) {
+ return m->actions_limits[i].cur_limit;
}
}
diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c
index 00e819f32..5728b3342 100644
--- a/src/lua/lua_task.c
+++ b/src/lua/lua_task.c
@@ -23,6 +23,8 @@
#include "libserver/mempool_vars_internal.h"
#include "libserver/dkim.h"
#include "libserver/task.h"
+#include "libserver/cfg_file_private.h"
+#include "libmime/filter_private.h"
#include "libstat/stat_api.h"
#include "libutil/map_helpers.h"
@@ -1653,7 +1655,7 @@ lua_task_set_pre_result (lua_State * L)
struct rspamd_task *task = lua_check_task (L, 1);
const gchar *message = NULL, *module = NULL;
gdouble score = NAN;
- gint action = METRIC_ACTION_MAX;
+ struct rspamd_action *action;
guint priority = RSPAMD_PASSTHROUGH_NORMAL;
if (task != NULL) {
@@ -1663,11 +1665,15 @@ lua_task_set_pre_result (lua_State * L)
return 0;
}
- if (lua_type (L, 2) == LUA_TNUMBER) {
- action = lua_tointeger (L, 2);
+ if (lua_type (L, 2) == LUA_TSTRING) {
+ action = rspamd_config_get_action (task->cfg, lua_tostring (L, 2));
}
- else if (lua_type (L, 2) == LUA_TSTRING) {
- rspamd_action_from_str (lua_tostring (L, 2), &action);
+ else {
+ return luaL_error (L, "invalid arguments");
+ }
+
+ if (action == NULL) {
+ return luaL_error (L, "unknown action %s", lua_tostring (L, 2));
}
if (lua_type (L, 3) == LUA_TSTRING) {
@@ -1698,21 +1704,16 @@ lua_task_set_pre_result (lua_State * L)
priority = lua_tonumber (L, 6);
}
- if (action < METRIC_ACTION_MAX && action >= METRIC_ACTION_REJECT) {
- rspamd_add_passthrough_result (task, action, priority,
- score, rspamd_mempool_strdup (task->task_pool, message),
- rspamd_mempool_strdup (task->task_pool, module));
+ rspamd_add_passthrough_result (task, action, priority,
+ score, rspamd_mempool_strdup (task->task_pool, message),
+ rspamd_mempool_strdup (task->task_pool, module));
- /* Don't classify or filter message if pre-filter sets results */
- task->processed_stages |= (RSPAMD_TASK_STAGE_FILTERS |
- RSPAMD_TASK_STAGE_CLASSIFIERS |
- RSPAMD_TASK_STAGE_CLASSIFIERS_PRE |
- RSPAMD_TASK_STAGE_CLASSIFIERS_POST);
- }
- else {
- return luaL_error (L, "invalid arguments");
- }
+ /* Don't classify or filter message if pre-filter sets results */
+ task->processed_stages |= (RSPAMD_TASK_STAGE_FILTERS |
+ RSPAMD_TASK_STAGE_CLASSIFIERS |
+ RSPAMD_TASK_STAGE_CLASSIFIERS_PRE |
+ RSPAMD_TASK_STAGE_CLASSIFIERS_POST);
}
else {
return luaL_error (L, "invalid arguments");
@@ -4360,20 +4361,23 @@ lua_task_set_settings (lua_State *L)
/* Adjust desired actions */
mres = task->result;
- for (i = 0; i < METRIC_ACTION_MAX; i++) {
- elt = ucl_object_lookup_any (act, rspamd_action_to_str (i),
- rspamd_action_to_str_alt (i), NULL);
+ for (i = 0; i < mres->nactions; i++) {
+ struct rspamd_action_result *act_res = &mres->actions_limits[i];
+ elt = ucl_object_lookup (act, act_res->action->name);
if (elt) {
-
if (ucl_object_type (elt) == UCL_FLOAT ||
ucl_object_type (elt) == UCL_INT) {
- mres->actions_limits[i] = ucl_object_todouble (elt);
- msg_debug_task ("adjusted action %s to %.2f",
- ucl_object_key (elt), mres->actions_limits[i]);
+ gdouble nscore = ucl_object_todouble (elt);
+
+ msg_debug_task ("adjusted action %s: %.2f -> %.2f",
+ ucl_object_key (elt),
+ act_res->cur_limit,
+ nscore);
+ act_res->cur_limit = nscore;
}
else if (ucl_object_type (elt) == UCL_NULL) {
- mres->actions_limits[i] = NAN;
+ act_res->cur_limit = NAN;
msg_info_task ("disabled action %s due to settings",
ucl_object_key (elt));
}
@@ -4384,6 +4388,8 @@ lua_task_set_settings (lua_State *L)
vars = ucl_object_lookup (task->settings, "variables");
if (vars && ucl_object_type (vars) == UCL_OBJECT) {
/* Set memory pool variables */
+ it = NULL;
+
while ((cur = ucl_object_iterate (vars, &it, true)) != NULL) {
if (ucl_object_type (cur) == UCL_STRING) {
rspamd_mempool_set_variable (task->task_pool,
@@ -4741,6 +4747,7 @@ lua_task_get_metric_result (lua_State *L)
LUA_TRACE_POINT;
struct rspamd_task *task = lua_check_task (L, 1);
struct rspamd_metric_result *metric_res;
+ struct rspamd_action *action;
if (task) {
metric_res = task->result;
@@ -4760,10 +4767,13 @@ lua_task_get_metric_result (lua_State *L)
lua_pushnumber (L, metric_res->score);
lua_settable (L, -3);
- lua_pushstring (L, "action");
- lua_pushstring (L, rspamd_action_to_str (
- rspamd_check_action_metric (task, metric_res)));
- lua_settable (L, -3);
+ action = rspamd_check_action_metric (task);
+
+ if (action) {
+ lua_pushstring (L, "action");
+ lua_pushstring (L, action->name);
+ lua_settable (L, -3);
+ }
lua_pushstring (L, "nnegative");
lua_pushnumber (L, metric_res->nnegative);
@@ -4826,13 +4836,13 @@ lua_task_get_metric_action (lua_State *L)
LUA_TRACE_POINT;
struct rspamd_task *task = lua_check_task (L, 1);
struct rspamd_metric_result *metric_res;
- enum rspamd_action_type action;
+ struct rspamd_action *action;
if (task) {
metric_res = task->result;
- action = rspamd_check_action_metric (task, metric_res);
- lua_pushstring (L, rspamd_action_to_str (action));
+ action = rspamd_check_action_metric (task);
+ lua_pushstring (L, action->name);
}
else {
return luaL_error (L, "invalid arguments");
@@ -4880,21 +4890,29 @@ lua_task_disable_action (lua_State *L)
LUA_TRACE_POINT;
struct rspamd_task *task = lua_check_task (L, 1);
const gchar *action_name;
- gint action;
+ struct rspamd_action_result *action_res;
action_name = luaL_checkstring (L, 2);
- if (task && action_name && rspamd_action_from_str (action_name, &action)) {
- if (!task->result) {
- task->result = rspamd_create_metric_result (task);
- }
- if (isnan (task->result->actions_limits[action])) {
- lua_pushboolean (L, false);
- }
- else {
- task->result->actions_limits[action] = NAN;
- lua_pushboolean (L, true);
+ if (task && action_name) {
+
+ for (guint i = 0; i < task->result->nactions; i ++) {
+ action_res = &task->result->actions_limits[i];
+
+ if (strcmp (action_name, action_res->action->name) == 0) {
+ if (isnan (action_res->cur_limit)) {
+ lua_pushboolean (L, false);
+ }
+ else {
+ action_res->cur_limit = NAN;
+ lua_pushboolean (L, true);
+ }
+
+ break;
+ }
}
+
+
}
else {
return luaL_error (L, "invalid arguments");
diff --git a/src/worker.c b/src/worker.c
index 5147e0a2d..2f7176a8d 100644
--- a/src/worker.c
+++ b/src/worker.c
@@ -36,6 +36,7 @@
#include "libutil/http_private.h"
#include "libmime/lang_detection.h"
#include <math.h>
+#include <src/libserver/cfg_file_private.h>
#include "unix-std.h"
#include "lua/lua_common.h"
@@ -144,11 +145,15 @@ rspamd_task_timeout (gint fd, short what, gpointer ud)
msg_info_task ("processing of task timed out, forced processing");
if (task->cfg->soft_reject_on_timeout) {
- struct rspamd_metric_result *res = task->result;
+ struct rspamd_action *action, *soft_reject;
- if (rspamd_check_action_metric (task, res) != METRIC_ACTION_REJECT) {
+ action = rspamd_check_action_metric (task);
+
+ if (action->action_type != METRIC_ACTION_REJECT) {
+ soft_reject = rspamd_config_get_action_by_type (task->cfg,
+ METRIC_ACTION_SOFT_REJECT);
rspamd_add_passthrough_result (task,
- METRIC_ACTION_SOFT_REJECT,
+ soft_reject,
0,
NAN,
"timeout processing message",