diff options
author | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2012-03-30 20:54:18 +0400 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@rambler-co.ru> | 2012-03-30 20:54:18 +0400 |
commit | e5d0c7f8f6cda246eddfcab82b056650be753fe7 (patch) | |
tree | 6a2370ad9e0bd6dbf363ef0cb6927196c832c758 /src/lua | |
parent | 8e09451a57dda5becb741e289a5dbb9890747f8d (diff) | |
download | rspamd-e5d0c7f8f6cda246eddfcab82b056650be753fe7.tar.gz rspamd-e5d0c7f8f6cda246eddfcab82b056650be753fe7.zip |
* Implement pre-filters that realizes concepts to check mail by some absolute values like:
- greylisting
- DNS BL/WL
- ratelimits
Diffstat (limited to 'src/lua')
-rw-r--r-- | src/lua/lua_common.c | 18 | ||||
-rw-r--r-- | src/lua/lua_common.h | 3 | ||||
-rw-r--r-- | src/lua/lua_config.c | 57 | ||||
-rw-r--r-- | src/lua/lua_task.c | 25 |
4 files changed, 102 insertions, 1 deletions
diff --git a/src/lua/lua_common.c b/src/lua/lua_common.c index 8fbff979c..4a62a7d02 100644 --- a/src/lua/lua_common.c +++ b/src/lua/lua_common.c @@ -219,6 +219,22 @@ luaopen_logger (lua_State * L) return 1; } +static void +lua_add_actions_global (lua_State *L) +{ + gint i; + + lua_newtable (L); + + for (i = METRIC_ACTION_REJECT; i <= METRIC_ACTION_NOACTION; i ++) { + lua_pushstring (L, str_action_metric (i)); + lua_pushinteger (L, i); + lua_settable (L, -3); + } + /* Set global table */ + lua_setglobal (L, "rspamd_actions"); +} + void init_lua (struct config_file *cfg) { @@ -253,6 +269,8 @@ init_lua (struct config_file *cfg) (void)luaopen_http (L); (void)luaopen_redis (L); (void)luaopen_upstream (L); + (void)lua_add_actions_global (L); + cfg->lua_state = L; memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func)lua_close, L); diff --git a/src/lua/lua_common.h b/src/lua/lua_common.h index adb87135e..c138a35a2 100644 --- a/src/lua/lua_common.h +++ b/src/lua/lua_common.h @@ -17,7 +17,7 @@ extern const luaL_reg null_reg[]; extern GMutex *lua_mtx; -#define RSPAMD_LUA_API_VERSION 10 +#define RSPAMD_LUA_API_VERSION 11 /* Common utility functions */ @@ -71,6 +71,7 @@ gint lua_call_chain_filter (const gchar *function, struct worker_task *task, gin double lua_consolidation_func (struct worker_task *task, const gchar *metric_name, const gchar *function_name); gboolean lua_call_expression_func (const gchar *module, const gchar *symbol, struct worker_task *task, GList *args, gboolean *res); void lua_call_post_filters (struct worker_task *task); +void lua_call_pre_filters (struct worker_task *task); void add_luabuf (const gchar *line); /* Classify functions */ diff --git a/src/lua/lua_config.c b/src/lua/lua_config.c index bdb4ce056..0e63f6421 100644 --- a/src/lua/lua_config.c +++ b/src/lua/lua_config.c @@ -44,6 +44,7 @@ LUA_FUNCTION_DEF (config, register_symbol); LUA_FUNCTION_DEF (config, register_virtual_symbol); LUA_FUNCTION_DEF (config, register_callback_symbol); LUA_FUNCTION_DEF (config, register_callback_symbol_priority); +LUA_FUNCTION_DEF (config, register_pre_filter); LUA_FUNCTION_DEF (config, register_post_filter); LUA_FUNCTION_DEF (config, register_module_option); LUA_FUNCTION_DEF (config, get_api_version); @@ -61,6 +62,7 @@ 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_module_option), + LUA_INTERFACE_DEF (config, register_pre_filter), LUA_INTERFACE_DEF (config, register_post_filter), LUA_INTERFACE_DEF (config, get_api_version), {"__tostring", lua_class_tostring}, @@ -489,6 +491,61 @@ lua_config_register_post_filter (lua_State *L) return 1; } +void +lua_call_pre_filters (struct worker_task *task) +{ + struct lua_callback_data *cd; + struct worker_task **ptask; + GList *cur; + + g_mutex_lock (lua_mtx); + cur = task->cfg->pre_filters; + while (cur) { + cd = cur->data; + if (cd->cb_is_ref) { + lua_rawgeti (cd->L, LUA_REGISTRYINDEX, cd->callback.ref); + } + else { + lua_getglobal (cd->L, cd->callback.name); + } + ptask = lua_newuserdata (cd->L, sizeof (struct worker_task *)); + lua_setclass (cd->L, "rspamd{task}", -1); + *ptask = task; + + if (lua_pcall (cd->L, 1, 0, 0) != 0) { + msg_info ("call to %s failed: %s", cd->cb_is_ref ? "local function" : + cd->callback.name, lua_tostring (cd->L, -1)); + } + cur = g_list_next (cur); + } + g_mutex_unlock (lua_mtx); +} + +static gint +lua_config_register_pre_filter (lua_State *L) +{ + struct config_file *cfg = lua_check_config (L); + struct lua_callback_data *cd; + + if (cfg) { + cd = memory_pool_alloc (cfg->cfg_pool, sizeof (struct lua_callback_data)); + if (lua_type (L, 2) == LUA_TSTRING) { + cd->callback.name = memory_pool_strdup (cfg->cfg_pool, luaL_checkstring (L, 2)); + cd->cb_is_ref = FALSE; + } + else { + lua_pushvalue (L, 2); + /* Get a reference */ + cd->callback.ref = luaL_ref (L, LUA_REGISTRYINDEX); + cd->cb_is_ref = TRUE; + } + cd->L = L; + cfg->pre_filters = g_list_prepend (cfg->pre_filters, cd); + memory_pool_add_destructor (cfg->cfg_pool, (pool_destruct_func)lua_destroy_cfg_symbol, cd); + } + return 1; +} + static gint lua_config_add_radix_map (lua_State *L) { diff --git a/src/lua/lua_task.c b/src/lua/lua_task.c index d28d897f6..d205016e0 100644 --- a/src/lua/lua_task.c +++ b/src/lua/lua_task.c @@ -45,6 +45,7 @@ extern stat_file_t* get_statfile_by_symbol (statfile_pool_t *pool, struct classi /* Task methods */ LUA_FUNCTION_DEF (task, get_message); LUA_FUNCTION_DEF (task, insert_result); +LUA_FUNCTION_DEF (task, set_pre_result); LUA_FUNCTION_DEF (task, get_urls); LUA_FUNCTION_DEF (task, get_emails); LUA_FUNCTION_DEF (task, get_text_parts); @@ -75,6 +76,7 @@ LUA_FUNCTION_DEF (task, learn_statfile); static const struct luaL_reg tasklib_m[] = { LUA_INTERFACE_DEF (task, get_message), LUA_INTERFACE_DEF (task, insert_result), + LUA_INTERFACE_DEF (task, set_pre_result), LUA_INTERFACE_DEF (task, get_urls), LUA_INTERFACE_DEF (task, get_emails), LUA_INTERFACE_DEF (task, get_text_parts), @@ -233,6 +235,29 @@ lua_task_insert_result (lua_State * L) return 1; } +static gint +lua_task_set_pre_result (lua_State * L) +{ + struct worker_task *task = lua_check_task (L); + gchar *action_str; + guint action; + + if (task != NULL) { + action = luaL_checkinteger (L, 2); + if (action < task->pre_result.action) { + task->pre_result.action = action; + if (lua_gettop (L) >= 3) { + action_str = memory_pool_strdup (task->task_pool, luaL_checkstring (L, 3)); + task->pre_result.str = action_str; + } + else { + task->pre_result.str = NULL; + } + } + } + return 1; +} + struct lua_tree_cb_data { lua_State *L; int i; |