From 65ae7ecb508095bbbcc2a3be464c4bc4fed3a9aa Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sat, 27 Feb 2016 13:19:03 +0000 Subject: [PATCH] [Minor] Implement workaround for legacy clients --- src/libserver/cfg_file.h | 1 + src/libserver/cfg_rcl.c | 6 ++++++ src/libserver/cfg_utils.c | 4 ++++ src/libserver/task.c | 4 ++++ src/libserver/task.h | 1 + src/worker.c | 16 ++++++++++++---- 6 files changed, 28 insertions(+), 4 deletions(-) diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h index 88b5b4538..17ca4f863 100644 --- a/src/libserver/cfg_file.h +++ b/src/libserver/cfg_file.h @@ -245,6 +245,7 @@ struct rspamd_config { gboolean check_all_filters; /**< check all filters */ gboolean allow_raw_input; /**< scan messages with invalid mime */ gboolean disable_hyperscan; /**< disable hyperscan usage */ + gboolean enable_shutdown_workaround; /**< enable workaround for legacy SA clients (exim) */ gsize max_diff; /**< maximum diff size for text parts */ gsize max_cores_size; /**< maximum size occupied by rspamd core files */ diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c index 559d0ee03..83b3dcada 100644 --- a/src/libserver/cfg_rcl.c +++ b/src/libserver/cfg_rcl.c @@ -1669,6 +1669,12 @@ rspamd_rcl_config_init (struct rspamd_config *cfg) G_STRUCT_OFFSET (struct rspamd_config, trusted_keys), RSPAMD_CL_FLAG_STRING_LIST_HASH, "List of trusted public keys used for signatures in base32 encoding"); + rspamd_rcl_add_default_handler (sub, + "enable_shutdown_workaround", + rspamd_rcl_parse_struct_boolean, + G_STRUCT_OFFSET (struct rspamd_config, enable_shutdown_workaround), + 0, + "Enable workaround for legacy clients"); /* New DNS configuration */ ssub = rspamd_rcl_add_section_doc (&sub->subsections, "dns", NULL, NULL, UCL_OBJECT, FALSE, TRUE, diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c index e87ba2a25..ea6894259 100644 --- a/src/libserver/cfg_utils.c +++ b/src/libserver/cfg_utils.c @@ -156,6 +156,10 @@ rspamd_config_new (void) cfg->ups_ctx = rspamd_upstreams_library_init (); cfg->re_cache = rspamd_re_cache_new (); cfg->doc_strings = ucl_object_typed_new (UCL_OBJECT); + /* + * Unless exim is fixed + */ + cfg->enable_shutdown_workaround = TRUE; REF_INIT_RETAIN (cfg, rspamd_config_free); diff --git a/src/libserver/task.c b/src/libserver/task.c index 1220dc4bc..cd80137d7 100644 --- a/src/libserver/task.c +++ b/src/libserver/task.c @@ -215,6 +215,10 @@ rspamd_task_free (struct rspamd_task *task) event_del (&task->timeout_ev); } + if (task->guard_ev) { + event_del (task->guard_ev); + } + rspamd_re_cache_runtime_destroy (task->re_rt); REF_RELEASE (task->cfg); diff --git a/src/libserver/task.h b/src/libserver/task.h index 44a71b289..749f3adc2 100644 --- a/src/libserver/task.h +++ b/src/libserver/task.h @@ -183,6 +183,7 @@ struct rspamd_task { struct rspamd_dns_resolver *resolver; /**< DNS resolver */ struct event_base *ev_base; /**< Event base */ struct event timeout_ev; /**< Global task timeout */ + struct event *guard_ev; /**< Event for input sanity guard */ gpointer checkpoint; /**< Opaque checkpoint data */ diff --git a/src/worker.c b/src/worker.c index 45ac2200e..bd54368a6 100644 --- a/src/worker.c +++ b/src/worker.c @@ -146,8 +146,17 @@ rspamd_worker_guard_handler (gint fd, short what, void *data) * reliable way to distinguish between shutdown(SHUT_WR) and * close. */ - msg_err_task ("the peer has closed connection unexpectedly"); - rspamd_session_destroy (task->s); + if (task->cfg->enable_shutdown_workaround) { + msg_info_task ("workaround for shutdown enabled, please update " + "your client, this support might be removed in future"); + shutdown (fd, SHUT_RD); + event_del (task->guard_ev); + task->guard_ev = NULL; + } + else { + msg_err_task ("the peer has closed connection unexpectedly"); + rspamd_session_destroy (task->s); + } } else if (errno != EAGAIN) { msg_err_task ("the peer has closed connection unexpectedly: %s", @@ -203,8 +212,7 @@ rspamd_worker_body_handler (struct rspamd_http_connection *conn, rspamd_worker_guard_handler, task); event_base_set (task->ev_base, guard_ev); event_add (guard_ev, NULL); - rspamd_mempool_add_destructor (task->task_pool, - (rspamd_mempool_destruct_t)event_del, guard_ev); + task->guard_ev = guard_ev; rspamd_task_process (task, RSPAMD_TASK_PROCESS_ALL); -- 2.39.5