]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic-be: Save the backend 0-RTT parameters
authorFrederic Lecaille <flecaille@haproxy.com>
Thu, 31 Jul 2025 15:56:02 +0000 (17:56 +0200)
committerFrederic Lecaille <flecaille@haproxy.com>
Thu, 13 Nov 2025 13:04:31 +0000 (14:04 +0100)
For both TCP and QUIC connections, this is ssl_sess_new_srv_cb() callback which
is called when a new SSL session is created. Its role is to save the session to
be reused for the next sessions.

This patch modifies this callback to save the QUIC parameters to be reused
for the next 0-RTT sessions (or during SSL session resumption).

The already existing path_params->nego_alpn member is used to store the ALPN as
this is done for TCP alongside path_params->tps new quic_early_transport_params
struct used to save the QUIC transport parameters to be reused for 0-RTT sessions.

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

index f888de3c7aca060387fe9eb4d284c11358b39df8..2d4f3a07d13402c98bc7afbc1f45aa40d4a9207d 100644 (file)
@@ -325,6 +325,9 @@ enum renegotiate_mode {
 struct path_parameters {
        __decl_thread(HA_RWLOCK_T param_lock);
        char nego_alpn[MAX_ALPN_SIZE];
+#ifdef USE_QUIC
+       struct quic_early_transport_params tps;
+#endif
 };
 
 struct proxy;
index f0cfb14584658b99709138abf93111326ee2a56f..1a3fbf6c2b0d58b480e0df62cd022099a62ef384 100644 (file)
@@ -4181,6 +4181,9 @@ static int ssl_sess_new_srv_cb(SSL *ssl, SSL_SESSION *sess)
                int len;
                unsigned char *ptr;
                const char *sni;
+#ifdef USE_QUIC
+               struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
+#endif
 
                /* determine the required len to store this new session */
                len = i2d_SSL_SESSION(sess, NULL);
@@ -4233,6 +4236,29 @@ static int ssl_sess_new_srv_cb(SSL *ssl, SSL_SESSION *sess)
                        /* if there wasn't an old sni but there is a new one */
                        s->ssl_ctx.reused_sess[tid].sni = strdup(sni);
                }
+#ifdef USE_QUIC
+               /* The selected ALPN is not stored without SSL session. */
+               if (qc && (s->ssl_ctx.options & SRV_SSL_O_EARLY_DATA) &&
+                   s->ssl_ctx.reused_sess[tid].ptr) {
+                       const char *alpn = NULL;
+                       int len;
+
+                       if (ssl_sock_get_alpn(conn, qc->xprt_ctx, &alpn, &len)) {
+                               struct quic_early_transport_params *etps = &s->path_params.tps;
+
+                               if (len < sizeof(s->path_params.nego_alpn) &&
+                                   (len != strlen(s->path_params.nego_alpn) ||
+                                    memcmp(&s->path_params.nego_alpn, alpn, len) != 0)) {
+                                       HA_RWLOCK_WRLOCK(SERVER_LOCK, &s->path_params.param_lock);
+                                       memcpy(&s->path_params.nego_alpn, alpn, len);
+                                       s->path_params.nego_alpn[len] = 0;
+                                       /* The transport parameters are not stored without ALPN */
+                                       qc_early_transport_params_cpy(qc, etps, &qc->tx.params);
+                                       HA_RWLOCK_WRUNLOCK(SERVER_LOCK, &s->path_params.param_lock);
+                               }
+                       }
+               }
+#endif
                HA_RWLOCK_WRUNLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.reused_sess[tid].sess_lock);
                HA_RWLOCK_RDUNLOCK(SSL_SERVER_LOCK, &s->ssl_ctx.lock);
        } else {