diff --git a/include/haproxy/connection-t.h b/include/haproxy/connection-t.h index e2ae0297d..96b5611b2 100644 --- a/include/haproxy/connection-t.h +++ b/include/haproxy/connection-t.h @@ -477,8 +477,9 @@ enum conn_hash_params_t { CONN_HASH_PARAMS_TYPE_DST_PORT = 0x4, CONN_HASH_PARAMS_TYPE_SRC_ADDR = 0x8, CONN_HASH_PARAMS_TYPE_SRC_PORT = 0x10, + CONN_HASH_PARAMS_TYPE_PROXY = 0x20, }; -#define CONN_HASH_PARAMS_TYPE_COUNT 5 +#define CONN_HASH_PARAMS_TYPE_COUNT 6 #define CONN_HASH_PAYLOAD_LEN \ (((sizeof(((struct connection *)0)->hash)) * 8) - CONN_HASH_PARAMS_TYPE_COUNT) @@ -495,6 +496,7 @@ struct conn_hash_params { XXH64_hash_t *sni_prehash; struct sockaddr_storage *src_addr; struct sockaddr_storage *dst_addr; + XXH64_hash_t *proxy_prehash; }; /* This structure describes a connection with its methods and data. diff --git a/reg-tests/connection/proxy_protocol_send_unique_id.vtc b/reg-tests/connection/proxy_protocol_send_unique_id.vtc index c1f0fc480..4f6b848e7 100644 --- a/reg-tests/connection/proxy_protocol_send_unique_id.vtc +++ b/reg-tests/connection/proxy_protocol_send_unique_id.vtc @@ -38,5 +38,5 @@ client c1 -connect ${h1_feS_sock} { -hdr "in: bar" rxresp expect resp.http.http_unique_id == "TEST-bar" - expect resp.http.proxy_unique_id == "TEST-foo" + expect resp.http.proxy_unique_id == "TEST-bar" } -run diff --git a/src/backend.c b/src/backend.c index 1ab0af828..639fbd781 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1267,9 +1267,10 @@ int connect_server(struct stream *s) int err; struct sample *sni_smp = NULL; struct sockaddr_storage *bind_addr; + int proxy_line_ret; int64_t hash = 0; struct conn_hash_params hash_params; - XXH64_hash_t sni_hash; + XXH64_hash_t sni_hash, proxy_hash; /* first, set unique connection parameters and then calculate hash */ memset(&hash_params, 0, sizeof(hash_params)); @@ -1310,6 +1311,15 @@ int connect_server(struct stream *s) hash_params.src_addr = bind_addr; + /* 4. proxy protocol */ + if (srv && srv->pp_opts) { + proxy_line_ret = make_proxy_line(trash.area, trash.size, srv, cli_conn, s); + if (proxy_line_ret) { + proxy_hash = conn_hash_prehash(trash.area, proxy_line_ret); + hash_params.proxy_prehash = &proxy_hash; + } + } + if (srv) hash = conn_calculate_hash(&hash_params); @@ -1535,7 +1545,6 @@ int connect_server(struct stream *s) srv_conn->send_proxy_ofs = 0; if (srv && srv->pp_opts) { - conn_set_private(srv_conn); srv_conn->flags |= CO_FL_SEND_PROXY; srv_conn->send_proxy_ofs = 1; /* must compute size */ if (cli_conn) diff --git a/src/connection.c b/src/connection.c index 159f4c629..002d6e75a 100644 --- a/src/connection.c +++ b/src/connection.c @@ -1486,7 +1486,12 @@ XXH64_hash_t conn_calculate_hash(const struct conn_hash_params *params) CONN_HASH_PARAMS_TYPE_SRC_PORT); } - hash = conn_hash_digest(buf, idx, hash_flags); + if (params->proxy_prehash) { + conn_hash_update(buf, &idx, + params->proxy_prehash, sizeof(*params->proxy_prehash), + &hash_flags, CONN_HASH_PARAMS_TYPE_PROXY); + } + hash = conn_hash_digest(buf, idx, hash_flags); return hash; }