Browse Source

* Implement composite symbols

rspamd-0.5
cebka@cebka-laptop 17 years ago
parent
commit
cd9b528a22
  1. 3
      cfg_file.h
  2. 1
      cfg_file.l
  3. 23
      cfg_file.y
  4. 3
      cfg_utils.c
  5. 130
      filter.c
  6. 9
      filter.h
  7. 1
      main.h
  8. 20
      protocol.c

3
cfg_file.h

@ -47,6 +47,7 @@
fprintf (stderr, fmt, ##__VA_ARGS__); \
fprintf (stderr, "\n")
struct expression;
enum { VAL_UNDEF=0, VAL_TRUE, VAL_FALSE };
@ -119,6 +120,7 @@ struct config_file {
GHashTable* metrics;
GHashTable* factors;
GHashTable* c_modules;
GHashTable* composite_symbols;
};
int add_memcached_server (struct config_file *cf, char *str);
@ -132,6 +134,7 @@ char parse_flag (const char *str);
char* substitute_variable (struct config_file *cfg, char *str, u_char recursive);
void post_load_config (struct config_file *cfg);
struct rspamd_regexp* parse_regexp (memory_pool_t *pool, char *line);
struct expression* parse_expression (memory_pool_t *pool, char *line);
int yylex (void);
int yyparse (void);

1
cfg_file.l

@ -24,6 +24,7 @@ extern struct config_file *cfg;
^[ \t]*#.* /* ignore comments */;
.include BEGIN(incl);
.module BEGIN(module);
composites return COMPOSITES;
tempdir return TEMPDIR;
pidfile return PIDFILE;
workers return WORKERS;

23
cfg_file.y

@ -17,6 +17,7 @@
#include <glib.h>
#include "cfg_file.h"
#include "main.h"
#define YYDEBUG 1
@ -48,7 +49,7 @@ struct metric *cur_metric = NULL;
%token MEMCACHED WORKERS REQUIRE MODULE
%token MODULE_OPT PARAM VARIABLE
%token HEADER_FILTERS MIME_FILTERS MESSAGE_FILTERS URL_FILTERS FACTORS METRIC NAME
%token REQUIRED_SCORE FUNCTION FRACT
%token REQUIRED_SCORE FUNCTION FRACT COMPOSITES
%type <string> STRING
%type <string> VARIABLE
@ -85,6 +86,7 @@ command :
| variable
| factors
| metric
| composites
;
tempdir :
@ -351,6 +353,25 @@ requirecmd:
}
;
composites:
COMPOSITES OBRACE compositesbody EBRACE
;
compositesbody:
compositescmd SEMICOLON
| compositesbody compositescmd SEMICOLON
;
compositescmd:
QUOTEDSTRING EQSIGN QUOTEDSTRING {
struct expression *expr;
if ((expr = parse_expression (cfg->cfg_pool, $3)) == NULL) {
yyerror ("yyparse: cannot parse composite expression: %s", $3);
YYERROR;
}
g_hash_table_insert (cfg->composite_symbols, $1, expr);
}
;
module_opt:
MODULE_OPT OBRACE moduleoptbody EBRACE {
g_hash_table_insert (cfg->modules_opts, $1, cur_module_opt);

3
cfg_utils.c

@ -134,6 +134,7 @@ init_defaults (struct config_file *cfg)
cfg->metrics = g_hash_table_new (g_str_hash, g_str_equal);
cfg->factors = g_hash_table_new (g_str_hash, g_str_equal);
cfg->c_modules = g_hash_table_new (g_str_hash, g_str_equal);
cfg->composite_symbols = g_hash_table_new (g_str_hash, g_str_equal);
LIST_INIT (&cfg->perl_modules);
}
@ -151,6 +152,8 @@ free_config (struct config_file *cfg)
g_hash_table_unref (cfg->factors);
g_hash_table_remove_all (cfg->c_modules);
g_hash_table_unref (cfg->c_modules);
g_hash_table_remove_all (cfg->composite_symbols);
g_hash_table_unref (cfg->composite_symbols);
memory_pool_delete (cfg->cfg_pool);
}

130
filter.c

