diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/cfg_file.l | 1 | ||||
-rw-r--r-- | src/cfg_file.y | 15 | ||||
-rw-r--r-- | src/main.h | 1 | ||||
-rw-r--r-- | src/view.c | 46 | ||||
-rw-r--r-- | src/view.h | 2 | ||||
-rw-r--r-- | src/worker.c | 7 |
6 files changed, 63 insertions, 9 deletions
diff --git a/src/cfg_file.l b/src/cfg_file.l index 1b677a4f4..f3baff15d 100644 --- a/src/cfg_file.l +++ b/src/cfg_file.l @@ -42,6 +42,7 @@ pidfile return PIDFILE; view return VIEW; ip return IP; +client_ip return CLIENT_IP; from return FROM; symbols return SYMBOLS; skip_check return SKIP_CHECK; diff --git a/src/cfg_file.y b/src/cfg_file.y index c51e5a853..24a94bbc3 100644 --- a/src/cfg_file.y +++ b/src/cfg_file.y @@ -57,7 +57,7 @@ struct rspamd_view *cur_view = NULL; %token LOG_LEVEL LOG_LEVEL_DEBUG LOG_LEVEL_INFO LOG_LEVEL_WARNING LOG_LEVEL_ERROR LOG_FACILITY LOG_FILENAME %token STATFILE ALIAS PATTERN WEIGHT STATFILE_POOL_SIZE SIZE TOKENIZER CLASSIFIER %token DELIVERY LMTP ENABLED AGENT SECTION LUACODE RAW_MODE PROFILE_FILE COUNT -%token VIEW IP FROM SYMBOLS +%token VIEW IP FROM SYMBOLS CLIENT_IP %token AUTOLEARN MIN_MARK MAX_MARK %token SETTINGS USER_SETTINGS DOMAIN_SETTINGS SYMBOL PATH SKIP_CHECK GROW_FACTOR @@ -999,6 +999,7 @@ viewbody: viewcmd: | viewip + | viewclientip | viewfrom | viewsymbols | viewskipcheck @@ -1016,6 +1017,18 @@ viewip: } ; +viewclientip: + CLIENT_IP EQSIGN QUOTEDSTRING { + if (cur_view == NULL) { + cur_view = init_view (cfg->cfg_pool); + } + if (!add_view_client_ip (cur_view, $3)) { + yyerror ("yyparse: invalid ip line in view definition: ip = '%s'", $3); + YYERROR; + } + } + ; + viewfrom: FROM EQSIGN QUOTEDSTRING { if (cur_view == NULL) { diff --git a/src/main.h b/src/main.h index 35ea627be..c633d4f7a 100644 --- a/src/main.h +++ b/src/main.h @@ -182,6 +182,7 @@ struct worker_task { GList *rcpt; /**< recipients list */ unsigned int nrcpt; /**< number of recipients */ struct in_addr from_addr; /**< client addr in numeric form */ + struct in_addr client_addr; /**< client addr in numeric form */ char *deliver_to; /**< address to deliver */ char *user; /**< user to deliver */ char *subject; /**< subject (for non-mime) */ diff --git a/src/view.c b/src/view.c index 0f9aefcf7..f3a273899 100644 --- a/src/view.c +++ b/src/view.c @@ -100,8 +100,18 @@ add_view_ip (struct rspamd_view * view, char *line) return FALSE; } +gboolean +add_view_client_ip (struct rspamd_view * view, char *line) +{ + if (add_map (line, read_radix_list, fin_radix_list, (void **)&view->client_ip_tree)) { + return TRUE; + } -struct rspamd_view * + return FALSE; +} + + +static struct rspamd_view * find_view_by_ip (GList * views, struct worker_task *task) { GList *cur; @@ -123,7 +133,29 @@ find_view_by_ip (GList * views, struct worker_task *task) return NULL; } -struct rspamd_view * +static struct rspamd_view * +find_view_by_client_ip (GList * views, struct worker_task *task) +{ + GList *cur; + struct rspamd_view *v; + + if (task->client_addr.s_addr == INADDR_NONE) { + return NULL; + } + + cur = views; + while (cur) { + v = cur->data; + if (radix32tree_find (v->client_ip_tree, ntohl (task->client_addr.s_addr)) != RADIX_NO_VALUE) { + return v; + } + cur = g_list_next (cur); + } + + return NULL; +} + +static struct rspamd_view * find_view_by_from (GList * views, struct worker_task *task) { GList *cur, *cur_re; @@ -201,10 +233,12 @@ check_view (GList * views, const char *symbol, struct worker_task * task) } if ((selected = find_view_by_ip (views, task)) == NULL) { - if ((selected = find_view_by_from (views, task)) == NULL) { - /* No matching view for this task */ - task->view_checked = TRUE; - return TRUE; + if ((selected = find_view_by_client_ip (views, task)) == NULL) { + if ((selected = find_view_by_from (views, task)) == NULL) { + /* No matching view for this task */ + task->view_checked = TRUE; + return TRUE; + } } } diff --git a/src/view.h b/src/view.h index 9114c6393..ea15149bd 100644 --- a/src/view.h +++ b/src/view.h @@ -10,6 +10,7 @@ struct rspamd_view { GHashTable *from_hash; radix_tree_t *ip_tree; + radix_tree_t *client_ip_tree; GHashTable *symbols_hash; GList *symbols_re_list; @@ -22,6 +23,7 @@ struct rspamd_view* init_view (memory_pool_t *pool); gboolean add_view_from (struct rspamd_view *view, char *line); gboolean add_view_ip (struct rspamd_view *view, char *line); +gboolean add_view_client_ip (struct rspamd_view *view, char *line); gboolean add_view_symbols (struct rspamd_view *view, char *line); gboolean check_view (GList *views, const char *symbol, struct worker_task *task); diff --git a/src/worker.c b/src/worker.c index c5589a533..ded5e57aa 100644 --- a/src/worker.c +++ b/src/worker.c @@ -326,16 +326,19 @@ accept_socket (int fd, short what, void *arg) return; } + + new_task = construct_task (worker); + if (ss.ss_family == AF_UNIX) { msg_info ("accept_socket: accepted connection from unix socket"); + new_task->client_addr.s_addr = INADDR_NONE; } else if (ss.ss_family == AF_INET) { sin = (struct sockaddr_in *)&ss; msg_info ("accept_socket: accepted connection from %s port %d", inet_ntoa (sin->sin_addr), ntohs (sin->sin_port)); + memcpy (&new_task->client_addr, &sin->sin_addr, sizeof (struct in_addr)); } - new_task = construct_task (worker); - new_task->sock = nfd; new_task->is_mime = is_mime; worker->srv->stat->connections_count++; |