aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/libserver/cfg_rcl.c52
-rw-r--r--src/libserver/cfg_utils.c47
-rw-r--r--src/libserver/worker_util.c13
-rw-r--r--src/rspamd.h14
4 files changed, 109 insertions, 17 deletions
diff --git a/src/libserver/cfg_rcl.c b/src/libserver/cfg_rcl.c
index 79d9c9e0e..9b05c1396 100644
--- a/src/libserver/cfg_rcl.c
+++ b/src/libserver/cfg_rcl.c
@@ -528,9 +528,11 @@ rspamd_rcl_worker_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
struct rspamd_rcl_section *section, GError **err)
{
const ucl_object_t *val, *cur, *cur_obj;
+ struct rspamd_dynamic_worker *dyn_wrk;
+ worker_t *dyn_ctx;
ucl_object_t *robj;
ucl_object_iter_t it = NULL;
- const gchar *worker_type, *worker_bind;
+ const gchar *worker_type, *worker_bind, *lib_path;
struct rspamd_config *cfg = ud;
GQuark qtype;
struct rspamd_worker_conf *wrk;
@@ -541,6 +543,49 @@ rspamd_rcl_worker_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
g_assert (key != NULL);
worker_type = key;
+ val = ucl_object_find_any_key (obj, "module", "load", NULL);
+
+ if (val != NULL && ucl_object_tostring_safe (val, &lib_path)) {
+
+ if (!g_module_supported ()) {
+ msg_err_config ("modules are not supported, so load of %s is impossible",
+ worker_type);
+
+ return FALSE;
+ }
+
+ dyn_wrk = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (*dyn_wrk));
+ dyn_wrk->lib = g_module_open (lib_path, G_MODULE_BIND_LAZY);
+
+ if (dyn_wrk->lib == NULL) {
+ msg_err_config ("cannot load %s at %s: %s", worker_type,
+ lib_path, strerror (errno));
+
+ return FALSE;
+ }
+
+ if (!g_module_symbol (dyn_wrk->lib, "rspamd_dyn_worker",
+ (gpointer *)&dyn_ctx)) {
+ msg_err_config ("cannot load %s at %s: missing entry point",
+ worker_type,
+ lib_path);
+ g_module_close (dyn_wrk->lib);
+
+ return FALSE;
+ }
+
+ if (!rspamd_check_worker (cfg, dyn_ctx)) {
+ g_module_close (dyn_wrk->lib);
+
+ return FALSE;
+ }
+
+ memcpy (&dyn_wrk->wrk, dyn_ctx, sizeof (dyn_wrk->wrk));
+ dyn_wrk->path = lib_path;
+ dyn_wrk->type = g_quark_from_static_string (worker_type);
+ cfg->dynamic_workers = g_list_prepend (cfg->dynamic_workers, dyn_wrk);
+ }
+
qtype = g_quark_try_string (worker_type);
if (qtype != 0) {
wrk = rspamd_config_new_worker (cfg, NULL);
@@ -563,11 +608,8 @@ rspamd_rcl_worker_handler (rspamd_mempool_t *pool, const ucl_object_t *obj,
return TRUE;
}
- val = ucl_object_find_key (obj, "bind_socket");
+ val = ucl_object_find_any_key (obj, "bind_socket", "listen", "bind", NULL);
/* This name is more logical */
- if (val == NULL) {
- val = ucl_object_find_key (obj, "listen");
- }
if (val != NULL) {
it = ucl_object_iterate_new (val);
while ((cur = ucl_object_iterate_safe (it, true)) != NULL) {
diff --git a/src/libserver/cfg_utils.c b/src/libserver/cfg_utils.c
index bd2aac89b..eba9d66d9 100644
--- a/src/libserver/cfg_utils.c
+++ b/src/libserver/cfg_utils.c
@@ -162,6 +162,10 @@ rspamd_config_new (void)
void
rspamd_config_free (struct rspamd_config *cfg)
{
+ struct rspamd_dynamic_module *dyn_mod;
+ struct rspamd_dynamic_worker *dyn_wrk;
+ GList *cur;
+
rspamd_map_remove_all (cfg);
ucl_object_unref (cfg->rcl_obj);
ucl_object_unref (cfg->doc_strings);
@@ -182,6 +186,28 @@ rspamd_config_free (struct rspamd_config *cfg)
g_free (cfg->checksum);
}
+ /* Unload dynamic workers/modules */
+ cur = g_list_first (cfg->dynamic_modules);
+ while (cur) {
+ dyn_mod = cur->data;
+
+ if (dyn_mod->lib) {
+ g_module_close (dyn_mod->lib);
+ }
+
+ cur = g_list_next (cur);
+ }
+ cur = g_list_first (cfg->dynamic_workers);
+ while (cur) {
+ dyn_wrk = cur->data;
+
+ if (dyn_wrk->lib) {
+ g_module_close (dyn_wrk->lib);
+ }
+
+ cur = g_list_next (cur);
+ }
+
g_list_free (cfg->classifiers);
g_list_free (cfg->metrics_list);
rspamd_symbols_cache_destroy (cfg->cache);
@@ -1192,6 +1218,7 @@ rspamd_init_filters (struct rspamd_config *cfg, bool reconfig)
{
GList *cur;
module_t *mod, **pmod;
+ struct rspamd_dynamic_module *dyn_mod;
struct module_ctx *mod_ctx;
/* Init all compiled modules */
@@ -1214,16 +1241,20 @@ rspamd_init_filters (struct rspamd_config *cfg, bool reconfig)
cur = g_list_first (cfg->dynamic_modules);
while (cur) {
- mod = cur->data;
+ dyn_mod = cur->data;
- if (rspamd_check_module (cfg, mod)) {
- mod_ctx = g_slice_alloc0 (sizeof (struct module_ctx));
+ if (dyn_mod->lib) {
+ mod = &dyn_mod->mod;
- 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;
+ }
}
}
diff --git a/src/libserver/worker_util.c b/src/libserver/worker_util.c
index b18c36ec9..41f6e3ef2 100644
--- a/src/libserver/worker_util.c
+++ b/src/libserver/worker_util.c
@@ -50,6 +50,7 @@ worker_t *
rspamd_get_worker_by_type (struct rspamd_config *cfg, GQuark type)
{
worker_t **pwrk, *wrk;
+ struct rspamd_dynamic_worker *dyn_wrk;
GList *cur;
pwrk = cfg->compiled_workers;
@@ -65,11 +66,15 @@ rspamd_get_worker_by_type (struct rspamd_config *cfg, GQuark type)
cur = g_list_first (cfg->dynamic_workers);
while (cur) {
- wrk = cur->data;
+ dyn_wrk = cur->data;
- if (rspamd_check_worker (cfg, wrk)) {
- if (g_quark_from_string (wrk->name) == type) {
- return wrk;
+ if (dyn_wrk->lib) {
+ wrk = &dyn_wrk->wrk;
+
+ if (rspamd_check_worker (cfg, wrk)) {
+ if (g_quark_from_string (wrk->name) == type) {
+ return wrk;
+ }
}
}
diff --git a/src/rspamd.h b/src/rspamd.h
index 0c7668bfa..5fb40861c 100644
--- a/src/rspamd.h
+++ b/src/rspamd.h
@@ -162,6 +162,20 @@ typedef struct worker_s {
const gchar *rspamd_features;
} worker_t;
+struct rspamd_dynamic_module {
+ module_t mod;
+ GModule *lib;
+ const gchar *path;
+ GQuark type;
+};
+
+struct rspamd_dynamic_worker {
+ worker_t wrk;
+ GModule *lib;
+ GQuark type;
+ const gchar *path;
+};
+
/**
* Check if loaded worker is compatible with rspamd
* @param cfg