From d3d19ad641185f0fdb380705cb999e51dbbb5e50 Mon Sep 17 00:00:00 2001
From: Vsevolod Stakhov <vsevolod@highsecure.ru>
Date: Sat, 8 Dec 2018 13:32:18 +0000
Subject: [Feature] Core: allow to emit soft reject on task timeout

---
 src/libserver/cfg_file.h |  3 ++-
 src/libserver/cfg_rcl.c  |  6 ++++++
 src/worker.c             | 20 ++++++++++++++++++++
 3 files changed, 28 insertions(+), 1 deletion(-)

(limited to 'src')

diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h
index edc1258dc..6d6ed6f62 100644
--- a/src/libserver/cfg_file.h
+++ b/src/libserver/cfg_file.h
@@ -317,6 +317,7 @@ struct rspamd_config {
 	gboolean disable_pcre_jit;                      /**< Disable pcre JIT									*/
 	gboolean disable_lua_squeeze;                   /**< Disable lua rules squeezing						*/
 	gboolean own_lua_state;                         /**< True if we have created lua_state internally		*/
+	gboolean soft_reject_on_timeout;                /**< If true emit soft reject on task timeout (if not reject) */
 
 	gsize max_cores_size;                           /**< maximum size occupied by rspamd core files			*/
 	gsize max_cores_count;                          /**< maximum number of core files						*/
@@ -324,8 +325,8 @@ struct rspamd_config {
 	gsize max_message;                              /**< maximum size for messages							*/
 	gsize max_pic_size;                             /**< maximum size for a picture to process				*/
 	gsize images_cache_size;                        /**< size of LRU cache for DCT data from images			*/
-	gint default_max_shots;                         /**< default maximum count of symbols hits permitted (-1 for unlimited) */
 	gdouble task_timeout;                           /**< maximum message processing time					*/
+	gint default_max_shots;                         /**< default maximum count of symbols hits permitted (-1 for unlimited) */
 
 	enum rspamd_log_type log_type;                  /**< log type											*/
 	gint log_facility;                              /**< log facility in case of syslog						*/
diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c
index b9934929f..d6aadc03e 100644
--- a/src/libserver/cfg_rcl.c
+++ b/src/libserver/cfg_rcl.c
@@ -1984,6 +1984,12 @@ rspamd_rcl_config_init (struct rspamd_config *cfg, GHashTable *skip_sections)
 				G_STRUCT_OFFSET (struct rspamd_config, task_timeout),
 				RSPAMD_CL_FLAG_TIME_FLOAT,
 				"Maximum time for checking a message");
+		rspamd_rcl_add_default_handler (sub,
+				"soft_reject_on_timeout",
+				rspamd_rcl_parse_struct_boolean,
+				G_STRUCT_OFFSET (struct rspamd_config, soft_reject_on_timeout),
+				0,
+				"Emit soft reject if task timeout takes place");
 		rspamd_rcl_add_default_handler (sub,
 				"check_timeout",
 				rspamd_rcl_parse_struct_time,
diff --git a/src/worker.c b/src/worker.c
index 81c59a786..5147e0a2d 100644
--- a/src/worker.c
+++ b/src/worker.c
@@ -142,6 +142,26 @@ rspamd_task_timeout (gint fd, short what, gpointer ud)
 
 	if (!(task->processed_stages & RSPAMD_TASK_STAGE_FILTERS)) {
 		msg_info_task ("processing of task timed out, forced processing");
+
+		if (task->cfg->soft_reject_on_timeout) {
+			struct rspamd_metric_result *res = task->result;
+
+			if (rspamd_check_action_metric (task, res) != METRIC_ACTION_REJECT) {
+				rspamd_add_passthrough_result (task,
+						METRIC_ACTION_SOFT_REJECT,
+						0,
+						NAN,
+						"timeout processing message",
+						"task timeout");
+
+				ucl_object_replace_key (task->messages,
+						ucl_object_fromstring_common ("timeout processing message",
+								0, UCL_STRING_RAW),
+						"smtp_message", 0,
+						false);
+			}
+		}
+
 		task->processed_stages |= RSPAMD_TASK_STAGE_FILTERS;
 		rspamd_session_cleanup (task->s);
 		rspamd_task_process (task, RSPAMD_TASK_PROCESS_ALL);
-- 
cgit v1.2.3