gboolean rspamd_init_filters (struct rspamd_config *cfg, bool reconfig) { GList *cur; module_t *mod, **pmod; struct module_ctx *mod_ctx; /* Init all compiled modules */ 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; } } } cur = g_list_first (cfg->filters); while (cur) { /* Perform modules configuring */ mod_ctx = NULL; mod_ctx = g_hash_table_lookup (cfg->c_modules, cur->data); if (mod_ctx) { mod = mod_ctx->mod; mod_ctx->enabled = TRUE; if (reconfig) { (void)mod->module_reconfig_func (cfg); msg_debug_config ("reconfig of %s", mod->name); } else { (void)mod->module_config_func (cfg); } } if (mod_ctx == NULL) { msg_warn_config ("requested unknown module %s", cur->data); } cur = g_list_next (cur); } return rspamd_init_lua_filters (cfg); }
gboolean rspamd_config_add_metric_symbol (struct rspamd_config *cfg, const gchar *metric_name, const gchar *symbol, gdouble score, const gchar *description, const gchar *group, gboolean one_shot, gboolean rewrite_existing) { struct rspamd_symbols_group *sym_group; struct rspamd_symbol_def *sym_def; GList *metric_list; struct metric *metric; gdouble *score_ptr; g_assert (cfg != NULL); g_assert (symbol != NULL); if (metric_name == NULL) { metric_name = DEFAULT_METRIC; } metric = g_hash_table_lookup (cfg->metrics, metric_name); if (metric == NULL) { msg_err_config ("metric %s has not been found", metric_name); return FALSE; } if (g_hash_table_lookup (cfg->metrics_symbols, symbol) != NULL && !rewrite_existing) { msg_debug_config ("symbol %s has been already registered, do not override"); return FALSE; } sym_def = rspamd_mempool_alloc0 (cfg->cfg_pool, sizeof (struct rspamd_symbol_def)); score_ptr = rspamd_mempool_alloc (cfg->cfg_pool, sizeof (gdouble)); *score_ptr = score; sym_def->score = score; sym_def->weight_ptr = score_ptr; sym_def->name = rspamd_mempool_strdup (cfg->cfg_pool, symbol); sym_def->one_shot = one_shot; if (description) { sym_def->description = rspamd_mempool_strdup (cfg->cfg_pool, description); } msg_debug_config ("registered symbol %s with weight %.2f in metric %s and group %s", sym_def->name, score, metric->name, group); g_hash_table_insert (metric->symbols, sym_def->name, sym_def); if ((metric_list = g_hash_table_lookup (cfg->metrics_symbols, sym_def->name)) == NULL) { metric_list = g_list_prepend (NULL, metric); rspamd_mempool_add_destructor (cfg->cfg_pool, (rspamd_mempool_destruct_t)g_list_free, metric_list); g_hash_table_insert (cfg->metrics_symbols, sym_def->name, metric_list); } else { /* Slow but keep start element of list in safe */ if (!g_list_find (metric_list, metric)) { metric_list = g_list_append (metric_list, metric); } } /* Search for symbol group */ if (group == NULL) { group = "ungrouped"; } sym_group = g_hash_table_lookup (metric->groups, group); if (sym_group == NULL) { /* Create new group */ sym_group = rspamd_config_new_group (cfg, metric, group); } sym_def->gr = sym_group; g_hash_table_insert (sym_group->symbols, sym_def->name, sym_def); return TRUE; }
void rspamd_stat_init (struct rspamd_config *cfg, struct event_base *ev_base) { GList *cur, *curst; struct rspamd_classifier_config *clf; struct rspamd_statfile_config *stf; struct rspamd_stat_backend *bk; struct rspamd_statfile *st; struct rspamd_classifier *cl; const ucl_object_t *cache_obj = NULL, *cache_name_obj; const gchar *cache_name = NULL; if (stat_ctx == NULL) { stat_ctx = g_slice_alloc0 (sizeof (*stat_ctx)); } stat_ctx->backends_subrs = stat_backends; stat_ctx->backends_count = G_N_ELEMENTS (stat_backends); stat_ctx->classifiers_subrs = stat_classifiers; stat_ctx->classifiers_count = G_N_ELEMENTS (stat_classifiers); stat_ctx->tokenizers_subrs = stat_tokenizers; stat_ctx->tokenizers_count = G_N_ELEMENTS (stat_tokenizers); stat_ctx->caches_subrs = stat_caches; stat_ctx->caches_count = G_N_ELEMENTS (stat_caches); stat_ctx->cfg = cfg; stat_ctx->statfiles = g_ptr_array_new (); stat_ctx->classifiers = g_ptr_array_new (); stat_ctx->async_elts = g_queue_new (); stat_ctx->ev_base = ev_base; REF_RETAIN (stat_ctx->cfg); /* Create statfiles from the classifiers */ cur = cfg->classifiers; while (cur) { clf = cur->data; bk = rspamd_stat_get_backend (clf->backend); if (bk == NULL) { msg_err_config ("cannot get backend of type %s, so disable classifier" " %s completely", clf->backend, clf->name); cur = g_list_next (cur); continue; } /* XXX: * Here we get the first classifier tokenizer config as the only one * We NO LONGER support multiple tokenizers per rspamd instance */ if (stat_ctx->tkcf == NULL) { stat_ctx->tokenizer = rspamd_stat_get_tokenizer (clf->tokenizer->name); g_assert (stat_ctx->tokenizer != NULL); stat_ctx->tkcf = stat_ctx->tokenizer->get_config (cfg->cfg_pool, clf->tokenizer, NULL); } cl = g_slice_alloc0 (sizeof (*cl)); cl->cfg = clf; cl->ctx = stat_ctx; cl->statfiles_ids = g_array_new (FALSE, FALSE, sizeof (gint)); cl->subrs = rspamd_stat_get_classifier (clf->classifier); g_assert (cl->subrs != NULL); cl->subrs->init_func (cfg->cfg_pool, cl); /* Init classifier cache */ cache_name = NULL; if (clf->opts) { cache_obj = ucl_object_find_key (clf->opts, "cache"); cache_name_obj = NULL; if (cache_obj) { cache_name_obj = ucl_object_find_any_key (cache_obj, "name", "type", NULL); } if (cache_name_obj) { cache_name = ucl_object_tostring (cache_name_obj); } } if (cache_name == NULL) { /* We assume that learn cache is the same as backend */ cache_name = clf->backend; } curst = clf->statfiles; while (curst) { stf = curst->data; st = g_slice_alloc0 (sizeof (*st)); st->classifier = cl; st->stcf = stf; st->backend = bk; st->bkcf = bk->init (stat_ctx, cfg, st); msg_debug_config ("added backend %s for symbol %s", bk->name, stf->symbol); /* XXX: bad hack to pass statfiles configuration to cache */ if (cl->cache == NULL) { cl->cache = rspamd_stat_get_cache (cache_name); g_assert (cl->cache != NULL); cl->cachecf = cl->cache->init (stat_ctx, cfg, st, cache_obj); if (cl->cachecf == NULL) { msg_err_config ("error adding cache %s for symbol %s", cl->cache->name, stf->symbol); cl->cache = NULL; } else { msg_debug_config ("added cache %s for symbol %s", cl->cache->name, stf->symbol); } } if (st->bkcf == NULL) { msg_err_config ("cannot init backend %s for statfile %s", clf->backend, stf->symbol); g_slice_free1 (sizeof (*st), st); } else { st->id = stat_ctx->statfiles->len; g_ptr_array_add (stat_ctx->statfiles, st); g_array_append_val (cl->statfiles_ids, st->id); } curst = curst->next; } g_ptr_array_add (stat_ctx->classifiers, cl); cur = cur->next; } }