Browse Source

[Feature] Support multiple conditions for symbols

tags/2.7
Vsevolod Stakhov 3 years ago
parent
commit
5ab536d145
1 changed files with 64 additions and 40 deletions
  1. 64
    40
      src/libserver/rspamd_symcache.c

+ 64
- 40
src/libserver/rspamd_symcache.c View File

#include "contrib/t1ha/t1ha.h" #include "contrib/t1ha/t1ha.h"
#include "libserver/worker_util.h" #include "libserver/worker_util.h"
#include "khash.h" #include "khash.h"
#include "utlist.h"
#include <math.h> #include <math.h>


#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L #if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
}; };
}; };


struct rspamd_symcache_condition {
gint cb;
struct rspamd_symcache_condition *prev, *next;
};

struct rspamd_symcache_item { struct rspamd_symcache_item {
/* This block is likely shared */ /* This block is likely shared */
struct rspamd_symcache_item_stat *st; struct rspamd_symcache_item_stat *st;
struct { struct {
symbol_func_t func; symbol_func_t func;
gpointer user_data; gpointer user_data;
gint condition_cb;
struct rspamd_symcache_condition *conditions;
} normal; } normal;
struct { struct {
gint parent; gint parent;
luaL_unref (dcond->L, LUA_REGISTRYINDEX, dcond->cbref); luaL_unref (dcond->L, LUA_REGISTRYINDEX, dcond->cbref);
} }
else { else {
it->specific.normal.condition_cb = dcond->cbref;
struct rspamd_symcache_condition *ncond = rspamd_mempool_alloc0 (cache->static_pool,
sizeof (*ncond));
ncond->cb = dcond->cbref;
DL_APPEND (it->specific.normal.conditions, ncond);
} }


cur = g_list_next (cur); cur = g_list_next (cur);


item->specific.normal.func = func; item->specific.normal.func = func;
item->specific.normal.user_data = user_data; item->specific.normal.user_data = user_data;
item->specific.normal.condition_cb = -1;
item->specific.normal.conditions = NULL;
} }
else { else {
/* /*
* - composite symbol * - composite symbol
*/ */
if (item->type & SYMBOL_TYPE_COMPOSITE) { if (item->type & SYMBOL_TYPE_COMPOSITE) {
item->specific.normal.condition_cb = -1;
item->specific.normal.conditions = NULL;
item->specific.normal.user_data = user_data; item->specific.normal.user_data = user_data;
g_assert (user_data != NULL); g_assert (user_data != NULL);
g_ptr_array_add (cache->composites, item); g_ptr_array_add (cache->composites, item);
item->is_filter = TRUE; item->is_filter = TRUE;
item->specific.normal.func = NULL; item->specific.normal.func = NULL;
item->specific.normal.user_data = NULL; item->specific.normal.user_data = NULL;
item->specific.normal.condition_cb = -1;
item->specific.normal.conditions = NULL;
type_str = "classifier"; type_str = "classifier";
} }
else { else {
if (!rspamd_symcache_is_item_allowed (task, item, TRUE)) { if (!rspamd_symcache_is_item_allowed (task, item, TRUE)) {
check = FALSE; check = FALSE;
} }
else if (item->specific.normal.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->specific.normal.condition_cb);
ptask = lua_newuserdata (L, sizeof (struct rspamd_task *));
rspamd_lua_setclass (L, "rspamd{task}", -1);
*ptask = task;
else if (item->specific.normal.conditions) {
struct rspamd_symcache_condition *cur_cond;

DL_FOREACH (item->specific.normal.conditions, cur_cond) {
/* We also executes condition callback to check if we need this symbol */
L = task->cfg->lua_state;
lua_rawgeti (L, LUA_REGISTRYINDEX, cur_cond->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_task ("call to condition for %s failed: %s",
item->symbol, lua_tostring (L, -1));
lua_pop (L, 1);
}
else {
check = lua_toboolean (L, -1);
lua_pop (L, 1);
}


if (lua_pcall (L, 1, 1, 0) != 0) {
msg_info_task ("call to condition for %s failed: %s",
item->symbol, lua_tostring (L, -1));
lua_pop (L, 1);
}
else {
check = lua_toboolean (L, -1);
lua_pop (L, 1);
if (!check) {
break;
}
} }


if (!check) { if (!check) {
ret = FALSE; ret = FALSE;
} }
else { else {
if (item->specific.normal.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->specific.normal.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_task ("call to condition for %s failed: %s",
item->symbol, lua_tostring (L, -1));
lua_pop (L, 1);
}
else {
ret = lua_toboolean (L, -1);
lua_pop (L, 1);
if (item->specific.normal.conditions) {
struct rspamd_symcache_condition *cur_cond;

DL_FOREACH (item->specific.normal.conditions, cur_cond) {
/*
* We also executes condition callback to check
* if we need this symbol
*/
L = task->cfg->lua_state;
lua_rawgeti (L, LUA_REGISTRYINDEX, cur_cond->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_task ("call to condition for %s failed: %s",
item->symbol, lua_tostring (L, -1));
lua_pop (L, 1);
}
else {
ret = lua_toboolean (L, -1);
lua_pop (L, 1);
}

if (!ret) {
break;
}
} }
} }
} }

Loading…
Cancel
Save