diff options
-rw-r--r-- | src/CMakeLists.txt | 4 | ||||
-rw-r--r-- | src/fuzzy_storage.c | 1 | ||||
-rw-r--r-- | src/hs_helper.c | 154 | ||||
-rw-r--r-- | src/libserver/rspamd_control.c | 13 | ||||
-rw-r--r-- | src/libserver/rspamd_control.h | 7 | ||||
-rw-r--r-- | src/rspamadm/CMakeLists.txt | 5 |
6 files changed, 182 insertions, 2 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index acc91b673..fc85428ca 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -94,6 +94,10 @@ SET(PLUGINSSRC plugins/surbl.c SET(MODULES_LIST surbl regexp chartable fuzzy_check spf dkim) SET(WORKERS_LIST normal controller smtp_proxy fuzzy lua http_proxy) +IF (ENABLE_HYPERSCAN MATCHES "ON") + LIST(APPEND WORKERS_LIST "hs_helper") + LIST(APPEND RSPAMDSRC "hs_helper.c") +ENDIF() AddModules(MODULES_LIST WORKERS_LIST) LIST(LENGTH PLUGINSSRC RSPAMD_MODULES_NUM) diff --git a/src/fuzzy_storage.c b/src/fuzzy_storage.c index 40862dd1a..0acc7e4e0 100644 --- a/src/fuzzy_storage.c +++ b/src/fuzzy_storage.c @@ -26,7 +26,6 @@ * Rspamd fuzzy storage server */ -#include <libserver/rspamd_control.h> #include "config.h" #include "util.h" #include "rspamd.h" diff --git a/src/hs_helper.c b/src/hs_helper.c new file mode 100644 index 000000000..6bc9c3d18 --- /dev/null +++ b/src/hs_helper.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2015, Vsevolod Stakhov + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY AUTHOR ''AS IS'' AND ANY + * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include "config.h" +#include "libutil/util.h" +#include "libserver/cfg_file.h" +#include "libserver/cfg_rcl.h" +#include "libserver/worker_util.h" +#include "libserver/rspamd_control.h" +#include "unix-std.h" + +#ifdef HAVE_GLOB_H +#include <glob.h> +#endif + +static gpointer init_hs_helper (struct rspamd_config *cfg); +static void start_hs_helper (struct rspamd_worker *worker); + +worker_t hs_helper_worker = { + "hs_helper", /* Name */ + init_hs_helper, /* Init function */ + start_hs_helper, /* Start function */ + FALSE, /* No socket */ + FALSE, /* Unique */ + FALSE, /* Non threaded */ + TRUE, /* Killable */ + SOCK_STREAM /* TCP socket */ +}; + +/* + * Worker's context + */ +struct hs_helper_ctx { + const gchar *hs_dir; + struct rspamd_config *cfg; + struct event_base *ev_base; +}; + +static gpointer +init_hs_helper (struct rspamd_config *cfg) +{ + struct hs_helper_ctx *ctx; + GQuark type; + + type = g_quark_try_string ("hs_helper"); + ctx = g_malloc0 (sizeof (*ctx)); + + ctx->cfg = cfg; + ctx->hs_dir = RSPAMD_DBDIR "/"; + + rspamd_rcl_register_worker_option (cfg, type, "cachedir", + rspamd_rcl_parse_struct_string, ctx, + G_STRUCT_OFFSET (struct hs_helper_ctx, hs_dir), 0); + + return ctx; +} + +/** + * Clean + */ +static gboolean +rspamd_hs_helper_cleanup_dir (struct hs_helper_ctx *ctx) +{ + struct stat st; + glob_t globbuf; + guint len, i; + gchar *pattern; + gboolean ret = TRUE; + + if (stat (ctx->hs_dir, &st) == -1) { + msg_err ("cannot stat path %s, %s", + ctx->hs_dir, + strerror (errno)); + return FALSE; + } + + globbuf.gl_offs = 0; + len = strlen (ctx->hs_dir) + sizeof ("*.hs"); + pattern = g_malloc (len); + rspamd_snprintf (pattern, len, "%s%s", ctx->hs_dir, "*.hs"); + + if (glob (pattern, GLOB_DOOFFS, NULL, &globbuf) == 0) { + for (i = 0; i < globbuf.gl_pathc; i++) { + if (unlink (globbuf.gl_pathv[i]) == -1) { + msg_err ("cannot unlink %s: %s", globbuf.gl_pathv[i], + strerror (errno)); + ret = FALSE; + } + } + } + else { + msg_err ("glob %s failed: %s", pattern, strerror (errno)); + ret = FALSE; + } + + globfree (&globbuf); + g_free (pattern); + + return ret; +} + +static void +start_hs_helper (struct rspamd_worker *worker) +{ + struct hs_helper_ctx *ctx = worker->ctx; + GError *err = NULL; + struct rspamd_srv_command srv_cmd; + + ctx->ev_base = rspamd_prepare_worker (worker, + "hs_helper", + NULL); + + if (!rspamd_hs_helper_cleanup_dir (ctx)) { + msg_warn ("cannot cleanup cache dir '%s'", ctx->hs_dir); + } + + if (!rspamd_re_cache_compile_hyperscan (ctx->cfg->re_cache, + ctx->hs_dir, + &err)) { + msg_err ("failed to compile re cache: %e", err); + g_error_free (err); + + /* Tell main not to respawn process */ + exit (EXIT_SUCCESS); + } + + event_base_loop (ctx->ev_base, 0); + rspamd_worker_block_signals (); + + rspamd_log_close (worker->srv->logger); + + exit (EXIT_SUCCESS); +} diff --git a/src/libserver/rspamd_control.c b/src/libserver/rspamd_control.c index 8f2b66641..5ba24d056 100644 --- a/src/libserver/rspamd_control.c +++ b/src/libserver/rspamd_control.c @@ -87,6 +87,13 @@ static const struct rspamd_control_cmd_match { }, .type = RSPAMD_CONTROL_RERESOLVE }, + { + .name = { + .begin = "/recompile", + .len = sizeof ("/recompile") - 1 + }, + .type = RSPAMD_CONTROL_RECOMPILE + }, }; void @@ -193,10 +200,15 @@ rspamd_control_write_reply (struct rspamd_control_session *session) total_conns += elt->reply.reply.stat.conns; break; + case RSPAMD_CONTROL_RELOAD: ucl_object_insert_key (cur, ucl_object_fromint ( elt->reply.reply.reload.status), "status", 0, false); break; + case RSPAMD_CONTROL_RECOMPILE: + ucl_object_insert_key (cur, ucl_object_fromint ( + elt->reply.reply.recompile.status), "status", 0, false); + break; case RSPAMD_CONTROL_RERESOLVE: ucl_object_insert_key (cur, ucl_object_fromint ( elt->reply.reply.reresolve.status), "status", 0, false); @@ -390,6 +402,7 @@ rspamd_control_default_cmd_handler (gint fd, rep.reply.stat.uptime = rspamd_get_calendar_ticks () - cd->worker->start_time; break; case RSPAMD_CONTROL_RELOAD: + case RSPAMD_CONTROL_RECOMPILE: break; case RSPAMD_CONTROL_RERESOLVE: if (cd->worker->srv->cfg) { diff --git a/src/libserver/rspamd_control.h b/src/libserver/rspamd_control.h index 5e8497a0a..74597a1ac 100644 --- a/src/libserver/rspamd_control.h +++ b/src/libserver/rspamd_control.h @@ -35,6 +35,7 @@ enum rspamd_control_type { RSPAMD_CONTROL_STAT = 0, RSPAMD_CONTROL_RELOAD, RSPAMD_CONTROL_RERESOLVE, + RSPAMD_CONTROL_RECOMPILE, RSPAMD_CONTROL_MAX }; @@ -54,6 +55,9 @@ struct rspamd_control_command { struct { guint unused; } reresolve; + struct { + guint unused; + } recompile; } cmd; }; @@ -73,6 +77,9 @@ struct rspamd_control_reply { struct { guint status; } reresolve; + struct { + guint status; + } recompile; } reply; }; diff --git a/src/rspamadm/CMakeLists.txt b/src/rspamadm/CMakeLists.txt index 585e42628..44da69156 100644 --- a/src/rspamadm/CMakeLists.txt +++ b/src/rspamadm/CMakeLists.txt @@ -7,7 +7,9 @@ SET(RSPAMADMSRC rspamadm.c commands.c pw.c keypair.c configtest.c ${CMAKE_SOURCE_DIR}/src/smtp_proxy.c ${CMAKE_SOURCE_DIR}/src/worker.c ${CMAKE_SOURCE_DIR}/src/http_proxy.c fuzzy_merge.c configdump.c control.c) - +IF (ENABLE_HYPERSCAN MATCHES "ON") + LIST(APPEND RSPAMADMSRC "${CMAKE_SOURCE_DIR}/src/hs_helper.c") +ENDIF() ADD_EXECUTABLE(rspamadm ${RSPAMADMSRC}) TARGET_LINK_LIBRARIES(rspamadm rspamd-server) TARGET_LINK_LIBRARIES(rspamadm ${RSPAMD_REQUIRED_LIBRARIES}) @@ -20,6 +22,7 @@ TARGET_LINK_LIBRARIES(rspamadm rspamd-actrie) IF (NOT DEBIAN_BUILD) SET_TARGET_PROPERTIES(rspamadm PROPERTIES VERSION ${RSPAMD_VERSION}) ENDIF (NOT DEBIAN_BUILD) + IF (ENABLE_HYPERSCAN MATCHES "ON") TARGET_LINK_LIBRARIES(rspamadm hs) SET_TARGET_PROPERTIES(rspamadm PROPERTIES LINKER_LANGUAGE CXX) |