From 098bad331a1bfad297c519ae2d310eb3639b94ba Mon Sep 17 00:00:00 2001 From: Vsevolod Stakhov Date: Tue, 12 Feb 2019 15:03:30 +0000 Subject: [PATCH] [Project] Implement new flags in Lua API --- lualib/lua_squeeze_rules.lua | 10 ++- src/libserver/rspamd_symcache.c | 64 +++++++++++++- src/libserver/rspamd_symcache.h | 16 ++++ src/lua/lua_config.c | 147 ++++++++++++++++++++++++++++++++ 4 files changed, 232 insertions(+), 5 deletions(-) diff --git a/lualib/lua_squeeze_rules.lua b/lualib/lua_squeeze_rules.lua index 1df8a4ec1..0062504bc 100644 --- a/lualib/lua_squeeze_rules.lua +++ b/lualib/lua_squeeze_rules.lua @@ -322,12 +322,13 @@ exports.handle_settings = function(task, settings) local symbols_disabled = {} local symbols_enabled = {} local found = false + local disabled = false if settings.default then settings = settings.default end local function disable_all() - for k,_ in pairs(squeezed_symbols) do - if not symbols_enabled[k] then + for k,sym in pairs(squeezed_symbols) do + if not symbols_enabled[k] and not (sym.flags and sym.flags.explicit_disable) then symbols_disabled[k] = true end end @@ -336,6 +337,7 @@ exports.handle_settings = function(task, settings) if settings.symbols_enabled then disable_all() found = true + disabled = true for _,s in ipairs(settings.symbols_enabled) do if squeezed_symbols[s] then lua_util.debugm(SN, task, 'enable symbol %s as it is in `symbols_enabled`', s) @@ -346,7 +348,9 @@ exports.handle_settings = function(task, settings) end if settings.groups_enabled then - disable_all() + if not disabled then + disable_all() + end found = true for _,gr in ipairs(settings.groups_enabled) do if squeezed_groups[gr] then diff --git a/src/libserver/rspamd_symcache.c b/src/libserver/rspamd_symcache.c index 92f75ecbb..d02638add 100644 --- a/src/libserver/rspamd_symcache.c +++ b/src/libserver/rspamd_symcache.c @@ -2427,7 +2427,7 @@ rspamd_symcache_disable_symbol_perm (struct rspamd_symcache *cache, g_assert (cache != NULL); g_assert (symbol != NULL); - item = g_hash_table_lookup (cache->items_by_symbol, symbol); + item = rspamd_symcache_find_filter (cache, symbol); if (item) { item->enabled = FALSE; @@ -2443,7 +2443,7 @@ rspamd_symcache_enable_symbol_perm (struct rspamd_symcache *cache, g_assert (cache != NULL); g_assert (symbol != NULL); - item = g_hash_table_lookup (cache->items_by_symbol, symbol); + item = rspamd_symcache_find_filter (cache, symbol); if (item) { item->enabled = TRUE; @@ -2774,4 +2774,64 @@ rspamd_symcache_item_async_dec_check_full (struct rspamd_task *task, } return FALSE; +} + +gboolean +rspamd_symcache_add_symbol_flags (struct rspamd_symcache *cache, + const gchar *symbol, + guint flags) +{ + struct rspamd_symcache_item *item; + + g_assert (cache != NULL); + g_assert (symbol != NULL); + + item = rspamd_symcache_find_filter (cache, symbol); + + if (item) { + item->type |= flags; + + return TRUE; + } + + return FALSE; +} + +gboolean +rspamd_symcache_set_symbol_flags (struct rspamd_symcache *cache, + const gchar *symbol, + guint flags) +{ + struct rspamd_symcache_item *item; + + g_assert (cache != NULL); + g_assert (symbol != NULL); + + item = rspamd_symcache_find_filter (cache, symbol); + + if (item) { + item->type = flags; + + return TRUE; + } + + return FALSE; +} + +guint +rspamd_symcache_get_symbol_flags (struct rspamd_symcache *cache, + const gchar *symbol) +{ + struct rspamd_symcache_item *item; + + g_assert (cache != NULL); + g_assert (symbol != NULL); + + item = rspamd_symcache_find_filter (cache, symbol); + + if (item) { + return item->type; + } + + return 0; } \ No newline at end of file diff --git a/src/libserver/rspamd_symcache.h b/src/libserver/rspamd_symcache.h index b5e029a6b..965895221 100644 --- a/src/libserver/rspamd_symcache.h +++ b/src/libserver/rspamd_symcache.h @@ -249,7 +249,23 @@ void rspamd_symcache_enable_symbol_perm (struct rspamd_symcache *cache, struct rspamd_abstract_callback_data* rspamd_symcache_get_cbdata ( struct rspamd_symcache *cache, const gchar *symbol); +/** + * Adds flags to a symbol + * @param cache + * @param symbol + * @param flags + * @return + */ +gboolean rspamd_symcache_add_symbol_flags (struct rspamd_symcache *cache, + const gchar *symbol, + guint flags); + +gboolean rspamd_symcache_set_symbol_flags (struct rspamd_symcache *cache, + const gchar *symbol, + guint flags); +guint rspamd_symcache_get_symbol_flags (struct rspamd_symcache *cache, + const gchar *symbol); /** * Process settings for task * @param task diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c index 1b7eaaa4d..a41ffa63f 100644 --- a/src/lua/lua_config.c +++ b/src/lua/lua_config.c @@ -208,6 +208,8 @@ LUA_FUNCTION_DEF (config, get_classifier); * + `skip` if symbol should be skipped now * + `nostat` if symbol should be excluded from stat tokens * + `trivial` symbol is trivial (e.g. no network requests) + * + `explicit_disable` requires explicit disabling (e.g. via settings) + * + `ignore_passthrough` executed even if passthrough result has been set * - `parent`: id of parent symbol (useful for virtual symbols) * * @return {number} id of symbol registered @@ -262,6 +264,23 @@ rspamd_config:register_dependency('SYMBOL_FROM', 'SYMBOL_TO') */ LUA_FUNCTION_DEF (config, register_dependency); +/*** + * @method rspamd_config:get_symbol_flags(name) + * Returns symbol flags + * @param {string} name symbols's name + * @return {table|string} list of flags for symbol or nil + */ +LUA_FUNCTION_DEF (config, get_symbol_flags); + +/*** + * @method rspamd_config:add_symbol_flags(name, flags) + * Adds flags to a symbol + * @param {string} name symbols's name + * @param {table|string} flags flags to add + * @return {table|string} new set of flags + */ +LUA_FUNCTION_DEF (config, add_symbol_flags); + /** * @method rspamd_config:register_re_selector(name, selector_str) * Registers selector with the specific name to use in regular expressions in form @@ -761,6 +780,8 @@ static const struct luaL_reg configlib_m[] = { LUA_INTERFACE_DEF (config, register_callback_symbol), LUA_INTERFACE_DEF (config, register_callback_symbol_priority), LUA_INTERFACE_DEF (config, register_dependency), + LUA_INTERFACE_DEF (config, get_symbol_flags), + LUA_INTERFACE_DEF (config, add_symbol_flags), LUA_INTERFACE_DEF (config, set_metric_symbol), {"set_symbol", lua_config_set_metric_symbol}, LUA_INTERFACE_DEF (config, set_metric_action), @@ -1297,6 +1318,11 @@ rspamd_register_symbol_fromlua (lua_State *L, lua_pushboolean (L, true); lua_settable (L, -3); } + if (type & SYMBOL_TYPE_EXPLICIT_DISABLE) { + lua_pushstring (L, "explicit_disable"); + lua_pushboolean (L, true); + lua_settable (L, -3); + } /* Now call for squeeze function */ if (lua_pcall (L, 3, 1, err_idx) != 0) { @@ -1524,6 +1550,12 @@ lua_parse_symbol_flags (const gchar *str) if (strstr (str, "mime") != NULL) { ret |= SYMBOL_TYPE_MIME_ONLY; } + if (strstr (str, "ignore_passthrough") != NULL) { + ret |= SYMBOL_TYPE_IGNORE_PASSTHROUGH; + } + if (strstr (str, "explicit_disable") != NULL) { + ret |= SYMBOL_TYPE_EXPLICIT_DISABLE; + } } return ret; @@ -1579,6 +1611,121 @@ lua_parse_symbol_type (const gchar *str) return ret; } +static void +lua_push_symbol_flags (lua_State *L, guint flags) +{ + guint i = 1; + + lua_newtable (L); + + if (flags & SYMBOL_TYPE_FINE) { + lua_pushstring (L, "fine"); + lua_rawseti (L, -2, i++); + } + + if (flags & SYMBOL_TYPE_EMPTY) { + lua_pushstring (L, "empty"); + lua_rawseti (L, -2, i++); + } + + if (flags & SYMBOL_TYPE_SQUEEZED) { + lua_pushstring (L, "squeezed"); + lua_rawseti (L, -2, i++); + } + + if (flags & SYMBOL_TYPE_EXPLICIT_DISABLE) { + lua_pushstring (L, "explicit_disable"); + lua_rawseti (L, -2, i++); + } + + if (flags & SYMBOL_TYPE_IGNORE_PASSTHROUGH) { + lua_pushstring (L, "ignore_passthrough"); + lua_rawseti (L, -2, i++); + } + + if (flags & SYMBOL_TYPE_NOSTAT) { + lua_pushstring (L, "nostat"); + lua_rawseti (L, -2, i++); + } + + if (flags & SYMBOL_TYPE_IDEMPOTENT) { + lua_pushstring (L, "idempotent"); + lua_rawseti (L, -2, i++); + } + + if (flags & SYMBOL_TYPE_MIME_ONLY) { + lua_pushstring (L, "mime"); + lua_rawseti (L, -2, i++); + } + + if (flags & SYMBOL_TYPE_TRIVIAL) { + lua_pushstring (L, "trivial"); + lua_rawseti (L, -2, i++); + } + + if (flags & SYMBOL_TYPE_SKIPPED) { + lua_pushstring (L, "skip"); + lua_rawseti (L, -2, i++); + } +} + +static gint +lua_config_get_symbol_flags (lua_State *L) +{ + struct rspamd_config *cfg = lua_check_config (L, 1); + const gchar *name = luaL_checkstring (L, 2); + guint flags; + + if (cfg && name) { + flags = rspamd_symcache_get_symbol_flags (cfg->cache, + name); + + if (flags != 0) { + lua_push_symbol_flags (L, flags); + } + else { + lua_pushnil (L); + } + } + else { + return luaL_error (L, "invalid arguments"); + } + + return 1; +} + +static gint +lua_config_add_symbol_flags (lua_State *L) +{ + struct rspamd_config *cfg = lua_check_config (L, 1); + const gchar *name = luaL_checkstring (L, 2); + guint flags, new_flags = 0; + + if (cfg && name && lua_istable (L, 3)) { + + for (lua_pushnil (L); lua_next (L, 3); lua_pop (L, 1)) { + new_flags |= lua_parse_symbol_flags (lua_tostring (L, -1)); + } + + flags = rspamd_symcache_get_symbol_flags (cfg->cache, + name); + + if (flags != 0) { + rspamd_symcache_add_symbol_flags (cfg->cache, name, new_flags); + /* Push old flags */ + lua_push_symbol_flags (L, flags); + } + else { + lua_pushnil (L); + } + } + else { + return luaL_error (L, "invalid arguments"); + } + + return 1; +} + static gint lua_config_register_symbol (lua_State * L) { -- 2.39.5