@ -12,7 +12,6 @@
void
insert_result (struct worker_task *task, const char *metric_name, const char *symbol, u_char flag)
{
struct filter_result *result;
struct metric *metric;
struct metric_result *metric_res;
@ -21,20 +20,18 @@ insert_result (struct worker_task *task, const char *metric_name, const char *sy
return;
}
result = memory_pool_alloc (task->task_pool, sizeof (struct filter_result));
result->symbol = symbol;
result->flag = flag;
metric_res = g_hash_table_lookup (task->results, metric_name);
if (metric_res == NULL) {
/* Create new metric chain */
metric_res = memory_pool_alloc (task->task_pool, sizeof (struct metric_result));
LIST_INIT (&metric_res->results);
metric_res->symbols = g_hash_table_new (g_str_hash, g_str_equal);
memory_pool_add_destructor (task->task_pool, (pool_destruct_func)g_hash_table_destroy, metric_res->symbols);
metric_res->metric = metric;
g_hash_table_insert (task->results, (gpointer)metric_name, metric_res);
}
LIST_INSERT_HEAD (&metric_res->results, result, next);
g_hash_table_insert (metric_res->symbols, (gpointer)symbol, GSIZE_TO_POINTER (flag));
}
/*
@ -44,28 +41,31 @@ double
factor_consolidation_func (struct worker_task *task, const char *metric_name)
{
struct metric_result *metric_res;
struct filter_result *result;
double *factor;
double res = 0.;
GList *symbols = NULL, *cur;
metric_res = g_hash_table_lookup (task->results, metric_name);
if (metric_res == NULL) {
return res;
}
LIST_FOREACH (result, &metric_res->results, next) {
if (result->flag) {
factor = g_hash_table_lookup (task->worker->srv->cfg->factors, result->symbol);
if (factor == NULL) {
/* Default multiplier is 1 */
res ++;
}
else {
res += *factor;
}
symbols = g_hash_table_get_keys (metric_res->symbols);
cur = g_list_first (symbols);
while (cur) {
factor = g_hash_table_lookup (task->worker->srv->cfg->factors, cur->data);
if (factor == NULL) {
/* Default multiplier is 1 */
res ++;
}
else {
res += *factor;
}
cur = g_list_next (cur);
}
g_list_free (symbols);
return res;
}
@ -240,3 +240,97 @@ process_filters (struct worker_task *task)
g_hash_table_foreach (task->results, metric_process_callback, task);
return 1;
}
struct composites_data {
struct worker_task *task;
struct metric_result *metric_res;
};
static void
composites_foreach_callback (gpointer key, gpointer value, void *data)
{
struct composites_data *cd = (struct composites_data *)data;
struct expression *expr = (struct expression *)value;
GQueue *stack;
GList *symbols = NULL, *s;
gsize cur, op1, op2;
stack = g_queue_new ();
while (expr) {
if (expr->type == EXPR_OPERAND) {
/* Find corresponding symbol */
if (g_hash_table_lookup (cd->metric_res->symbols, expr->content.operand) == NULL) {
cur = 0;
}
else {
cur = 1;
symbols = g_list_append (symbols, expr->content.operand);
}
g_queue_push_head (stack, GSIZE_TO_POINTER (cur));
}
else {
if (g_queue_is_empty (stack)) {
/* Queue has no operands for operation, exiting */
g_list_free (symbols);
g_queue_free (stack);
return;
}
switch (expr->content.operation) {
case '!':
op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack));
op1 = !op1;
g_queue_push_head (stack, GSIZE_TO_POINTER (op1));
break;
case '&':
op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack));
op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack));
g_queue_push_head (stack, GSIZE_TO_POINTER (op1 && op2));
case '|':
op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack));
op2 = GPOINTER_TO_SIZE (g_queue_pop_head (stack));
g_queue_push_head (stack, GSIZE_TO_POINTER (op1 || op2));
default:
expr = expr->next;
continue;
}
}
expr = expr->next;
}
if (!g_queue_is_empty (stack)) {
op1 = GPOINTER_TO_SIZE (g_queue_pop_head (stack));
if (op1) {
/* Remove all symbols that are in composite symbol */
s = g_list_first (symbols);
while (s) {
g_hash_table_remove (cd->metric_res->symbols, s->data);
s = g_list_next (s);
}
/* Add new symbol */
g_hash_table_insert (cd->metric_res->symbols, key, GSIZE_TO_POINTER (op1));
}
}
g_queue_free (stack);
g_list_free (symbols);
return;
}
static void
composites_metric_callback (gpointer key, gpointer value, void *data)
{
struct worker_task *task = (struct worker_task *)data;
struct composites_data *cd = memory_pool_alloc (task->task_pool, sizeof (struct composites_data));
struct metric_result *metric_res = (struct metric_result *)value;
cd->task = task;
cd->metric_res = (struct metric_result *)metric_res;
g_hash_table_foreach (task->cfg->composite_symbols, composites_foreach_callback, cd);
}
void make_composites (struct worker_task *task)
{
g_hash_table_foreach (task->results, composites_metric_callback, task);
}

9
filter.h

@ -29,20 +29,15 @@ struct metric {
double required_score;
};
struct filter_result {
const char *symbol;
u_char flag;
LIST_ENTRY (filter_result) next;
};
struct metric_result {
struct metric *metric;
double score;
LIST_HEAD (resultq, filter_result) results;
GHashTable *symbols;
};
int process_filters (struct worker_task *task);
void insert_result (struct worker_task *task, const char *metric_name, const char *symbol, u_char flag);
void make_composites (struct worker_task *task);
double factor_consolidation_func (struct worker_task *task, const char *metric_name);
#endif

1
main.h

@ -163,7 +163,6 @@ struct c_module {
};
void start_worker (struct rspamd_worker *worker, int listen_sock);
struct expression* parse_expression (memory_pool_t *pool, char *line);
#endif

20
protocol.c

@ -363,23 +363,25 @@ show_metric_symbols (gpointer metric_name, gpointer metric_value, void *user_dat
struct worker_task *task = (struct worker_task *)user_data;
int r = 0;
char outbuf[OUTBUFSIZ];
struct filter_result *result;
GList *symbols = NULL, *cur;
struct metric_result *metric_res = (struct metric_result *)metric_value;
if (task->proto == RSPAMC_PROTO) {
r = snprintf (outbuf, sizeof (outbuf), "%s: ", (char *)metric_name);
}
LIST_FOREACH (result, &metric_res->results, next) {
if (result->flag) {
if (LIST_NEXT (result, next) != NULL) {
r += snprintf (outbuf + r, sizeof (outbuf) - r, "%s,", result->symbol);
}
else {
r += snprintf (outbuf + r, sizeof (outbuf) - r, "%s", result->symbol);
}
symbols = g_hash_table_get_keys (metric_res->symbols);
cur = symbols;
while (cur) {
if (g_list_next (cur) != NULL) {
r += snprintf (outbuf + r, sizeof (outbuf) - r, "%s,", (char *)cur->data);
}
else {
r += snprintf (outbuf + r, sizeof (outbuf) - r, "%s", (char *)cur->data);
}
cur = g_list_next (cur);
}
g_list_free (symbols);
outbuf[r++] = '\r'; outbuf[r] = '\n';
bufferevent_write (task->bev, outbuf, r);
}

Loading…
Cancel
Save