]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: connection: use pool-conn-name instead of sni on reuse
authorAmaury Denoyelle <adenoyelle@haproxy.com>
Thu, 23 May 2024 16:31:48 +0000 (18:31 +0200)
committerAmaury Denoyelle <adenoyelle@haproxy.com>
Fri, 24 May 2024 12:47:21 +0000 (14:47 +0200)
Implement pool-conn-name support for idle connection reuse. It replaces
SNI as arbitrary identifier for connections in the idle pool. Thus,
every SNI reference in this context have been replaced.

Main change occurs in connect_server() where pool-conn-name sample fetch
is now prehash to generate idle connection identifier. SNI is now solely
used in the context of SSL for ssl_sock_set_servername().

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

index 6ee0940be4bb00a0720700a1c4b2a9bc7e931b06..83969da06e0c569d56ca353efbdf35c51b1f15c8 100644 (file)
@@ -473,7 +473,7 @@ struct conn_src {
  * 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_NAME     = 0x1,
        CONN_HASH_PARAMS_TYPE_DST_ADDR = 0x2,
        CONN_HASH_PARAMS_TYPE_DST_PORT = 0x4,
        CONN_HASH_PARAMS_TYPE_SRC_ADDR = 0x8,
@@ -494,7 +494,7 @@ enum conn_hash_params_t {
  * connection hash.
  */
 struct conn_hash_params {
-       uint64_t sni_prehash;
+       uint64_t name_prehash;
        uint64_t proxy_prehash;
        uint64_t mark_tos_prehash;
        void *target;
index 91ddcd6a53c2aaa9316976ee09d8577bd33742ae..aa61cc71afdbaa6730df58d58a8ffade62ca68ab 100644 (file)
@@ -97,7 +97,7 @@ void sockaddr_free(struct sockaddr_storage **sap);
 
 /* connection hash stuff */
 uint64_t conn_calculate_hash(const struct conn_hash_params *params);
-uint64_t conn_hash_prehash(char *buf, size_t size);
+uint64_t conn_hash_prehash(const char *buf, size_t size);
 
 int conn_reverse(struct connection *conn);
 
index e5444988c2344a0ce5079f591ba6489cec328e5b..d74ae40825120ac6872f7449d269814660fcd222 100644 (file)
@@ -1349,9 +1349,7 @@ int connect_server(struct stream *s)
        int reuse = 0;
        int init_mux = 0;
        int err;
-#ifdef USE_OPENSSL
-       struct sample *sni_smp = NULL;
-#endif
+       struct sample *name_smp = NULL;
        struct sockaddr_storage *bind_addr = NULL;
        int proxy_line_ret;
        int64_t hash = 0;
@@ -1373,13 +1371,11 @@ int connect_server(struct stream *s)
        if (err != SRV_STATUS_OK)
                return SF_ERR_INTERNAL;
 
-#ifdef USE_OPENSSL
-       if (srv && srv->ssl_ctx.sni) {
-               sni_smp = sample_fetch_as_type(s->be, s->sess, s,
-                                              SMP_OPT_DIR_REQ | SMP_OPT_FINAL,
-                                              srv->ssl_ctx.sni, SMP_T_STR);
+       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);
        }
-#endif
 
        /* do not reuse if mode is not http */
        if (!IS_HTX_STRM(s)) {
@@ -1403,17 +1399,12 @@ int connect_server(struct stream *s)
        /* 1. target */
        hash_params.target = s->target;
 
-#ifdef USE_OPENSSL
-       /* 2. sni
-        * only test if the sample is not null as smp_make_safe (called before
-        * ssl_sock_set_servername) can only fails if this is not the case
-        */
-       if (sni_smp) {
-               hash_params.sni_prehash =
-                 conn_hash_prehash(sni_smp->data.u.str.area,
-                                   sni_smp->data.u.str.data);
+       /* 2. pool-conn-name */
+       if (name_smp) {
+               hash_params.name_prehash =
+                 conn_hash_prehash(name_smp->data.u.str.area,
+                                   name_smp->data.u.str.data);
        }
-#endif /* USE_OPENSSL */
 
        /* 3. destination address */
        if (srv && srv_is_transparent(srv))
@@ -1787,7 +1778,13 @@ skip_reuse:
                return err;
 
 #ifdef USE_OPENSSL
-       if (!(s->flags & SF_SRV_REUSED)) {
+       /* Set socket SNI unless connection is reused. */
+       if (srv && srv->ssl_ctx.sni && !(s->flags & SF_SRV_REUSED)) {
+               struct sample *sni_smp = NULL;
+
+               sni_smp = sample_fetch_as_type(s->be, s->sess, s,
+                                              SMP_OPT_DIR_REQ | SMP_OPT_FINAL,
+                                              srv->ssl_ctx.sni, SMP_T_STR);
                if (smp_make_safe(sni_smp))
                        ssl_sock_set_servername(srv_conn, sni_smp->data.u.str.area);
        }
index 97af8f65e50c6d637fa3bd005f0601b48b17b82a..d186c2f01e5d3f90342ca5d68521160233ca60ee 100644 (file)
@@ -2621,7 +2621,7 @@ INITCALL1(STG_REGISTER, cfg_register_keywords, &cfg_kws);
 /* Generate the hash of a connection with params as input
  * Each non-null field of params is taken into account for the hash calcul.
  */
-uint64_t conn_hash_prehash(char *buf, size_t size)
+uint64_t conn_hash_prehash(const char *buf, size_t size)
 {
        return XXH64(buf, size, 0);
 }
@@ -2699,10 +2699,10 @@ uint64_t conn_calculate_hash(const struct conn_hash_params *params)
 
        conn_hash_update(&hash, &params->target, sizeof(params->target), &hash_flags, 0);
 
-       if (params->sni_prehash) {
+       if (params->name_prehash) {
                conn_hash_update(&hash,
-                                &params->sni_prehash, sizeof(params->sni_prehash),
-                                &hash_flags, CONN_HASH_PARAMS_TYPE_SNI);
+                                &params->name_prehash, sizeof(params->name_prehash),
+                                &hash_flags, CONN_HASH_PARAMS_TYPE_NAME);
        }
 
        if (params->dst_addr) {
@@ -2770,7 +2770,7 @@ int conn_reverse(struct connection *conn)
                        /* data cannot wrap else prehash usage is incorrect */
                        BUG_ON(b_data(&conn->reverse.name) != b_contig_data(&conn->reverse.name, 0));
 
-                       hash_params.sni_prehash =
+                       hash_params.name_prehash =
                          conn_hash_prehash(b_head(&conn->reverse.name),
                                            b_data(&conn->reverse.name));
                }