]> source.dussan.org Git - rspamd.git/commitdiff
[Feature] Distinguish IP failures from connection failures
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 2 Jul 2018 11:30:08 +0000 (12:30 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Mon, 2 Jul 2018 11:30:08 +0000 (12:30 +0100)
12 files changed:
src/fuzzy_storage.c
src/libserver/dns.c
src/libserver/fuzzy_backend_redis.c
src/libstat/backends/redis_backend.c
src/libstat/learn_cache/redis_cache.c
src/libutil/upstream.c
src/libutil/upstream.h
src/lua/lua_upstream.c
src/plugins/fuzzy_check.c
src/plugins/surbl.c
src/rspamd_proxy.c
test/rspamd_upstream_test.c

index 9243e369ef1675ff0bfdd29bd6bc6ee4bf934e8d..c97756aba9f6370b4e747d9738c466a6d3ad54d2 100644 (file)
@@ -452,7 +452,7 @@ rspamd_fuzzy_send_update_mirror (struct rspamd_fuzzy_storage_ctx *ctx,
 
        if (conn->sock == -1) {
                msg_err ("cannot connect upstream for %s", m->name);
-               rspamd_upstream_fail (conn->up);
+               rspamd_upstream_fail (conn->up, TRUE);
                return;
        }
 
index c07447471d4adfba2da6051bb5dfcd7630f5f7e3..b10eaf8c4dd83e6bd16f203bd82fb9d0e79fe406 100644 (file)
@@ -593,7 +593,7 @@ rspamd_dns_upstream_fail (struct rdns_upstream_elt *elt,
 {
        struct upstream *up = elt->lib_data;
 
-       rspamd_upstream_fail (up);
+       rspamd_upstream_fail (up, FALSE);
 }
 
 static unsigned int
index 06f100132ee4d3af61b9f33baae14ac05e5daa37..d25f057edc47df964ebc5254db391865133161c0 100644 (file)
@@ -467,7 +467,7 @@ rspamd_fuzzy_redis_shingles_callback (redisAsyncContext *c, gpointer r,
                        msg_err_redis_session ("error getting shingles: %s", c->errstr);
                }
 
-               rspamd_upstream_fail (session->up);
+               rspamd_upstream_fail (session->up, FALSE);
        }
 
        rspamd_fuzzy_redis_session_dtor (session, FALSE);
@@ -606,7 +606,7 @@ rspamd_fuzzy_redis_check_callback (redisAsyncContext *c, gpointer r,
                        msg_err_redis_session ("error getting hashes: %s", c->errstr);
                }
 
-               rspamd_upstream_fail (session->up);
+               rspamd_upstream_fail (session->up, FALSE);
        }
 
        rspamd_fuzzy_redis_session_dtor (session, FALSE);
@@ -674,7 +674,7 @@ rspamd_fuzzy_backend_check_redis (struct rspamd_fuzzy_backend *bk,
                        rspamd_inet_address_get_port (addr));
 
        if (session->ctx == NULL) {
-               rspamd_upstream_fail (up);
+               rspamd_upstream_fail (up, TRUE);
                rspamd_fuzzy_redis_session_dtor (session, TRUE);
 
                if (cb) {
@@ -744,7 +744,7 @@ rspamd_fuzzy_redis_count_callback (redisAsyncContext *c, gpointer r,
                        msg_err_redis_session ("error getting count: %s", c->errstr);
                }
 
-               rspamd_upstream_fail (session->up);
+               rspamd_upstream_fail (session->up, FALSE);
        }
 
        rspamd_fuzzy_redis_session_dtor (session, FALSE);
@@ -798,7 +798,7 @@ rspamd_fuzzy_backend_count_redis (struct rspamd_fuzzy_backend *bk,
                        rspamd_inet_address_get_port (addr));
 
        if (session->ctx == NULL) {
-               rspamd_upstream_fail (up);
+               rspamd_upstream_fail (up, TRUE);
                rspamd_fuzzy_redis_session_dtor (session, TRUE);
 
                if (cb) {
@@ -866,7 +866,7 @@ rspamd_fuzzy_redis_version_callback (redisAsyncContext *c, gpointer r,
                        msg_err_redis_session ("error getting version: %s", c->errstr);
                }
 
-               rspamd_upstream_fail (session->up);
+               rspamd_upstream_fail (session->up, FALSE);
        }
 
        rspamd_fuzzy_redis_session_dtor (session, FALSE);
@@ -921,7 +921,7 @@ rspamd_fuzzy_backend_version_redis (struct rspamd_fuzzy_backend *bk,
                        rspamd_inet_address_get_port (addr));
 
        if (session->ctx == NULL) {
-               rspamd_upstream_fail (up);
+               rspamd_upstream_fail (up, FALSE);
                rspamd_fuzzy_redis_session_dtor (session, TRUE);
 
                if (cb) {
@@ -1272,7 +1272,7 @@ rspamd_fuzzy_redis_update_callback (redisAsyncContext *c, gpointer r,
                        msg_err_redis_session ("error sending update to redis: %s", c->errstr);
                }
 
-               rspamd_upstream_fail (session->up);
+               rspamd_upstream_fail (session->up, FALSE);
        }
 
        rspamd_fuzzy_redis_session_dtor (session, FALSE);
@@ -1382,7 +1382,7 @@ rspamd_fuzzy_backend_update_redis (struct rspamd_fuzzy_backend *bk,
                        rspamd_inet_address_get_port (addr));
 
        if (session->ctx == NULL) {
-               rspamd_upstream_fail (up);
+               rspamd_upstream_fail (up, TRUE);
                rspamd_fuzzy_redis_session_dtor (session, TRUE);
 
                if (cb) {
index 79fafd15bc5dc2cb58edf53458442066c5390488..0b421f2a58345eadecc239b1cb4c39f84802606d 100644 (file)
@@ -909,7 +909,8 @@ rspamd_redis_stat_keys (redisAsyncContext *c, gpointer r, gpointer priv)
                else {
                        msg_err ("cannot get keys to gather stat: unknown error");
                }
-               rspamd_upstream_fail (cbdata->selected);
+
+               rspamd_upstream_fail (cbdata->selected, FALSE);
                rspamd_redis_async_cbdata_cleanup (cbdata);
        }
 }
@@ -1031,7 +1032,7 @@ rspamd_redis_timeout (gint fd, short what, gpointer d)
        msg_err_task_check ("connection to redis server %s timed out",
                        rspamd_upstream_name (rt->selected));
 
-       rspamd_upstream_fail (rt->selected);
+       rspamd_upstream_fail (rt->selected, FALSE);
 
        if (rt->redis) {
                redis = rt->redis;
@@ -1091,7 +1092,7 @@ rspamd_redis_connected (redisAsyncContext *c, gpointer r, gpointer priv)
        else {
                msg_err_task ("error getting reply from redis server %s: %s",
                                rspamd_upstream_name (rt->selected), c->errstr);
-               rspamd_upstream_fail (rt->selected);
+               rspamd_upstream_fail (rt->selected, FALSE);
 
                if (!rt->err) {
                        g_set_error (&rt->err, rspamd_redis_stat_quark (), c->err,
@@ -1178,7 +1179,7 @@ rspamd_redis_processed (redisAsyncContext *c, gpointer r, gpointer priv)
                                rspamd_upstream_name (rt->selected), c->errstr);
 
                if (rt->redis) {
-                       rspamd_upstream_fail (rt->selected);
+                       rspamd_upstream_fail (rt->selected, FALSE);
                }
 
                if (!rt->err) {
@@ -1210,7 +1211,7 @@ rspamd_redis_learned (redisAsyncContext *c, gpointer r, gpointer priv)
                                rspamd_upstream_name (rt->selected), c->errstr);
 
                if (rt->redis) {
-                       rspamd_upstream_fail (rt->selected);
+                       rspamd_upstream_fail (rt->selected, FALSE);
                }
 
                if (!rt->err) {
index c3f4c65988ec9d74be3deb597fc4871f37bb8fa5..d43ec366501526ce3d5637e416af29e952d0355b 100644 (file)
@@ -95,7 +95,7 @@ rspamd_redis_cache_timeout (gint fd, short what, gpointer d)
 
        msg_err_task ("connection to redis server %s timed out",
                        rspamd_upstream_name (rt->selected));
-       rspamd_upstream_fail (rt->selected);
+       rspamd_upstream_fail (rt->selected, FALSE);
 
        if (rt->has_event) {
                rspamd_session_remove_event (task->s, rspamd_redis_cache_fin, d);
@@ -147,7 +147,7 @@ rspamd_stat_cache_redis_get (redisAsyncContext *c, gpointer r, gpointer priv)
                rspamd_upstream_ok (rt->selected);
        }
        else {
-               rspamd_upstream_fail (rt->selected);
+               rspamd_upstream_fail (rt->selected, FALSE);
        }
 
        if (rt->has_event) {
@@ -169,7 +169,7 @@ rspamd_stat_cache_redis_set (redisAsyncContext *c, gpointer r, gpointer priv)
                rspamd_upstream_ok (rt->selected);
        }
        else {
-               rspamd_upstream_fail (rt->selected);
+               rspamd_upstream_fail (rt->selected, FALSE);
        }
 
        if (rt->has_event) {
index 310a768ef3a7a17ad8b1f5b50cdd6e6731319ef3..883c6f2eb3ba6873d1cb3a2f73aacba520ca8ea0 100644 (file)
@@ -428,7 +428,7 @@ rspamd_upstream_set_inactive (struct upstream_list *ls, struct upstream *up)
 }
 
 void
-rspamd_upstream_fail (struct upstream *up)
+rspamd_upstream_fail (struct upstream *up, gboolean addr_failure)
 {
        gdouble error_rate, max_error_rate;
        gdouble sec_last, sec_cur;
@@ -476,10 +476,12 @@ rspamd_upstream_fail (struct upstream *up)
                        }
                }
 
-               /* Also increase count of errors for this specific address */
-               if (up->addrs.addr) {
-                       addr_elt = g_ptr_array_index (up->addrs.addr, up->addrs.cur);
-                       addr_elt->errors ++;
+               if (addr_failure) {
+                       /* Also increase count of errors for this specific address */
+                       if (up->addrs.addr) {
+                               addr_elt = g_ptr_array_index (up->addrs.addr, up->addrs.cur);
+                               addr_elt->errors++;
+                       }
                }
 
                RSPAMD_UPSTREAM_UNLOCK (up->lock);
index 84e75288df476f4c971207c8bc9e34a09dba0684..3bc2132daeaa8e69bafbef847fd60bf140fd76cf 100644 (file)
@@ -55,7 +55,7 @@ void rspamd_upstreams_library_config (struct rspamd_config *cfg,
 /**
  * Add an error to an upstream
  */
-void rspamd_upstream_fail (struct upstream *up);
+void rspamd_upstream_fail (struct upstream *up, gboolean addr_failure);
 
 /**
  * Increase upstream successes count
index e403d34af6d8fa906859776b423a89c73a9a6e8d..0d1246229ec56933670831e4523cdc854a2d7e11 100644 (file)
@@ -124,9 +124,15 @@ static gint
 lua_upstream_fail (lua_State *L)
 {
        struct upstream *up = lua_check_upstream (L);
+       gboolean fail_addr = FALSE;
 
        if (up) {
-               rspamd_upstream_fail (up);
+
+               if (lua_isboolean (L, 2)) {
+                       fail_addr = lua_toboolean (L, 2);
+               }
+
+               rspamd_upstream_fail (up, fail_addr);
        }
 
        return 0;
index 777f6fa62c4baae2bcdd7a2974bc716355b09386..766d11e5f2ea108db3b7ce81fcbd5a92696d7583 100644 (file)
@@ -2168,7 +2168,7 @@ fuzzy_check_io_callback (gint fd, short what, void *arg)
                        session->state == 1 ? "read" : "write",
                        errno,
                        strerror (errno));
-               rspamd_upstream_fail (session->server);
+               rspamd_upstream_fail (session->server, FALSE);
                rspamd_session_remove_event (session->task->s, fuzzy_io_fin, session);
        }
        else {
@@ -2207,7 +2207,7 @@ fuzzy_check_timer_callback (gint fd, short what, void *arg)
                                rspamd_upstream_name (session->server),
                                rspamd_inet_address_to_string_pretty (session->addr),
                                session->retransmits);
-               rspamd_upstream_fail (session->server);
+               rspamd_upstream_fail (session->server, FALSE);
                rspamd_session_remove_event (session->task->s, fuzzy_io_fin, session);
        }
        else {
@@ -2412,7 +2412,7 @@ fuzzy_controller_io_callback (gint fd, short what, void *arg)
                                rspamd_upstream_name (session->server),
                                rspamd_inet_address_to_string_pretty (session->addr),
                                errno, strerror (errno));
-               rspamd_upstream_fail (session->server);
+               rspamd_upstream_fail (session->server, FALSE);
        }
 
        /*
@@ -2509,7 +2509,7 @@ fuzzy_controller_timer_callback (gint fd, short what, void *arg)
        task = session->task;
 
        if (session->retransmits >= fuzzy_module_ctx->retransmits) {
-               rspamd_upstream_fail (session->server);
+               rspamd_upstream_fail (session->server, FALSE);
                msg_err_task_check ("got IO timeout with server %s(%s), "
                                "after %d retransmits",
                                rspamd_upstream_name (session->server),
@@ -2831,7 +2831,7 @@ register_fuzzy_client_call (struct rspamd_task *task,
                                        rspamd_inet_address_to_string_pretty (addr),
                                errno,
                                strerror (errno));
-                       rspamd_upstream_fail (selected);
+                       rspamd_upstream_fail (selected, FALSE);
                        g_ptr_array_free (commands, TRUE);
                }
                else {
@@ -2942,7 +2942,7 @@ register_fuzzy_controller_call (struct rspamd_http_connection_entry *entry,
 
                if ((sock = rspamd_inet_address_connect (addr,
                                SOCK_DGRAM, TRUE)) == -1) {
-                       rspamd_upstream_fail (selected);
+                       rspamd_upstream_fail (selected, TRUE);
                }
                else {
                        s =
@@ -3302,7 +3302,7 @@ fuzzy_check_send_lua_learn (struct fuzzy_rule *rule,
 
                if ((sock = rspamd_inet_address_connect (addr,
                                SOCK_DGRAM, TRUE)) == -1) {
-                       rspamd_upstream_fail (selected);
+                       rspamd_upstream_fail (selected, TRUE);
                }
                else {
                        s =
index 64b1b14f6c8f02278e6bd6424cfc9c726c8083cc..bfb6f4e82f0aa532edf516cd37cee6f31a627fe4 100644 (file)
@@ -1539,7 +1539,7 @@ surbl_redirector_error (struct rspamd_http_connection *conn,
        msg_err_surbl ("connection with http server %s terminated incorrectly: %e",
                rspamd_inet_address_to_string (rspamd_upstream_addr (param->redirector)),
                err);
-       rspamd_upstream_fail (param->redirector);
+       rspamd_upstream_fail (param->redirector, FALSE);
        rspamd_session_remove_event (param->task->s, free_redirector_session,
                        param);
 }
index 1d4324bdcfb7b5d6cb840acc4edbb2b86bcf5aa8..4af5ee5f49f5a41f2f8be05b9b685220a00e9337 100644 (file)
@@ -1308,7 +1308,7 @@ proxy_backend_mirror_error_handler (struct rspamd_http_connection *conn, GError
                bk_conn->err = rspamd_mempool_strdup (session->pool, err->message);
        }
 
-       rspamd_upstream_fail (bk_conn->up);
+       rspamd_upstream_fail (bk_conn->up, FALSE);
 
        proxy_backend_close_connection (bk_conn);
        REF_RELEASE (bk_conn->s);
@@ -1384,7 +1384,7 @@ proxy_open_mirror_connections (struct rspamd_proxy_session *session)
 
                if (bk_conn->backend_sock == -1) {
                        msg_err_session ("cannot connect upstream for %s", m->name);
-                       rspamd_upstream_fail (bk_conn->up);
+                       rspamd_upstream_fail (bk_conn->up, TRUE);
                        continue;
                }
 
@@ -1505,7 +1505,7 @@ proxy_backend_master_error_handler (struct rspamd_http_connection *conn, GError
                err,
                session->ctx->max_retries - session->retries);
        session->retries ++;
-       rspamd_upstream_fail (bk_conn->up);
+       rspamd_upstream_fail (bk_conn->up, FALSE);
        proxy_backend_close_connection (session->master_conn);
 
        if (session->ctx->max_retries &&
@@ -1810,7 +1810,7 @@ retry:
                                        host ? hostbuf : "default",
                                                        rspamd_inet_address_to_string (rspamd_upstream_addr (
                                                                        session->master_conn->up)));
-                       rspamd_upstream_fail (session->master_conn->up);
+                       rspamd_upstream_fail (session->master_conn->up, TRUE);
                        session->retries ++;
                        goto retry;
                }
index cce0008a927d757a5b85f25258b7b4d295559e2a..4e4f1ae87533155d859011506429f5ea2c61fefd 100644 (file)
@@ -103,7 +103,7 @@ rspamd_upstream_test_func (void)
        next_addr = rspamd_upstream_addr (up);
        g_assert (rspamd_inet_address_get_af (next_addr) == AF_INET6);
        /* Test errors with IPv6 */
-       rspamd_upstream_fail (up);
+       rspamd_upstream_fail (up, TRUE);
        /* Now we should have merely IPv4 addresses in rotation */
        addr = rspamd_upstream_addr (up);
        for (i = 0; i < 256; i++) {
@@ -166,7 +166,7 @@ rspamd_upstream_test_func (void)
 
        up = rspamd_upstream_get (ls, RSPAMD_UPSTREAM_MASTER_SLAVE, NULL, 0);
        for (i = 0; i < 100; i ++) {
-               rspamd_upstream_fail (up);
+               rspamd_upstream_fail (up, TRUE);
        }
        g_assert (rspamd_upstreams_alive (ls) == 2);