]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: server: Introduce the concept of path parameters
authorOlivier Houchard <ohouchard@haproxy.com>
Mon, 8 Sep 2025 20:14:42 +0000 (22:14 +0200)
committerOlivier Houchard <cognet@ci0.org>
Tue, 9 Sep 2025 17:01:24 +0000 (19:01 +0200)
Add a new field in struct server, path parameters. It will contain
connection informations for the server that are not expected to change.
For now, just store the ALPN negociated with the server. Each time an
handhskae is done, we'll update it, even though it is not supposed to
change. This will be useful when trying to send early data, that way
we'll know which mux to use.
Each time the server goes down or is disabled, those informations are
erased, as we can't be sure those parameters will be the same once the
server will be back up.

include/haproxy/server-t.h
src/server.c
src/ssl_sock.c

index bed9332268395569cd68fee6b9f6c3eb08203c36..af6ffdee8b6901bb1d4bbaebe92708d3660cc573 100644 (file)
@@ -315,6 +315,12 @@ enum renegotiate_mode {
        SSL_RENEGOTIATE_ON              /* Enable secure renegotiation */
 };
 
+#define MAX_ALPN_SIZE 16
+
+struct path_parameters {
+       char nego_alpn[MAX_ALPN_SIZE];
+};
+
 struct proxy;
 struct server {
        /* mostly config or admin stuff, doesn't change often */
@@ -494,6 +500,7 @@ struct server {
 #ifdef USE_QUIC
        struct quic_transport_params quic_params; /* QUIC transport parameters */
 #endif
+       struct path_parameters path_params;     /* Connection parameters for that server */
        struct resolv_srvrq *srvrq;             /* Pointer representing the DNS SRV requeest, if any */
        struct list srv_rec_item;               /* to attach server to a srv record item */
        struct list ip_rec_item;                /* to attach server to a A or AAAA record item */
index 83257e1511bfdbda65e7b0e9d19b0d55312bc08e..514a1c61fc0e78fc4d248626dff7fd1697550c59 100644 (file)
@@ -137,6 +137,11 @@ static const char *srv_op_st_chg_cause_str[] = {
        [SRV_OP_STCHGC_STATEFILE] = "changed from server-state after a reload"
 };
 
+static void srv_reset_path_parameters(struct server *s)
+{
+       s->path_params.nego_alpn[0] = 0;
+}
+
 const char *srv_op_st_chg_cause(enum srv_op_st_chg_cause cause)
 {
        return srv_op_st_chg_cause_str[cause];
@@ -6642,6 +6647,7 @@ static int _srv_update_status_op(struct server *s, enum srv_op_st_chg_cause caus
                if (s->onmarkeddown & HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS)
                        srv_shutdown_streams(s, SF_ERR_DOWN);
 
+               srv_reset_path_parameters(s);
                /* we might have streams queued on this server and waiting for
                 * a connection. Those which are redispatchable will be queued
                 * to another server or to the proxy itself.
@@ -6669,6 +6675,7 @@ static int _srv_update_status_op(struct server *s, enum srv_op_st_chg_cause caus
        else if ((s->cur_state != SRV_ST_STOPPING) && (s->next_state == SRV_ST_STOPPING)) {
                srv_lb_propagate(s);
 
+               srv_reset_path_parameters(s);
                /* we might have streams queued on this server and waiting for
                 * a connection. Those which are redispatchable will be queued
                 * to another server or to the proxy itself.
@@ -6783,6 +6790,8 @@ static int _srv_update_status_adm(struct server *s, enum srv_adm_st_chg_cause ca
                        s->next_state = SRV_ST_STOPPED;
                        srv_lb_propagate(s);
 
+                       srv_reset_path_parameters(s);
+
                        if (s->onmarkeddown & HANA_ONMARKEDDOWN_SHUTDOWNSESSIONS)
                                srv_shutdown_streams(s, SF_ERR_DOWN);
 
index 4e0072e0b4cec91b68ac7d21bdc2617690e11317..f8640e2f140fefd66d2e41c0dcb7b109c6b16adb 100644 (file)
@@ -6487,8 +6487,31 @@ struct task *ssl_sock_io_cb(struct task *t, void *context, unsigned int state)
                if (ctx->conn->xprt_ctx == ctx) {
                        int closed_connection = 0;
 
-                       if (!ctx->conn->mux)
+                       if (!ctx->conn->mux) {
                                ret = conn_create_mux(ctx->conn, &closed_connection);
+                               /*
+                                * For backend connections, attempt to
+                                * retrieve the ALPN, and store it into
+                                * the server's path_params, so that for
+                                * next connections, we'll know the ALPN
+                                * already, and immediately know which mux
+                                * to use, in case we want to use 0RTT.
+                                */
+                               if (conn_is_back(conn)) {
+                                       struct server *srv;
+                                       const char *alpn;
+                                       int len;
+
+                                       if (ssl_sock_get_alpn(conn, ctx, &alpn, &len)) {
+                                               srv = objt_server(conn->target);
+                                               if (srv && len < sizeof(srv->path_params.nego_alpn)) {
+                                                       memcpy(&srv->path_params.nego_alpn, alpn, len);
+                                                       srv->path_params.nego_alpn[len] = 0;
+                                               }
+                                       }
+                               }
+
+                       }
                        if (ret >= 0 && !woke && ctx->conn->mux && ctx->conn->mux->wake) {
                                ret = ctx->conn->mux->wake(ctx->conn);
                                if (ret < 0)