]> source.dussan.org Git - rspamd.git/commitdiff
* Add ability to check views by client's ip (that ip from which we have a connection...
authorVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 27 Oct 2009 16:34:11 +0000 (19:34 +0300)
committerVsevolod Stakhov <vsevolod@rambler-co.ru>
Tue, 27 Oct 2009 16:34:11 +0000 (19:34 +0300)
src/cfg_file.l
src/cfg_file.y
src/main.h
src/view.c
src/view.h
src/worker.c

index 1b677a4f44b2f4404efcf7081f8d9d24dcc0e872..f3baff15d2c3dd1a9df0de3e41abb94475f9fbca 100644 (file)
@@ -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;
index c51e5a85381b72acf5d4c8340bed1d47d1f79b42..24a94bbc38cbf60242c058495ffe683020cccef7 100644 (file)
@@ -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) {
index 35ea627bea985220ad70d6a0e5af72b7b1587b34..c633d4f7ada9abe18c90ecc68c51c53764f419f7 100644 (file)
@@ -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)                                                     */
index 0f9aefcf7085eed432134ff5ca85f86d6600b8c2..f3a273899e9648e8fd8080f5697ad66279f329bd 100644 (file)
@@ -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;
+                       }
                }
        }
 
index 9114c639358bac36eaab339066c3f95da6b3d523..ea15149bd1e68830f0982b1801929c162630fdd2 100644 (file)
@@ -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);
index c5589a533aef1130fbe59fb6fed7a87b0dcf247e..ded5e57aa6bca588b02a77404f7a421330037c7f 100644 (file)
@@ -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++;