ENDIF(NOT LUA_FOUND)
ENDIF(ENABLE_LUAJIT MATCHES "ON")
-ProcessPackage(GLIB2 LIBRARY glib-2.0 INCLUDE glib.h INCLUDE_SUFFIXES include/glib
+ProcessPackage(GLIB2 LIBRARY glib-2.0 INCLUDE glib.h
+ INCLUDE_SUFFIXES include/glib
ROOT ${GLIB_ROOT_DIR} MODULES glib-2.0>=2.28)
+ProcessPackage(GMODULE2 LIBRARY gmodule-2.0 INCLUDE glib.h
+ INCLUDE_SUFFIXES include/glib
+ ROOT ${GLIB_ROOT_DIR} MODULES gmodule-2.0>=2.28)
IF(ENABLE_PCRE2 MATCHES "ON")
ProcessPackage(PCRE LIBRARY pcre2 INCLUDE pcre2.h INCLUDE_SUFFIXES include/pcre2
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;
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);
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) {
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);
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);
{
GList *cur;
module_t *mod, **pmod;
+ struct rspamd_dynamic_module *dyn_mod;
struct module_ctx *mod_ctx;
/* Init all compiled modules */
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;
+ }
}
}
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;
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;
+ }
}
}
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