mirror of
https://git.haproxy.org/git/haproxy.git/
synced 2026-05-04 20:46:11 +02:00
MINOR: connection: use dst addr as parameter for srv conn hash
The destination address is used as an input to the server connection hash. The address and port are used as separated hash inputs. Note that they are not used when statically specified on the server line. This is only useful for dynamic destination address. This is typically used when the server address is dynamically set via the set-dst action. The address and port are separated hash parameters. Most notably, it should fixed set-dst use case (cf github issue #947).
This commit is contained in:
parent
68cf3959b3
commit
01a287f1e5
@ -472,9 +472,11 @@ struct conn_stream {
|
||||
* CAUTION! Always update CONN_HASH_PARAMS_TYPE_COUNT when adding a new entry.
|
||||
*/
|
||||
enum conn_hash_params_t {
|
||||
CONN_HASH_PARAMS_TYPE_SNI = 0x1,
|
||||
CONN_HASH_PARAMS_TYPE_SNI = 0x1,
|
||||
CONN_HASH_PARAMS_TYPE_DST_ADDR = 0x2,
|
||||
CONN_HASH_PARAMS_TYPE_DST_PORT = 0x4,
|
||||
};
|
||||
#define CONN_HASH_PARAMS_TYPE_COUNT 1
|
||||
#define CONN_HASH_PARAMS_TYPE_COUNT 3
|
||||
|
||||
#define CONN_HASH_PAYLOAD_LEN \
|
||||
(((sizeof(((struct connection *)0)->hash)) * 8) - CONN_HASH_PARAMS_TYPE_COUNT)
|
||||
@ -489,6 +491,7 @@ enum conn_hash_params_t {
|
||||
struct conn_hash_params {
|
||||
struct server *srv;
|
||||
XXH64_hash_t *sni_prehash;
|
||||
struct sockaddr_storage *dst_addr;
|
||||
};
|
||||
|
||||
/* This structure describes a connection with its methods and data.
|
||||
|
||||
@ -1274,6 +1274,18 @@ int connect_server(struct stream *s)
|
||||
}
|
||||
#endif /* USE_OPENSSL */
|
||||
|
||||
/* 2. destination address */
|
||||
if (!(s->flags & SF_ADDR_SET)) {
|
||||
err = alloc_dst_address(&s->target_addr, srv, s);
|
||||
if (err != SRV_STATUS_OK)
|
||||
return SF_ERR_INTERNAL;
|
||||
|
||||
s->flags |= SF_ADDR_SET;
|
||||
}
|
||||
|
||||
if (srv && (!is_addr(&srv->addr) || srv->flags & SRV_F_MAPPORTS))
|
||||
hash_params.dst_addr = s->target_addr;
|
||||
|
||||
if (srv)
|
||||
hash = conn_calculate_hash(&hash_params);
|
||||
|
||||
@ -1460,23 +1472,15 @@ skip_reuse:
|
||||
srv_conn->owner = s->sess;
|
||||
if (reuse_mode == PR_O_REUSE_NEVR)
|
||||
conn_set_private(srv_conn);
|
||||
|
||||
if (!sockaddr_alloc(&srv_conn->dst, 0, 0)) {
|
||||
conn_free(srv_conn);
|
||||
return SF_ERR_RESOURCE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!srv_conn || !sockaddr_alloc(&srv_conn->dst, 0, 0)) {
|
||||
if (srv_conn)
|
||||
conn_free(srv_conn);
|
||||
return SF_ERR_RESOURCE;
|
||||
}
|
||||
|
||||
if (!(s->flags & SF_ADDR_SET)) {
|
||||
err = alloc_dst_address(&s->target_addr, srv, s);
|
||||
if (err != SRV_STATUS_OK) {
|
||||
conn_free(srv_conn);
|
||||
return SF_ERR_INTERNAL;
|
||||
else {
|
||||
return SF_ERR_RESOURCE;
|
||||
}
|
||||
|
||||
s->flags |= SF_ADDR_SET;
|
||||
}
|
||||
|
||||
/* copy the target address into the connection */
|
||||
|
||||
@ -1412,6 +1412,49 @@ static struct cfg_kw_list cfg_kws = {ILH, {
|
||||
|
||||
INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
|
||||
|
||||
/* private function to handle sockaddr as input for connection hash */
|
||||
static void conn_calculate_hash_sockaddr(const struct sockaddr_storage *ss,
|
||||
char *buf, size_t *idx,
|
||||
enum conn_hash_params_t *hash_flags,
|
||||
enum conn_hash_params_t param_type_addr,
|
||||
enum conn_hash_params_t param_type_port)
|
||||
{
|
||||
struct sockaddr_in *addr;
|
||||
struct sockaddr_in6 *addr6;
|
||||
|
||||
switch (ss->ss_family) {
|
||||
case AF_INET:
|
||||
addr = (struct sockaddr_in *)ss;
|
||||
|
||||
conn_hash_update(buf, idx,
|
||||
&addr->sin_addr, sizeof(addr->sin_addr),
|
||||
hash_flags, param_type_addr);
|
||||
|
||||
if (addr->sin_port) {
|
||||
conn_hash_update(buf, idx,
|
||||
&addr->sin_port, sizeof(addr->sin_port),
|
||||
hash_flags, param_type_port);
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case AF_INET6:
|
||||
addr6 = (struct sockaddr_in6 *)ss;
|
||||
|
||||
conn_hash_update(buf, idx,
|
||||
&addr6->sin6_addr, sizeof(addr6->sin6_addr),
|
||||
hash_flags, param_type_addr);
|
||||
|
||||
if (addr6->sin6_port) {
|
||||
conn_hash_update(buf, idx,
|
||||
&addr6->sin6_port, sizeof(addr6->sin6_port),
|
||||
hash_flags, param_type_port);
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
XXH64_hash_t conn_calculate_hash(const struct conn_hash_params *params)
|
||||
{
|
||||
char *buf;
|
||||
@ -1429,6 +1472,14 @@ XXH64_hash_t conn_calculate_hash(const struct conn_hash_params *params)
|
||||
&hash_flags, CONN_HASH_PARAMS_TYPE_SNI);
|
||||
}
|
||||
|
||||
if (params->dst_addr) {
|
||||
conn_calculate_hash_sockaddr(params->dst_addr,
|
||||
buf, &idx, &hash_flags,
|
||||
CONN_HASH_PARAMS_TYPE_DST_ADDR,
|
||||
CONN_HASH_PARAMS_TYPE_DST_PORT);
|
||||
}
|
||||
|
||||
hash = conn_hash_digest(buf, idx, hash_flags);
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user