diff --git a/include/haproxy/backend.h b/include/haproxy/backend.h index efceb65ab..01b0cbdcb 100644 --- a/include/haproxy/backend.h +++ b/include/haproxy/backend.h @@ -49,7 +49,8 @@ int alloc_bind_address(struct sockaddr_storage **ss, int64_t be_calculate_conn_hash(struct server *srv, struct stream *strm, struct session *sess, struct sockaddr_storage *src, - struct sockaddr_storage *dst); + struct sockaddr_storage *dst, + struct ist name); int be_reuse_connection(int64_t hash, struct session *sess, struct proxy *be, struct server *srv, struct stconn *sc, enum obj_type *target, int not_first_req); diff --git a/src/backend.c b/src/backend.c index e49a12d05..6ae61fa51 100644 --- a/src/backend.c +++ b/src/backend.c @@ -1553,6 +1553,8 @@ static int be_reuse_mode(struct proxy *be, struct server *srv) * - is the bind address if an explicit source address is used. * - is the destination address. Must be set in every cases, except on * reverse HTTP. + * - is a string identifier associated to the connection. Set by + * pool-conn-name, also used for SSL SNI matching. * * Note that all input parameters can be NULL. The only requirement is that * it's not possible to have both and NULL at the same time. @@ -1562,9 +1564,9 @@ static int be_reuse_mode(struct proxy *be, struct server *srv) int64_t be_calculate_conn_hash(struct server *srv, struct stream *strm, struct session *sess, struct sockaddr_storage *src, - struct sockaddr_storage *dst) + struct sockaddr_storage *dst, + struct ist name) { - struct proxy *be = srv ? srv->proxy : strm->be; struct conn_hash_params hash_params; /* Caller cannot set both and to NULL. */ @@ -1577,17 +1579,9 @@ int64_t be_calculate_conn_hash(struct server *srv, struct stream *strm, hash_params.target = srv ? &srv->obj_type : strm->target; /* 2. pool-conn-name */ - if (srv && srv->pool_conn_name_expr) { - struct sample *name_smp; - - name_smp = sample_fetch_as_type(be, sess, strm, - SMP_OPT_DIR_REQ | SMP_OPT_FINAL, - srv->pool_conn_name_expr, SMP_T_STR); - if (name_smp) { - hash_params.name_prehash = - conn_hash_prehash(name_smp->data.u.str.area, - name_smp->data.u.str.data); - } + if (istlen(name)) { + hash_params.name_prehash = + conn_hash_prehash(istptr(name), istlen(name)); } /* 3. destination address */ @@ -1808,7 +1802,20 @@ int connect_server(struct stream *s) } else { const int not_first_req = s->txn && s->txn->flags & TX_NOT_FIRST; - hash = be_calculate_conn_hash(srv, s, s->sess, bind_addr, s->scb->dst); + struct ist name = IST_NULL; + struct sample *name_smp; + + if (srv && srv->pool_conn_name_expr) { + name_smp = sample_fetch_as_type(s->be, s->sess, s, + SMP_OPT_DIR_REQ | SMP_OPT_FINAL, + srv->pool_conn_name_expr, SMP_T_STR); + if (name_smp) { + name = ist2(name_smp->data.u.str.area, + name_smp->data.u.str.data); + } + } + + hash = be_calculate_conn_hash(srv, s, s->sess, bind_addr, s->scb->dst, name); err = be_reuse_connection(hash, s->sess, s->be, srv, s->scb, s->target, not_first_req); if (err == SF_ERR_INTERNAL) diff --git a/src/tcpcheck.c b/src/tcpcheck.c index 754f41448..5329233a3 100644 --- a/src/tcpcheck.c +++ b/src/tcpcheck.c @@ -1216,7 +1216,7 @@ static inline int tcpcheck_use_nondefault_connect(const struct check *check, return check->mux_proto || connect->mux_proto || is_addr(&check->addr) || is_addr(&connect->addr) || check->port || connect->port || connect->port_expr || - check->use_ssl || check->sni || connect->sni || check->alpn_len || connect->alpn_len || + check->use_ssl || check->alpn_len || connect->alpn_len || check->send_proxy || check->via_socks4 || (connect->options & TCPCHK_MASK_OPTS_CONNECT); } @@ -1266,12 +1266,18 @@ enum tcpcheck_eval_ret tcpcheck_eval_connect(struct check *check, struct tcpchec if (!(check->state & CHK_ST_AGENT) && check->reuse_pool && !tcpcheck_use_nondefault_connect(check, connect)) { + struct ist pool_conn_name = IST_NULL; int64_t hash; int conn_err; TRACE_DEVEL("trying connection reuse for check", CHK_EV_TCPCHK_CONN, check); - hash = be_calculate_conn_hash(s, NULL, check->sess, NULL, NULL); + if (connect->sni) + pool_conn_name = ist(connect->sni); + else if ((connect->options & TCPCHK_OPT_DEFAULT_CONNECT) && check->sni) + pool_conn_name = ist(check->sni); + + hash = be_calculate_conn_hash(s, NULL, check->sess, NULL, NULL, pool_conn_name); conn_err = be_reuse_connection(hash, check->sess, s->proxy, s, check->sc, &s->obj_type, 0); if (conn_err == SF_ERR_INTERNAL) {