]> source.dussan.org Git - rspamd.git/commitdiff
Initial support for dynamic modules and workers
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 12 Feb 2016 14:44:35 +0000 (14:44 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 12 Feb 2016 14:44:35 +0000 (14:44 +0000)
src/libserver/cfg_file.h
src/libserver/cfg_utils.c
src/libserver/worker_util.c
src/plugins/regexp.c
src/plugins/spf.c
src/rspamd.c
src/rspamd.h

index 7b49e48668bfbdd71ccc8f9bad62b9044ad968dc..44e838dd653f4755694d8293c36b707279b0f0a1 100644 (file)
@@ -341,6 +341,8 @@ struct rspamd_config {
        GList *classify_headers;                                                /**< list of headers using for statistics                               */
        struct module_s **compiled_modules;                             /**< list of compiled C modules                                                 */
        struct worker_s **compiled_workers;                             /**< list of compiled C modules                                                 */
+       GList *dynamic_modules;                                                 /**< list of dynamic C modules                                                  */
+       GList *dynamic_workers;                                                 /**< list of dynamic C modules                                                  */
        struct rspamd_log_format *log_format;                   /**< parsed log format                                                                  */
        gchar *log_format_str;                                                  /**< raw log format string                                                              */
 
index 66a67fe13ae3cd56deabedb442c75445755a14fa..bd2aac89b92772d99e54f38453c65d93a6b5aaf4 100644 (file)
@@ -1129,6 +1129,64 @@ rspamd_ucl_fin_cb (rspamd_mempool_t * pool, struct map_cb_data *data)
        }
 }
 
