]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
Add hyperscan helper worker
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 7 Dec 2015 17:24:43 +0000 (17:24 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 7 Dec 2015 17:24:43 +0000 (17:24 +0000)
src/CMakeLists.txt
src/fuzzy_storage.c
src/hs_helper.c [new file with mode: 0644]
src/libserver/rspamd_control.c
src/libserver/rspamd_control.h
src/rspamadm/CMakeLists.txt

index acc91b673d199ce33a4497b97d28fe19c0516acb..fc85428caf58e5c27a6e5804edd08cbc1eda1e06 100644 (file)
@@ -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)
index 40862dd1a9e022bbfaad3047f7784ca139153fef..0acc7e4e0a371228ee742ade133a0587abd34f06 100644 (file)
@@ -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 (file)
index 0000000..6bc9c3d
--- /dev/null
@@ -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);
+}
index 8f2b66641ba461726b65ced4e8aac37816e1e45c..5ba24d0561a6d295c1773bd8619abc2ca3dbb715 100644 (file)
@@ -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) {
index 5e8497a0a00a85c75807fbeb4f04cfdeb86d1ad7..74597a1ac06a08fc19328c35cc77b14248d7a3f5 100644 (file)
@@ -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;
 };
 
index 585e42628e7451da99c7d75ecc6464c360226f2f..44da69156ab0d734848d95fd13be323779916f6e 100644 (file)
@@ -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)