summaryrefslogtreecommitdiffstats
path: root/src/lua
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2012-03-30 20:54:18 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2012-03-30 20:54:18 +0400
commite5d0c7f8f6cda246eddfcab82b056650be753fe7 (patch)
tree6a2370ad9e0bd6dbf363ef0cb6927196c832c758 /src/lua
parent8e09451a57dda5becb741e289a5dbb9890747f8d (diff)
downloadrspamd-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.c18
-rw-r--r--src/lua/lua_common.h3
-rw-r--r--src/lua/lua_config.c57
-rw-r--r--src/lua/lua_task.c25
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;