]> source.dussan.org Git - rspamd.git/commitdiff
[Project] More methods
authorVsevolod Stakhov <vsevolod@rspamd.com>
Sun, 24 Apr 2022 11:58:02 +0000 (12:58 +0100)
committerVsevolod Stakhov <vsevolod@rspamd.com>
Sun, 24 Apr 2022 11:58:02 +0000 (12:58 +0100)
src/libserver/symcache/symcache_c.cxx
src/libserver/symcache/symcache_impl.cxx
src/libserver/symcache/symcache_internal.hxx
src/libserver/symcache/symcache_runtime.hxx

index a559c3564c3ebfc4641eb00aa0e01b7ad08d1790..51b39098201a2bbfff4dc32d328dfea72c9a7915 100644 (file)
@@ -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
index da5a6145e5d6c46bd53277d82588cc9e2c097c2c..d5c442ab2722ec3a8a9046ca20ba37fea09d1465 100644 (file)
@@ -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
index 41edec53ec3afb908ce7f81932ee75bef3ffb49e..25eaa4f401f59faa8ff1688036008e4c37c89b8c 100644 (file)
@@ -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;
 };
 
 
index 8a0da7bc0228c6e78d4bfa341fbba273c95aad9e..1f237b5b3cbfa82977d95a5a4e667c61735ab00e 100644 (file)
@@ -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;
+       }
 };