+gboolean
+rspamd_check_module (struct rspamd_config *cfg, module_t *mod)
+{
+       gboolean ret = TRUE;
+
+       if (mod != NULL) {
+               if (mod->module_version != RSPAMD_CUR_MODULE_VERSION) {
+                       msg_err_config ("module %s has incorrect version %xd (%xd expected)",
+                                       mod->name, mod->module_version, RSPAMD_CUR_MODULE_VERSION);
+                       ret = FALSE;
+               }
+               if (ret && mod->rspamd_version != RSPAMD_VERSION_NUM) {
+                       msg_err_config ("module %s has incorrect rspamd version %xd (%xd expected)",
+                                       mod->name, mod->rspamd_version, RSPAMD_VERSION_NUM);
+                       ret = FALSE;
+               }
+               if (ret && strcmp (mod->rspamd_features, RSPAMD_FEATURES) != 0) {
+                       msg_err_config ("module %s has incorrect rspamd features '%s' ('%s' expected)",
+                                       mod->name, mod->rspamd_features, RSPAMD_FEATURES);
+                       ret = FALSE;
+               }
+       }
+       else {
+               ret = FALSE;
+       }
+
+       return ret;
+}
+
+gboolean
+rspamd_check_worker (struct rspamd_config *cfg, worker_t *wrk)
+{
+       gboolean ret = TRUE;
+
+       if (wrk != NULL) {
+               if (wrk->worker_version != RSPAMD_CUR_WORKER_VERSION) {
+                       msg_err_config ("worker %s has incorrect version %xd (%xd expected)",
+                                       wrk->name, wrk->worker_version, RSPAMD_CUR_WORKER_VERSION);
+                       ret = FALSE;
+               }
+               if (ret && wrk->rspamd_version != RSPAMD_VERSION_NUM) {
+                       msg_err_config ("worker %s has incorrect rspamd version %xd (%xd expected)",
+                                       wrk->name, wrk->rspamd_version, RSPAMD_VERSION_NUM);
+                       ret = FALSE;
+               }
+               if (ret && strcmp (wrk->rspamd_features, RSPAMD_FEATURES) != 0) {
+                       msg_err_config ("worker %s has incorrect rspamd features '%s' ('%s' expected)",
+                                       wrk->name, wrk->rspamd_features, RSPAMD_FEATURES);
+                       ret = FALSE;
+               }
+       }
+       else {
+               ret = FALSE;
+       }
+
+       return ret;
+}
+
 gboolean
 rspamd_init_filters (struct rspamd_config *cfg, bool reconfig)
 {
@@ -1140,17 +1198,40 @@ rspamd_init_filters (struct rspamd_config *cfg, bool reconfig)
        if (!reconfig) {
                for (pmod = cfg->compiled_modules; pmod != NULL && *pmod != NULL; pmod ++) {
                        mod = *pmod;
-                       mod_ctx = g_slice_alloc0 (sizeof (struct module_ctx));
 
-                       if (mod->module_init_func (cfg, &mod_ctx) == 0) {
-                               g_hash_table_insert (cfg->c_modules,
-                                               (gpointer) mod->name,
-                                               mod_ctx);
-                               mod_ctx->mod = mod;
+                       if (rspamd_check_module (cfg, mod)) {
+                               mod_ctx = g_slice_alloc0 (sizeof (struct module_ctx));
+
+                               if (mod->module_init_func (cfg, &mod_ctx) == 0) {
+                                       g_hash_table_insert (cfg->c_modules,
+                                                       (gpointer) mod->name,
+                                                       mod_ctx);
+                                       mod_ctx->mod = mod;
+                               }
                        }
                }
+
+               cur = g_list_first (cfg->dynamic_modules);
+
+               while (cur) {
+                       mod = cur->data;
+
+                       if (rspamd_check_module (cfg, mod)) {
+                               mod_ctx = g_slice_alloc0 (sizeof (struct module_ctx));
+
+                               if (mod->module_init_func (cfg, &mod_ctx) == 0) {
+                                       g_hash_table_insert (cfg->c_modules,
+                                                       (gpointer) mod->name,
+                                                       mod_ctx);
+                                       mod_ctx->mod = mod;
+                               }
+                       }
+
+                       cur = g_list_next (cur);
+               }
        }
 
+       /* Now check what's enabled */
        cur = g_list_first (cfg->filters);
 
        while (cur) {
index 8bda8d709c9a13a8b97fa8985e53f22f6204ffc2..b18c36ec91d96a962b23e44d4addf2167c37941c 100644 (file)
 worker_t *
 rspamd_get_worker_by_type (struct rspamd_config *cfg, GQuark type)
 {
-       worker_t **cur;
+       worker_t **pwrk, *wrk;
+       GList *cur;
 
-       cur = cfg->compiled_workers;
-       while (cur && *cur) {
-               if (g_quark_from_string ((*cur)->name) == type) {
-                       return *cur;
+       pwrk = cfg->compiled_workers;
+       while (pwrk && *pwrk) {
+               if (rspamd_check_worker (cfg, *pwrk)) {
+                       if (g_quark_from_string ((*pwrk)->name) == type) {
+                               return *pwrk;
+                       }
                }
-               cur++;
+
+               pwrk++;
+       }
+
+       cur = g_list_first (cfg->dynamic_workers);
+       while (cur) {
+               wrk = cur->data;
+
+               if (rspamd_check_worker (cfg, wrk)) {
+                       if (g_quark_from_string (wrk->name) == type) {
+                               return wrk;
+                       }
+               }
+
+               cur = g_list_next (cur);
        }
 
        return NULL;
index 7273d87d79c9a74ca05ab7f77aad8e0fd4f401f7..fbe612fbc36384aa917c49867910860fe9462cd2 100644 (file)
@@ -52,7 +52,8 @@ module_t regexp_module = {
        regexp_module_init,
        regexp_module_config,
        regexp_module_reconfig,
-       NULL
+       NULL,
+       RSPAMD_MODULE_VER
 };
 
 /* Process regexp expression */
index a73c06c71540784be18ede1b3753cf53f5718718..a02dcc002d7ca51ee143880c4ea2447ed2cb4a0d 100644 (file)
@@ -64,7 +64,8 @@ module_t spf_module = {
        spf_module_init,
        spf_module_config,
        spf_module_reconfig,
-       NULL
+       NULL,
+       RSPAMD_MODULE_VER
 };
 
 static GQuark
index a7cf68a20788b45e1621b3c8fee6f8255037e57c..abbce74a0e8491ea960b1db916ddbe08bc9de0ee 100644 (file)
@@ -459,6 +459,7 @@ spawn_workers (struct rspamd_main *rspamd_main, struct event_base *ev_base)
        gboolean listen_ok = FALSE, seen_hs_helper = FALSE;
        GQuark qtype;
 
+       /* Special hack for hs_helper if it's not defined in a config */
        qtype = g_quark_try_string ("hs_helper");
 
        cur = rspamd_main->cfg->workers;
index e5c7bb4db4e03875051343f9bc9019abb7ab0931..0c7668bfa22da0e8499b8afaa1b834fe287b5646 100644 (file)
@@ -117,17 +117,20 @@ struct module_ctx {
 #define RSPAMD_FEATURE_SNOWBALL "1"
 #endif
 
+#define RSPAMD_CUR_MODULE_VERSION 0x1
+#define RSPAMD_CUR_WORKER_VERSION 0x1
+
 #define RSPAMD_FEATURES \
                RSPAMD_FEATURE_HYPERSCAN RSPAMD_FEATURE_PCRE2 \
                RSPAMD_FEATURE_FANN RSPAMD_FEATURE_SNOWBALL
 
 #define RSPAMD_MODULE_VER \
-               0x1, /* Module version */ \
+               RSPAMD_CUR_MODULE_VERSION, /* Module version */ \
                RSPAMD_VERSION_NUM, /* Rspamd version */ \
                RSPAMD_FEATURES /* Compilation features */ \
 
 #define RSPAMD_WORKER_VER \
-               0x1, /* Worker version */ \
+               RSPAMD_CUR_WORKER_VERSION, /* Worker version */ \
                RSPAMD_VERSION_NUM, /* Rspamd version */ \
                RSPAMD_FEATURES /* Compilation features */ \
 /**
@@ -154,11 +157,27 @@ typedef struct worker_s {
        gboolean threaded;
        gboolean killable;
        gint listen_type;
-       guint module_version;
+       guint worker_version;
        guint64 rspamd_version;
        const gchar *rspamd_features;
 } worker_t;
 
+/**
+ * Check if loaded worker is compatible with rspamd
+ * @param cfg
+ * @param wrk
+ * @return
+ */
+gboolean rspamd_check_worker (struct rspamd_config *cfg, worker_t *wrk);
+
+/**
+ * Check if loaded module is compatible with rspamd
+ * @param cfg
+ * @param wrk
+ * @return
+ */
+gboolean rspamd_check_module (struct rspamd_config *cfg, module_t *wrk);
+
 struct pidfh;
 struct rspamd_config;
 struct tokenizer;