aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2015-08-27 14:36:18 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2015-08-27 17:36:29 +0100
commita3e19e37062d2debcb1c5e9b88623d35b643cb7e (patch)
treecb67edec0bbc198ac40f2c44e677c1c9b5b585e4 /src
parentba2d5a67c87589dbb87cbf9804600ae28670dc8d (diff)
downloadrspamd-a3e19e37062d2debcb1c5e9b88623d35b643cb7e.tar.gz
rspamd-a3e19e37062d2debcb1c5e9b88623d35b643cb7e.zip
Add possibility to create conditions for rules.
Diffstat (limited to 'src')
-rw-r--r--src/libserver/symbols_cache.c71
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);