]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: connection: use src addr as parameter for srv conn hash
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 11 Feb 2021 18:45:19 +0000 (19:45 +0100)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 12 Feb 2021 11:54:04 +0000 (12:54 +0100)
The source address is used as an input to the the server connection hash. The
address and port are used as separate hash inputs. Do not add anymore these
connections in the private list.

This parameter is set only if used in the transparent-proxy mode.

include/haproxy/connection-t.h
src/backend.c
src/connection.c
src/proto_tcp.c

index 7acbc2d77e95f23755978749259ffa78e5b18497..e2ae0297d47ce002647f1f445565f3e5f194d147 100644 (file)
@@ -475,8 +475,10 @@ enum conn_hash_params_t {
        CONN_HASH_PARAMS_TYPE_SNI      = 0x1,
        CONN_HASH_PARAMS_TYPE_DST_ADDR = 0x2,
        CONN_HASH_PARAMS_TYPE_DST_PORT = 0x4,
+       CONN_HASH_PARAMS_TYPE_SRC_ADDR = 0x8,
+       CONN_HASH_PARAMS_TYPE_SRC_PORT = 0x10,
 };
-#define CONN_HASH_PARAMS_TYPE_COUNT 3
+#define CONN_HASH_PARAMS_TYPE_COUNT 5
 
 #define CONN_HASH_PAYLOAD_LEN \
        (((sizeof(((struct connection *)0)->hash)) * 8) - CONN_HASH_PARAMS_TYPE_COUNT)
@@ -491,6 +493,7 @@ enum conn_hash_params_t {
 struct conn_hash_params {
        struct server *srv;
        XXH64_hash_t *sni_prehash;
+       struct sockaddr_storage *src_addr;
        struct sockaddr_storage *dst_addr;
 };
 
index 38a540fd60a9091d6c365112049695ce600d0fa0..1ab0af828d95bfea454aac274a4bcad0abbc8e1b 100644 (file)
@@ -1266,6 +1266,7 @@ int connect_server(struct stream *s)
        int init_mux = 0;
        int err;
        struct sample *sni_smp = NULL;
+       struct sockaddr_storage *bind_addr;
        int64_t hash = 0;
        struct conn_hash_params hash_params;
        XXH64_hash_t sni_hash;
@@ -1302,6 +1303,13 @@ int connect_server(struct stream *s)
        if (srv && (!is_addr(&srv->addr) || srv->flags & SRV_F_MAPPORTS))
                hash_params.dst_addr = s->target_addr;
 
+       /* 3. source address */
+       err = alloc_bind_address(&bind_addr, srv, s);
+       if (err != SRV_STATUS_OK)
+               return SF_ERR_INTERNAL;
+
+       hash_params.src_addr = bind_addr;
+
        if (srv)
                hash = conn_calculate_hash(&hash_params);
 
@@ -1381,21 +1389,6 @@ int connect_server(struct stream *s)
        /* here reuse might have been set above, indicating srv_conn finally
         * is OK.
         */
-       if (reuse) {
-               /* Disable connection reuse if a dynamic source is used.
-                * As long as we don't share connections between servers,
-                * we don't need to disable connection reuse on no-idempotent
-                * requests nor when PROXY protocol is used.
-                */
-               if (srv && srv->conn_src.opts & CO_SRC_BIND) {
-                       if ((srv->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_DYN)
-                               reuse = 0;
-               }
-               else if (s->be->conn_src.opts & CO_SRC_BIND) {
-                       if ((s->be->conn_src.opts & CO_SRC_TPROXY_MASK) == CO_SRC_TPROXY_DYN)
-                               reuse = 0;
-               }
-       }
 
        if (ha_used_fds > global.tune.pool_high_count && srv && srv->idle_conns_tree) {
                struct connection *tokill_conn = NULL;
@@ -1489,9 +1482,7 @@ skip_reuse:
                        if (reuse_mode == PR_O_REUSE_NEVR)
                                conn_set_private(srv_conn);
 
-                       err = alloc_bind_address(&srv_conn->src, srv, s);
-                       if (err != SRV_STATUS_OK)
-                               return SF_ERR_INTERNAL;
+                       srv_conn->src = bind_addr;
 
                        if (!sockaddr_alloc(&srv_conn->dst, 0, 0)) {
                                conn_free(srv_conn);
@@ -1499,6 +1490,7 @@ skip_reuse:
                        }
                }
                else {
+                       sockaddr_free(&bind_addr);
                        return SF_ERR_RESOURCE;
                }
        }
index 5e7a4c5d656e7bdb8cd5b677b2831fbb11b823d5..159f4c6292a1abbbe51d308616836f8b7cdd5972 100644 (file)
@@ -1479,6 +1479,13 @@ XXH64_hash_t conn_calculate_hash(const struct conn_hash_params *params)
                                             CONN_HASH_PARAMS_TYPE_DST_PORT);
        }
 
+       if (params->src_addr) {
+               conn_calculate_hash_sockaddr(params->src_addr,
+                                            buf, &idx, &hash_flags,
+                                            CONN_HASH_PARAMS_TYPE_SRC_ADDR,
+                                            CONN_HASH_PARAMS_TYPE_SRC_PORT);
+       }
+
        hash = conn_hash_digest(buf, idx, hash_flags);
 
        return hash;
index 485603d57aa8b20349dca96e97511d156c6356c7..a53415397f613cb3062f39786b25da6a9b3fa456 100644 (file)
@@ -392,14 +392,11 @@ int tcp_connect_server(struct connection *conn, int flags)
                if (conn->src && is_inet_addr(conn->src)) {
                        switch (src->opts & CO_SRC_TPROXY_MASK) {
                        case CO_SRC_TPROXY_CLI:
-                               conn_set_private(conn);
-                               /* fall through */
                        case CO_SRC_TPROXY_ADDR:
                                flags = 3;
                                break;
                        case CO_SRC_TPROXY_CIP:
                        case CO_SRC_TPROXY_DYN:
-                               conn_set_private(conn);
                                flags = 1;
                                break;
                        }