From: Amaury Denoyelle Date: Thu, 11 Feb 2021 18:45:19 +0000 (+0100) Subject: MINOR: connection: use src addr as parameter for srv conn hash X-Git-Tag: v2.4-dev8~64 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=d10a200f62f873437952f9f021c5b4ea720bd887;p=thirdparty%2Fhaproxy.git MINOR: connection: use src addr as parameter for srv conn hash 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. --- diff --git a/include/haproxy/connection-t.h b/include/haproxy/connection-t.h index 7acbc2d77e..e2ae0297d4 100644 --- a/include/haproxy/connection-t.h +++ b/include/haproxy/connection-t.h @@ -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; }; diff --git a/src/backend.c b/src/backend.c index 38a540fd60..1ab0af828d 100644 --- a/src/backend.c +++ b/src/backend.c @@ -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; } } diff --git a/src/connection.c b/src/connection.c index 5e7a4c5d65..159f4c6292 100644 --- a/src/connection.c +++ b/src/connection.c @@ -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; diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 485603d57a..a53415397f 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -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; }