summaryrefslogtreecommitdiffstats
path: root/src/filter.c
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@rambler-co.ru>2009-07-13 20:54:13 +0400
committerVsevolod Stakhov <vsevolod@rambler-co.ru>2009-07-13 20:54:13 +0400
commita8cdd33ac7ee59e195dca03a395c264877ee5168 (patch)
tree077413b678005aad4f66dbeae82a982cb71ce75f /src/filter.c
parent74b38eb87d0ee6e401e06d8c604d55be2d93a1b2 (diff)
downloadrspamd-a8cdd33ac7ee59e195dca03a395c264877ee5168.tar.gz
rspamd-a8cdd33ac7ee59e195dca03a395c264877ee5168.zip
* Rework the whole filters system
* Add metrics optimization and symbols cache * Change all plugins [DRAGONS]: not for production usage, some things are still not working!
Diffstat (limited to 'src/filter.c')
-rw-r--r--src/filter.c199
1 files changed, 53 insertions, 146 deletions
diff --git a/src/filter.c b/src/filter.c
index 1c45f0886..2bfd2bc36 100644
--- a/src/filter.c
+++ b/src/filter.c
@@ -144,7 +144,7 @@ factor_consolidation_func (struct worker_task *task, const char *metric_name, co
* Call perl or C module function for specified part of message
*/
static void
-call_filter_by_name (struct worker_task *task, const char *name, enum filter_type filt_type, enum script_type sc_type)
+call_filter_by_name (struct worker_task *task, const char *name, enum filter_type filt_type)
{
struct module_ctx *c_module;
int res = 0;
@@ -154,20 +154,7 @@ call_filter_by_name (struct worker_task *task, const char *name, enum filter_typ
c_module = g_hash_table_lookup (task->worker->srv->cfg->c_modules, name);
if (c_module) {
res = 1;
- switch (sc_type) {
- case SCRIPT_HEADER:
- c_module->header_filter (task);
- break;
- case SCRIPT_MIME:
- c_module->mime_filter (task);
- break;
- case SCRIPT_URL:
- c_module->url_filter (task);
- break;
- case SCRIPT_MESSAGE:
- c_module->message_filter (task);
- break;
- }
+ c_module->filter (task);
}
else {
msg_debug ("call_filter_by_name: %s is not a C module", name);
@@ -176,35 +163,9 @@ call_filter_by_name (struct worker_task *task, const char *name, enum filter_typ
case PERL_FILTER:
res = 1;
#ifndef WITHOUT_PERL
- switch (sc_type) {
- case SCRIPT_HEADER:
- perl_call_header_filter (name, task);
- break;
- case SCRIPT_MIME:
- perl_call_mime_filter (name, task);
- break;
- case SCRIPT_URL:
- perl_call_url_filter (name, task);
- break;
- case SCRIPT_MESSAGE:
- perl_call_message_filter (name, task);
- break;
- }
+ perl_call_filter (name, task);
#elif defined(WITH_LUA)
- switch (sc_type) {
- case SCRIPT_HEADER:
- lua_call_header_filter (name, task);
- break;
- case SCRIPT_MIME:
- lua_call_mime_filter (name, task);
- break;
- case SCRIPT_URL:
- lua_call_url_filter (name, task);
- break;
- case SCRIPT_MESSAGE:
- lua_call_message_filter (name, task);
- break;
- }
+ lua_call_filter (name, task);
#else
msg_err ("call_filter_by_name: trying to call perl function while perl support is disabled %s", name);
#endif
@@ -250,131 +211,77 @@ metric_process_callback_forced (gpointer key, gpointer value, void *data)
metric_process_callback_common (key, value, data, TRUE);
}
+/* Return true if metric has score that is more than spam score for it */
+static gboolean
+check_metric_is_spam (struct worker_task *task, struct metric *metric)
+{
+ struct metric_result *res;
+
+ res = g_hash_table_lookup (task->results, metric->name);
+ if (res) {
+ return res->score >= metric->required_score;
+ }
+
+ return FALSE;
+}
+
static int
continue_process_filters (struct worker_task *task)
{
GList *cur = task->save.entry;
- struct filter *filt = cur->data;
+ struct cache_item *item = task->save.item;
+
+ struct metric *metric = cur->data;
- cur = g_list_next (cur);
- /* Note: no breaks in this case! */
- switch (task->save.type) {
- case SCRIPT_HEADER:
- while (cur) {
- filt = cur->data;
- call_filter_by_name (task, filt->func_name, filt->type, SCRIPT_HEADER);
- if (task->save.saved) {
- task->save.entry = cur;
- task->save.type = SCRIPT_HEADER;
- return 0;
- }
- cur = g_list_next (cur);
- }
- /* Process mime filters */
- cur = g_list_first (task->worker->srv->cfg->mime_filters);
- case SCRIPT_MIME:
- while (cur) {
- filt = cur->data;
- call_filter_by_name (task, filt->func_name, filt->type, SCRIPT_MIME);
- if (task->save.saved) {
- task->save.entry = cur;
- task->save.type = SCRIPT_MIME;
- return 0;
- }
- cur = g_list_next (cur);
- }
- /* Process url filters */
- cur = g_list_first (task->worker->srv->cfg->url_filters);
- case SCRIPT_URL:
- while (cur) {
- filt = cur->data;
- call_filter_by_name (task, filt->func_name, filt->type, SCRIPT_URL);
- if (task->save.saved) {
- task->save.entry = cur;
- task->save.type = SCRIPT_URL;
- return 0;
- }
- cur = g_list_next (cur);
+ while (cur) {
+ metric = cur->data;
+ while (call_symbol_callback (task, metric->cache, &item)) {
+ /* call_filter_by_name (task, filt->func_name, filt->type, SCRIPT_HEADER); */
+ if (task->save.saved) {
+ task->save.entry = cur;
+ task->save.item = item;
+ return 0;
}
- /* Process message filters */
- cur = g_list_first (task->worker->srv->cfg->message_filters);
- case SCRIPT_MESSAGE:
- while (cur) {
- filt = cur->data;
- call_filter_by_name (task, filt->func_name, filt->type, SCRIPT_MESSAGE);
- if (task->save.saved) {
- task->save.entry = cur;
- task->save.type = SCRIPT_MESSAGE;
- return 0;
- }
- cur = g_list_next (cur);
+ else if (check_metric_is_spam (task, metric)) {
+ break;
}
- /* Process all statfiles */
- process_statfiles (task);
- /* XXX: ugly direct call */
- task->dispatcher->write_callback (task);
- return 1;
+ }
+ cur = g_list_next (cur);
}
- return -1;
+ /* Process all statfiles */
+ process_statfiles (task);
+ /* XXX: ugly direct call */
+ task->dispatcher->write_callback (task);
+ return 1;
}
int
process_filters (struct worker_task *task)
{
GList *cur;
- struct filter *filt;
+ struct metric *metric;
+ struct cache_item *item = NULL;
if (task->save.saved) {
task->save.saved = 0;
return continue_process_filters (task);
}
- /* Process filters in order that they are listed in config file */
- cur = task->worker->srv->cfg->header_filters;
- while (cur) {
- filt = cur->data;
- call_filter_by_name (task, filt->func_name, filt->type, SCRIPT_HEADER);
- if (task->save.saved) {
- task->save.entry = cur;
- task->save.type = SCRIPT_HEADER;
- return 0;
- }
- cur = g_list_next (cur);
- }
-
- cur = task->worker->srv->cfg->mime_filters;
+ /* Process metrics symbols */
+ cur = task->worker->srv->cfg->metrics_list;
while (cur) {
- filt = cur->data;
- call_filter_by_name (task, filt->func_name, filt->type, SCRIPT_MIME);
- if (task->save.saved) {
- task->save.entry = cur;
- task->save.type = SCRIPT_MIME;
- return 0;
- }
- cur = g_list_next (cur);
- }
-
- cur = task->worker->srv->cfg->url_filters;
- while (cur) {
- filt = cur->data;
- call_filter_by_name (task, filt->func_name, filt->type, SCRIPT_URL);
- if (task->save.saved) {
- task->save.entry = cur;
- task->save.type = SCRIPT_URL;
- return 0;
- }
- cur = g_list_next (cur);
- }
-
- cur = task->worker->srv->cfg->message_filters;
- while (cur) {
- filt = cur->data;
- call_filter_by_name (task, filt->func_name, filt->type, SCRIPT_MESSAGE);
- if (task->save.saved) {
- task->save.entry = cur;
- task->save.type = SCRIPT_MESSAGE;
- return 0;
+ metric = cur->data;
+ while (call_symbol_callback (task, metric->cache, &item)) {
+ /* call_filter_by_name (task, filt->func_name, filt->type, SCRIPT_HEADER); */
+ if (task->save.saved) {
+ task->save.entry = cur;
+ task->save.item = item;
+ return 0;
+ }
+ else if (check_metric_is_spam (task, metric)) {
+ break;
+ }
}
cur = g_list_next (cur);
}