aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-02-12 14:44:35 +0000
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-02-12 14:44:35 +0000
commit85b3f42f215e5736d90a803835f506673538bbd0 (patch)
tree30ac8621fee86ad9dcb5f7950af157016e0bc3cf /src
parentd54124d738a0e30d2b3b9adb1966374935ff3f46 (diff)
downloadrspamd-85b3f42f215e5736d90a803835f506673538bbd0.tar.gz
rspamd-85b3f42f215e5736d90a803835f506673538bbd0.zip
Initial support for dynamic modules and workers
Diffstat (limited to 'src')
-rw-r--r--src/libserver/cfg_file.h2
-rw-r--r--src/libserver/cfg_utils.c93
-rw-r--r--src/libserver/worker_util.c29
-rw-r--r--src/plugins/regexp.c3
-rw-r--r--src/plugins/spf.c3
-rw-r--r--src/rspamd.c1
-rw-r--r--src/rspamd.h25
7 files changed, 139 insertions, 17 deletions
diff --git a/src/libserver/cfg_file.h b/src/libserver/cfg_file.h
index 7b49e4866..44e838dd6 100644
--- a/src/libserver/cfg_file.h
+++ b/src/libserver/cfg_file.h
@@ -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 */
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c
index 66a67fe13..bd2aac89b 100644
--- a/src/libserver/cfg_utils.c
+++ b/src/libserver/cfg_utils.c
@@ -1130,6 +1130,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)
{
GList *cur;
@@ -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) {
diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c
index 8bda8d709..b18c36ec9 100644
--- a/src/libserver/worker_util.c
+++ b/src/libserver/worker_util.c
@@ -49,14 +49,31 @@
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;
diff --git a/src/plugins/regexp.c b/src/plugins/regexp.c
index 7273d87d7..fbe612fbc 100644
--- a/src/plugins/regexp.c
+++ b/src/plugins/regexp.c
@@ -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 */
diff --git a/src/plugins/spf.c b/src/plugins/spf.c
index a73c06c71..a02dcc002 100644
--- a/src/plugins/spf.c
+++ b/src/plugins/spf.c
@@ -64,7 +64,8 @@ module_t spf_module = {
spf_module_init,
spf_module_config,
spf_module_reconfig,
- NULL
+ NULL,
+ RSPAMD_MODULE_VER
};
static GQuark
diff --git a/src/rspamd.c b/src/rspamd.c
index a7cf68a20..abbce74a0 100644
--- a/src/rspamd.c
+++ b/src/rspamd.c
@@ -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;
diff --git a/src/rspamd.h b/src/rspamd.h
index e5c7bb4db..0c7668bfa 100644
--- a/src/rspamd.h
+++ b/src/rspamd.h
@@ -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;