From 08c83eb559b9f5225fa2e7e68a0987305aa9f5f3 Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Sun, 24 Apr 2022 12:58:02 +0100 Subject: [PATCH] [Project] More methods --- src/libserver/symcache/symcache_c.cxx | 26 ++++++ src/libserver/symcache/symcache_impl.cxx | 95 +++++++++++++++++++- src/libserver/symcache/symcache_internal.hxx | 6 ++ src/libserver/symcache/symcache_runtime.hxx | 9 ++ 4 files changed, 132 insertions(+), 4 deletions(-) diff --git a/src/libserver/symcache/symcache_c.cxx b/src/libserver/symcache/symcache_c.cxx index a559c3564..51b390982 100644 --- a/src/libserver/symcache/symcache_c.cxx +++ b/src/libserver/symcache/symcache_c.cxx @@ -277,6 +277,15 @@ rspamd_symcache_foreach(struct rspamd_symcache *cache, }); } +void +rspamd_symcache_process_settings_elt(struct rspamd_symcache *cache, + struct rspamd_config_settings_elt *elt) +{ + auto *real_cache = C_API_SYMCACHE(cache); + + real_cache->process_settings_elt(elt); +} + void rspamd_symcache_disable_all_symbols(struct rspamd_task *task, struct rspamd_symcache *_cache, @@ -349,4 +358,21 @@ rspamd_symcache_is_symbol_enabled(struct rspamd_task *task, auto *real_cache = C_API_SYMCACHE(cache); return cache_runtime->is_symbol_enabled(task, *real_cache, symbol); +} + +struct rspamd_symcache_item * +rspamd_symcache_get_cur_item(struct rspamd_task *task) +{ + auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime); + + return (struct rspamd_symcache_item *) cache_runtime->get_cur_item(); +} + +struct rspamd_symcache_item * +rspamd_symcache_set_cur_item(struct rspamd_task *task, struct rspamd_symcache_item *item) +{ + auto *cache_runtime = C_API_SYMCACHE_RUNTIME(task->symcache_runtime); + auto *real_item = C_API_SYMCACHE_ITEM(item); + + return (struct rspamd_symcache_item *) cache_runtime->set_cur_item(real_item); } \ No newline at end of file diff --git a/src/libserver/symcache/symcache_impl.cxx b/src/libserver/symcache/symcache_impl.cxx index da5a6145e..d5c442ab2 100644 --- a/src/libserver/symcache/symcache_impl.cxx +++ b/src/libserver/symcache/symcache_impl.cxx @@ -561,7 +561,7 @@ auto symcache::resort() -> void * as it is done in another place */ constexpr auto append_items_vec = [](const auto &vec, auto &out) { - for (const auto &it : vec) { + for (const auto &it: vec) { if (it) { out.emplace_back(it); } @@ -576,7 +576,7 @@ auto symcache::resort() -> void append_items_vec(classifiers, ord->d); /* After sorting is done, we can assign all elements in the by_symbol hash */ - for (auto i = 0; i < ord->size(); i ++) { + for (auto i = 0; i < ord->size(); i++) { const auto &it = ord->d[i]; ord->by_symbol[it->get_name()] = i; ord->by_cache_id[it->id] = i; @@ -879,7 +879,7 @@ auto symcache::periodic_resort(struct ev_loop *ev_loop, double cur_time, double if (item->update_counters_check_peak(L, ev_loop, cur_time, last_resort)) { auto cur_value = (item->st->total_hits - item->last_count) / - (cur_time - last_resort); + (cur_time - last_resort); auto cur_err = (item->st->avg_frequency - cur_value); cur_err *= cur_err; msg_debug_cache ("peak found for %s is %.2f, avg: %.2f, " @@ -927,7 +927,7 @@ auto symcache::maybe_resort() -> bool * Cache has been modified, need to resort it */ msg_info_cache("symbols cache has been modified since last check:" - " old id: %ud, new id: %ud", + " old id: %ud, new id: %ud", items_by_order->generation_id, cur_order_gen); resort(); @@ -962,4 +962,91 @@ symcache::get_item_specific_vector(const cache_item &it) -> symcache::items_ptr_ RSPAMD_UNREACHABLE; } +auto +symcache::process_settings_elt(struct rspamd_config_settings_elt *elt) -> void +{ + + auto id = elt->id; + + if (elt->symbols_disabled) { + /* Process denied symbols */ + ucl_object_iter_t iter = nullptr; + const ucl_object_t *cur; + + while ((cur = ucl_object_iterate(elt->symbols_disabled, &iter, true)) != NULL) { + const auto *sym = ucl_object_key(cur); + auto *item = get_item_by_name_mut(sym, false); + + if (item != nullptr) { + if (item->is_virtual()) { + /* + * Virtual symbols are special: + * we ignore them in symcache but prevent them from being + * inserted. + */ + item->forbidden_ids.add_id(id, static_pool); + msg_debug_cache("deny virtual symbol %s for settings %ud (%s); " + "parent can still be executed", + sym, id, elt->name); + } + else { + /* Normal symbol, disable it */ + item->forbidden_ids.add_id(id, static_pool); + msg_debug_cache ("deny symbol %s for settings %ud (%s)", + sym, id, elt->name); + } + } + else { + msg_warn_cache ("cannot find a symbol to disable %s " + "when processing settings %ud (%s)", + sym, id, elt->name); + } + } + } + + if (elt->symbols_enabled) { + ucl_object_iter_t iter = nullptr; + const ucl_object_t *cur; + + while ((cur = ucl_object_iterate (elt->symbols_enabled, &iter, true)) != nullptr) { + /* Here, we resolve parent and explicitly allow it */ + const auto *sym = ucl_object_key(cur); + + auto *item = get_item_by_name_mut(sym, false); + + if (item != nullptr) { + if (item->is_virtual()) { + if (!(item->flags & SYMBOL_TYPE_GHOST)) { + auto *parent = get_item_by_name_mut(sym, true); + + if (parent) { + if (elt->symbols_disabled && + ucl_object_lookup(elt->symbols_disabled, parent->symbol.data())) { + msg_err_cache ("conflict in %s: cannot enable disabled symbol %s, " + "wanted to enable symbol %s", + elt->name, parent->symbol.data(), sym); + continue; + } + + parent->exec_only_ids.add_id(id, static_pool); + msg_debug_cache ("allow just execution of symbol %s for settings %ud (%s)", + parent->symbol.data(), id, elt->name); + } + } + /* Ignore ghosts */ + } + + item->allowed_ids.add_id(id, static_pool); + msg_debug_cache ("allow execution of symbol %s for settings %ud (%s)", + sym, id, elt->name); + } + else { + msg_warn_cache ("cannot find a symbol to enable %s " + "when processing settings %ud (%s)", + sym, id, elt->name); + } + } + } +} + } \ No newline at end of file diff --git a/src/libserver/symcache/symcache_internal.hxx b/src/libserver/symcache/symcache_internal.hxx index 41edec53e..25eaa4f40 100644 --- a/src/libserver/symcache/symcache_internal.hxx +++ b/src/libserver/symcache/symcache_internal.hxx @@ -393,6 +393,12 @@ public: auto set_last_profile(double last_profile){ symcache::last_profile = last_profile; } + + /** + * Process settings elt identified by id + * @param elt + */ + auto process_settings_elt(struct rspamd_config_settings_elt *elt) -> void; }; diff --git a/src/libserver/symcache/symcache_runtime.hxx b/src/libserver/symcache/symcache_runtime.hxx index 8a0da7bc0..1f237b5b3 100644 --- a/src/libserver/symcache/symcache_runtime.hxx +++ b/src/libserver/symcache/symcache_runtime.hxx @@ -118,6 +118,15 @@ public: * @return */ auto is_symbol_enabled(struct rspamd_task *task, const symcache &cache, std::string_view name) -> bool; + + auto get_cur_item() const -> auto { + return cur_item; + } + + auto set_cur_item(cache_item *item) -> auto { + std::swap(item, cur_item); + return item; + } }; -- 2.39.5