diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-08-27 14:36:18 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2015-08-27 17:36:29 +0100 |
commit | a3e19e37062d2debcb1c5e9b88623d35b643cb7e (patch) | |
tree | cb67edec0bbc198ac40f2c44e677c1c9b5b585e4 /src | |
parent | ba2d5a67c87589dbb87cbf9804600ae28670dc8d (diff) | |
download | rspamd-a3e19e37062d2debcb1c5e9b88623d35b643cb7e.tar.gz rspamd-a3e19e37062d2debcb1c5e9b88623d35b643cb7e.zip |
Add possibility to create conditions for rules.
Diffstat (limited to 'src')
-rw-r--r-- | src/libserver/symbols_cache.c | 71 |
1 files changed, 53 insertions, 18 deletions
diff --git a/src/libserver/symbols_cache.c b/src/libserver/symbols_cache.c index 8bb3a2dad..bf363b499 100644 --- a/src/libserver/symbols_cache.c +++ b/src/libserver/symbols_cache.c @@ -28,6 +28,7 @@ #include "message.h" #include "symbols_cache.h" #include "cfg_file.h" +#include "lua/lua_common.h" static const guchar rspamd_symbols_cache_magic[8] = {'r', 's', 'c', 1, 0, 0, 0, 0 }; @@ -75,6 +76,9 @@ struct cache_item { symbol_func_t func; gpointer user_data; + /* Condition of execution */ + gint condition_cb; + /* Parent symbol id for virtual symbols */ gint parent; /* Priority */ @@ -869,34 +873,65 @@ rspamd_symbols_cache_check_symbol (struct rspamd_task *task, guint pending_before, pending_after; double t1, t2; guint64 diff; + struct rspamd_task **ptask; + lua_State *L; + gboolean check = TRUE; if (item->type & (SYMBOL_TYPE_NORMAL|SYMBOL_TYPE_CALLBACK)) { g_assert (item->func != NULL); /* Check has been started */ setbit (checkpoint->processed_bits, item->id * 2); - t1 = rspamd_get_ticks (); - pending_before = rspamd_session_events_pending (task->s); - /* Watch for events appeared */ - rspamd_session_watch_start (task->s, rspamd_symbols_cache_watcher_cb, - item); - - item->func (task, item->user_data); - - t2 = rspamd_get_ticks (); - diff = (t2 - t1) * 1000000; - rspamd_set_counter (item, diff); - rspamd_session_watch_stop (task->s); - pending_after = rspamd_session_events_pending (task->s); - - if (pending_before == pending_after) { - /* No new events registered */ + + if (item->condition_cb != -1) { + /* We also executes condition callback to check if we need this symbol */ + L = task->cfg->lua_state; + lua_rawgeti (L, LUA_REGISTRYINDEX, item->condition_cb); + ptask = lua_newuserdata (L, sizeof (struct rspamd_task *)); + rspamd_lua_setclass (L, "rspamd{task}", -1); + *ptask = task; + + if (lua_pcall (L, 1, 1, 0) != 0) { + msg_info ("call to condition for %s failed: %s", + item->symbol, lua_tostring (L, -1)); + } + else { + check = lua_toboolean (L, -1); + lua_pop (L, 1); + } + } + + if (check) { + t1 = rspamd_get_ticks (); + pending_before = rspamd_session_events_pending (task->s); + /* Watch for events appeared */ + rspamd_session_watch_start (task->s, rspamd_symbols_cache_watcher_cb, + item); + + item->func (task, item->user_data); + + t2 = rspamd_get_ticks (); + diff = (t2 - t1) * 1000000; + rspamd_set_counter (item, diff); + rspamd_session_watch_stop (task->s); + pending_after = rspamd_session_events_pending (task->s); + + if (pending_before == pending_after) { + /* No new events registered */ + setbit (checkpoint->processed_bits, item->id * 2 + 1); + + return TRUE; + } + + return FALSE; + } + else { + msg_debug ("skipping check of %s as its condition is false", + item->symbol); setbit (checkpoint->processed_bits, item->id * 2 + 1); return TRUE; } - - return FALSE; } else { setbit (checkpoint->processed_bits, item->id * 2); |