commit 7e08114: [Feature] Implement settings id propagation between deps
Vsevolod Stakhov
vsevolod at highsecure.ru
Tue Aug 20 16:42:06 UTC 2019
Author: Vsevolod Stakhov
Date: 2019-08-20 16:26:22 +0100
URL: https://github.com/rspamd/rspamd/commit/7e081148fdf4fa81c7973037c07236e804296272
[Feature] Implement settings id propagation between deps
---
src/libserver/rspamd_symcache.c | 213 ++++++++++++++++++++++++++++++----------
src/libserver/rspamd_symcache.h | 3 +-
src/lua/lua_config.c | 3 +-
src/plugins/surbl.c | 4 +-
4 files changed, 166 insertions(+), 57 deletions(-)
diff --git a/src/libserver/rspamd_symcache.c b/src/libserver/rspamd_symcache.c
index 054c6af5f..900a1894c 100644
--- a/src/libserver/rspamd_symcache.c
+++ b/src/libserver/rspamd_symcache.c
@@ -193,9 +193,10 @@ struct rspamd_symcache_dynamic_item {
struct cache_dependency {
- struct rspamd_symcache_item *item;
- gchar *sym;
- gint id;
+ struct rspamd_symcache_item *item; /* Real dependency */
+ gchar *sym; /* Symbolic dep name */
+ gint id; /* Real from */
+ gint vid; /* Virtual from */
};
struct delayed_cache_dependency {
@@ -533,12 +534,139 @@ rspamd_symcache_resort (struct rspamd_symcache *cache)
cache->items_by_order = ord;
}
+static void
+rspamd_symcache_propagate_dep (struct rspamd_symcache *cache,
+ struct rspamd_symcache_item *it,
+ struct rspamd_symcache_item *dit)
+{
+ const guint *ids;
+ guint nids = 0;
+
+ ids = rspamd_symcache_get_allowed_settings_ids (cache, dit->symbol, &nids);
+
+ /* TODO: merge? */
+ if (nids > 0) {
+ msg_info_cache ("propagate allowed ids from %s to %s",
+ dit->symbol, it->symbol);
+
+ rspamd_symcache_set_allowed_settings_ids (cache, it->symbol, ids,
+ nids);
+ }
+
+ ids = rspamd_symcache_get_forbidden_settings_ids (cache, dit->symbol, &nids);
+
+ if (nids > 0) {
+ msg_info_cache ("propagate forbidden ids from %s to %s",
+ dit->symbol, it->symbol);
+
+ rspamd_symcache_set_forbidden_settings_ids (cache, it->symbol, ids,
+ nids);
+ }
+}
+
+static void
+rspamd_symcache_process_dep (struct rspamd_symcache *cache,
+ struct rspamd_symcache_item *it,
+ struct cache_dependency *dep)
+{
+ struct rspamd_symcache_item *dit = NULL, *vdit = NULL;
+ struct cache_dependency *rdep;
+
+ if (dep->id >= 0) {
+ dit = rspamd_symcache_find_filter (cache, dep->sym, true);
+ }
+
+ if (dep->vid >= 0) {
+ /* Case of the virtual symbol that depends on another (maybe virtual) symbol */
+ vdit = rspamd_symcache_find_filter (cache, dep->sym, false);
+ }
+ else {
+ vdit = dit;
+ }
+
+ if (dit != NULL) {
+ if (!dit->is_filter) {
+ /*
+ * Check sanity:
+ * - filters -> prefilter dependency is OK and always satisfied
+ * - postfilter -> (filter, prefilter) dep is ok
+ * - idempotent -> (any) dep is OK
+ *
+ * Otherwise, emit error
+ * However, even if everything is fine this dep is useless ¯\_(ツ)_/¯
+ */
+ gboolean ok_dep = FALSE;
+
+ if (it->is_filter) {
+ if (dit->type & SYMBOL_TYPE_PREFILTER) {
+ ok_dep = TRUE;
+ }
+ }
+ else if (it->type & SYMBOL_TYPE_POSTFILTER) {
+ if (dit->type & SYMBOL_TYPE_PREFILTER) {
+ ok_dep = TRUE;
+ }
+ }
+ else if (it->type & SYMBOL_TYPE_IDEMPOTENT) {
+ if (dit->type & (SYMBOL_TYPE_PREFILTER|SYMBOL_TYPE_POSTFILTER)) {
+ ok_dep = TRUE;
+ }
+ }
+ else if (it->type & SYMBOL_TYPE_PREFILTER) {
+ if (it->priority < dit->priority) {
+ /* Also OK */
+ ok_dep = TRUE;
+ }
+ }
+
+ if (!ok_dep) {
+ msg_err_cache ("cannot add dependency from %s on %s: invalid symbol types",
+ dep->sym, dit->symbol);
+
+ return;
+ }
+ }
+ else {
+ if (dit->id == it->id) {
+ msg_err_cache ("cannot add dependency on self: %s -> %s "
+ "(resolved to %s)",
+ it->symbol, dep->sym, dit->symbol);
+ } else {
+ rdep = rspamd_mempool_alloc (cache->static_pool,
+ sizeof (*rdep));
+
+ rdep->sym = dep->sym;
+ rdep->item = it;
+ rdep->id = it->id;
+ g_assert (dit->rdeps != NULL);
+ g_ptr_array_add (dit->rdeps, rdep);
+ dep->item = dit;
+ dep->id = dit->id;
+
+ msg_debug_cache ("add dependency from %d on %d", it->id,
+ dit->id);
+ }
+ }
+ }
+ else if (dep->id >= 0) {
+ msg_err_cache ("cannot find dependency on symbol %s for symbol %s",
+ dep->sym, it->symbol);
+
+ return;
+ }
+
+ if (vdit) {
+ /* Use virtual symbol to propagate deps */
+ rspamd_symcache_propagate_dep (cache, it, vdit);
+ }
+}
+
/* Sort items in logical order */
static void
rspamd_symcache_post_init (struct rspamd_symcache *cache)
{
- struct rspamd_symcache_item *it, *dit;
- struct cache_dependency *dep, *rdep;
+ struct rspamd_symcache_item *it, *vit;
+ struct cache_dependency *dep;
struct delayed_cache_dependency *ddep;
struct delayed_cache_condition *dcond;
GList *cur;
@@ -548,6 +676,7 @@ rspamd_symcache_post_init (struct rspamd_symcache *cache)
while (cur) {
ddep = cur->data;
+ vit = rspamd_symcache_find_filter (cache, ddep->from, false);
it = rspamd_symcache_find_filter (cache, ddep->from, true);
if (it == NULL) {
@@ -555,9 +684,9 @@ rspamd_symcache_post_init (struct rspamd_symcache *cache)
"%s is missing", ddep->from, ddep->to, ddep->from);
}
else {
- msg_debug_cache ("delayed between %s(%d) -> %s", ddep->from,
- it->id, ddep->to);
- rspamd_symcache_add_dependency (cache, it->id, ddep->to);
+ msg_debug_cache ("delayed between %s(%d:%d) -> %s", ddep->from,
+ it->id, vit->id, ddep->to);
+ rspamd_symcache_add_dependency (cache, it->id, ddep->to, vit->id);
}
cur = g_list_next (cur);
@@ -585,40 +714,7 @@ rspamd_symcache_post_init (struct rspamd_symcache *cache)
PTR_ARRAY_FOREACH (cache->items_by_id, i, it) {
PTR_ARRAY_FOREACH (it->deps, j, dep) {
- dit = rspamd_symcache_find_filter (cache, dep->sym, true);
-
- if (dit != NULL) {
- if (!dit->is_filter) {
- msg_err_cache ("cannot depend on non filter symbol "
- "(%s wants to add dependency on %s)",
- dep->sym, dit->symbol);
- }
- else {
- if (dit->id == i) {
- msg_err_cache ("cannot add dependency on self: %s -> %s "
- "(resolved to %s)",
- it->symbol, dep->sym, dit->symbol);
- } else {
- rdep = rspamd_mempool_alloc (cache->static_pool,
- sizeof (*rdep));
-
- rdep->sym = dep->sym;
- rdep->item = it;
- rdep->id = i;
- g_assert (dit->rdeps != NULL);
- g_ptr_array_add (dit->rdeps, rdep);
- dep->item = dit;
- dep->id = dit->id;
-
- msg_debug_cache ("add dependency from %d on %d", it->id,
- dit->id);
- }
- }
- }
- else {
- msg_err_cache ("cannot find dependency on symbol %s for symbol %s",
- dep->sym, it->symbol);
- }
+ rspamd_symcache_process_dep (cache, it, dep);
}
if (it->deps) {
@@ -1083,15 +1179,12 @@ rspamd_symcache_add_symbol (struct rspamd_symcache *cache,
cache->used_items, item->id);
}
- if (item->is_filter) {
- /* Only plain filters can have deps and rdeps */
- item->deps = g_ptr_array_new ();
- item->rdeps = g_ptr_array_new ();
- rspamd_mempool_add_destructor (cache->static_pool,
- rspamd_ptr_array_free_hard, item->deps);
- rspamd_mempool_add_destructor (cache->static_pool,
- rspamd_ptr_array_free_hard, item->rdeps);
- }
+ item->deps = g_ptr_array_new ();
+ item->rdeps = g_ptr_array_new ();
+ rspamd_mempool_add_destructor (cache->static_pool,
+ rspamd_ptr_array_free_hard, item->deps);
+ rspamd_mempool_add_destructor (cache->static_pool,
+ rspamd_ptr_array_free_hard, item->rdeps);
if (name != NULL) {
g_hash_table_insert (cache->items_by_symbol, item->symbol, item);
@@ -2384,9 +2477,10 @@ rspamd_symcache_inc_frequency (struct rspamd_symcache *cache,
void
rspamd_symcache_add_dependency (struct rspamd_symcache *cache,
- gint id_from, const gchar *to)
+ gint id_from, const gchar *to,
+ gint virtual_id_from)
{
- struct rspamd_symcache_item *source;
+ struct rspamd_symcache_item *source, *vsource;
struct cache_dependency *dep;
g_assert (id_from >= 0 && id_from < (gint)cache->items_by_id->len);
@@ -2397,7 +2491,20 @@ rspamd_symcache_add_dependency (struct rspamd_symcache *cache,
dep->sym = rspamd_mempool_strdup (cache->static_pool, to);
/* Will be filled later */
dep->item = NULL;
+ dep->vid = -1;
g_ptr_array_add (source->deps, dep);
+
+ if (id_from != virtual_id_from) {
+ /* We need that for settings id propagation */
+ vsource = g_ptr_array_index (cache->items_by_id, virtual_id_from);
+ dep = rspamd_mempool_alloc (cache->static_pool, sizeof (*dep));
+ dep->vid = id_from;
+ dep->id = -1;
+ dep->sym = rspamd_mempool_strdup (cache->static_pool, to);
+ /* Will be filled later */
+ dep->item = NULL;
+ g_ptr_array_add (vsource->deps, dep);
+ }
}
void
diff --git a/src/libserver/rspamd_symcache.h b/src/libserver/rspamd_symcache.h
index ce2f3f7bf..6542e76ce 100644
--- a/src/libserver/rspamd_symcache.h
+++ b/src/libserver/rspamd_symcache.h
@@ -224,7 +224,8 @@ void rspamd_symcache_inc_frequency (struct rspamd_symcache *cache,
* @param to destination name
*/
void rspamd_symcache_add_dependency (struct rspamd_symcache *cache,
- gint id_from, const gchar *to);
+ gint id_from, const gchar *to,
+ gint virtual_id_from);
/**
* Add delayed dependency that is resolved on cache post-load routine
diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c
index aea0c8436..9b8c084c0 100644
--- a/src/lua/lua_config.c
+++ b/src/lua/lua_config.c
@@ -2206,7 +2206,8 @@ lua_config_register_dependency (lua_State * L)
if (child_id > 0 && parent != NULL) {
- rspamd_symcache_add_dependency (cfg->cache, child_id, parent);
+ rspamd_symcache_add_dependency (cfg->cache, child_id, parent,
+ child_id);
}
}
else {
diff --git a/src/plugins/surbl.c b/src/plugins/surbl.c
index 860f4b5e5..7da36f483 100644
--- a/src/plugins/surbl.c
+++ b/src/plugins/surbl.c
@@ -868,7 +868,7 @@ surbl_module_parse_rule (const ucl_object_t* value, struct rspamd_config* cfg)
1,
1);
rspamd_symcache_add_dependency (cfg->cache, cb_id,
- SURBL_REDIRECTOR_CALLBACK);
+ SURBL_REDIRECTOR_CALLBACK, cb_id);
/* Failure symbol */
g_string_append (sym, "_FAIL");
rspamd_symcache_add_symbol (cfg->cache, sym->str,
@@ -1205,7 +1205,7 @@ surbl_module_config (struct rspamd_config *cfg)
if (cur_suffix->options & SURBL_OPTION_CHECKDKIM) {
rspamd_symcache_add_dependency (cfg->cache,
- cur_suffix->callback_id, "DKIM_TRACE");
+ cur_suffix->callback_id, "DKIM_TRACE", cur_suffix->callback_id);
}
cur_opt = g_list_next (cur_opt);
More information about the Commits
mailing list