Browse Source

[Project] Add some generic code to squeeze lua rules

pull/2086/head
Vsevolod Stakhov 8 years ago
parent
commit
5321190dc5
  1. 97
      lualib/lua_squeeze_rules.lua
  2. 1
      lualib/lua_util.lua
  3. 2
      rules/headers_checks.lua
  4. 4
      rules/misc.lua
  5. 84
      src/lua/lua_config.c

97
lualib/lua_squeeze_rules.lua

@ -0,0 +1,97 @@
--[[
Copyright (c) 2018, Vsevolod Stakhov <vsevolod@highsecure.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
]]--
local exports = {}
local logger = require 'rspamd_logger'
-- Squeezed rules part
local squeezed_rules = {} -- plain vector of all rules squeezed
local squeezed_symbols = {} -- indexed by name of symbol
local squeezed_deps = {} -- squeezed deps
local SN = 'lua_squeeze'
local squeeze_function_id
local function lua_squeeze_function(task)
if not squeezed_symbols then
for k,v in pairs(squeezed_symbols) do
if not squeezed_exceptions[k] then
logger.debugm(SN, task, 'added squeezed rule: %s', k)
table.insert(squeezed_rules, v)
else
logger.debugm(SN, task, 'skipped squeezed rule: %s', k)
end
end
squeezed_symbols = nil
end
for _,func in ipairs(squeezed_rules) do
local ret = func(task)
if ret then
-- Function has returned something, so it is rule, not a plugin
logger.errx(task, 'hui: %s', ret)
end
end
end
exports.squeeze_rule = function(s, func)
if s then
if not squeezed_symbols[s] then
squeezed_symbols[s] = {
cb = func,
order = 0,
}
logger.debugm(SN, rspamd_config, 'squeezed rule: %s', s)
else
logger.warnx(rspamd_config, 'duplicate symbol registered: %s, skip', s)
end
else
-- Unconditionally add function to the squeezed rules
logger.debugm(SN, rspamd_config, 'squeezed unnamed rule: %s', #squeezed_rules)
table.insert(squeezed_rules, func)
end
if not squeeze_function_id then
squeeze_function_id = rspamd_config:register_symbol{
type = 'callback',
callback = lua_squeeze_function,
name = 'LUA_SQUEEZE',
description = 'Meta rule for Lua rules that can be squeezed',
no_squeeze = true, -- to avoid infinite recursion
}
end
return squeeze_function_id
end
exports.squeeze_dependency = function(from, to)
logger.debugm(SN, rspamd_config, 'squeeze dep %s->%s', to, from)
if not squeezed_deps[to] then
squeezed_deps[to] = {}
end
if not squeezed_symbols[to][from] then
squeezed_symbols[to][from] = true
else
logger.warnx('duplicate dependency %s->%s', to, from)
end
return true
end
return exports

1
lualib/lua_util.lua

@ -22,6 +22,7 @@ limitations under the License.
local exports = {}
local lpeg = require 'lpeg'
local split_grammar = {}
local function rspamd_str_split(s, sep)
local gr = split_grammar[sep]

2
rules/headers_checks.lua

@ -310,7 +310,7 @@ rspamd_config:register_symbol{
group = 'headers',
}
rspamd_config:register_dependency(check_replyto_id, 'FROM_NAME_HAS_TITLE')
rspamd_config:register_dependency('CHECK_REPLYTO', 'FROM_NAME_HAS_TITLE')
local check_mime_id = rspamd_config:register_symbol{
name = 'CHECK_MIME',

4
rules/misc.lua

@ -338,8 +338,8 @@ local freemail_reply_neq_from_id = rspamd_config:register_symbol({
score = 3.0,
group = 'headers',
})
rspamd_config:register_dependency(freemail_reply_neq_from_id, 'FREEMAIL_REPLYTO')
rspamd_config:register_dependency(freemail_reply_neq_from_id, 'FREEMAIL_FROM')
rspamd_config:register_dependency('FREEMAIL_REPLYTO_NEQ_FROM_DOM', 'FREEMAIL_REPLYTO')
rspamd_config:register_dependency('FREEMAIL_REPLYTO_NEQ_FROM_DOM', 'FREEMAIL_FROM')
rspamd_config.OMOGRAPH_URL = {
callback = function(task)

84
src/lua/lua_config.c

@ -1277,13 +1277,13 @@ rspamd_register_symbol_fromlua (lua_State *L,
if (ref != -1) {
/*
* We call for routine called lua_util.squeeze_rule if it exists
* We call for routine called lua_squeeze_rules.squeeze_rule if it exists
*/
lua_pushcfunction (L, &rspamd_lua_traceback);
err_idx = lua_gettop (L);
if (!no_squeeze && (type & (SYMBOL_TYPE_CALLBACK|SYMBOL_TYPE_NORMAL)) &&
rspamd_lua_require_function (L, "lua_util", "squeeze_rule")) {
rspamd_lua_require_function (L, "lua_squeeze_rules", "squeeze_rule")) {
if (name) {
lua_pushstring (L, name);
}
@ -1297,14 +1297,16 @@ rspamd_register_symbol_fromlua (lua_State *L,
/* Now call for squeeze function */
if (lua_pcall (L, 2, 1, err_idx) != 0) {
GString *tb = lua_touserdata (L, -1);
msg_err_config ("call to finishing script failed: %v", tb);
msg_err_config ("call to squeeze_rule failed: %v", tb);
if (tb) {
g_string_free (tb, TRUE);
}
}
if (!lua_toboolean (L, -1)) {
ret = lua_tonumber (L, -1);
if (ret == -1) {
/* Do direct registration */
cd = rspamd_mempool_alloc0 (cfg->cfg_pool,
sizeof (struct lua_callback_data));
@ -1324,6 +1326,9 @@ rspamd_register_symbol_fromlua (lua_State *L,
cd,
type,
parent);
rspamd_mempool_add_destructor (cfg->cfg_pool,
(rspamd_mempool_destruct_t)lua_destroy_cfg_symbol,
cd);
}
}
else {
@ -1345,6 +1350,9 @@ rspamd_register_symbol_fromlua (lua_State *L,
cd,
type,
parent);
rspamd_mempool_add_destructor (cfg->cfg_pool,
(rspamd_mempool_destruct_t)lua_destroy_cfg_symbol,
cd);
}
/* Cleanup lua stack */
@ -1360,10 +1368,6 @@ rspamd_register_symbol_fromlua (lua_State *L,
parent);
}
rspamd_mempool_add_destructor (cfg->cfg_pool,
(rspamd_mempool_destruct_t)lua_destroy_cfg_symbol,
cd);
return ret;
}
@ -1812,12 +1816,52 @@ lua_config_register_callback_symbol_priority (lua_State * L)
return 1;
}
static gboolean
rspamd_lua_squeeze_dependency (lua_State *L, struct rspamd_config *cfg,
const gchar *name,
const gchar *from)
{
gint err_idx;
gboolean ret = FALSE;
lua_pushcfunction (L, &rspamd_lua_traceback);
err_idx = lua_gettop (L);
if (rspamd_lua_require_function (L, "lua_squeeze_rules", "squeeze_dependency")) {
lua_pushstring (L, name);
if (from) {
lua_pushstring (L, from);
}
else {
lua_pushnil (L);
}
if (lua_pcall (L, 2, 1, err_idx) != 0) {
GString *tb = lua_touserdata (L, -1);
msg_err_config ("call to squeeze_dependency script failed: %v", tb);
if (tb) {
g_string_free (tb, TRUE);
}
}
else {
ret = lua_toboolean (L, -1);
}
}
lua_settop (L, err_idx - 1);
return ret;
}
static gint
lua_config_register_dependency (lua_State * L)
{
struct rspamd_config *cfg = lua_check_config (L, 1);
const gchar *name = NULL, *from = NULL;
gint id;
gboolean skip_squeeze = FALSE;
if (cfg == NULL) {
lua_error (L);
@ -1828,16 +1872,36 @@ lua_config_register_dependency (lua_State * L)
id = luaL_checknumber (L, 2);
name = luaL_checkstring (L, 3);
if (lua_isboolean (L, 4)) {
skip_squeeze = lua_toboolean (L, 4);
}
msg_warn_config ("calling for obsolete method to register deps for symbol %d->%s",
id, name);
if (id > 0 && name != NULL) {
rspamd_symbols_cache_add_dependency (cfg->cache, id, name);
if (skip_squeeze || !rspamd_lua_squeeze_dependency (L, cfg, name,
rspamd_symbols_cache_symbol_by_id (cfg->cache, id))) {
rspamd_symbols_cache_add_dependency (cfg->cache, id, name);
}
}
}
else {
from = luaL_checkstring (L,2);
name = luaL_checkstring (L, 3);
if (lua_isboolean (L, 4)) {
skip_squeeze = lua_toboolean (L, 4);
}
if (from != NULL && name != NULL) {
rspamd_symbols_cache_add_delayed_dependency (cfg->cache, from, name);
if (skip_squeeze || !rspamd_lua_squeeze_dependency (L, cfg, name, from)) {
rspamd_symbols_cache_add_delayed_dependency (cfg->cache, from,
name);
}
}
}

Loading…
Cancel
Save