]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: quic-be: make SSL/QUIC objects use their own indexes (ssl_qc_app_data_index)
authorFrederic Lecaille <flecaille@haproxy.com>
Wed, 10 Sep 2025 16:11:50 +0000 (18:11 +0200)
committerFrederic Lecaille <flecaille@haproxy.com>
Thu, 11 Sep 2025 07:51:28 +0000 (09:51 +0200)
This index is used to retrieve the quic_conn object from its SSL object, the same
way the connection is retrieved from its SSL object for SSL/TCP connections.

This patch implements two helper functions to avoid the ugly code with such blocks:

   #ifdef USE_QUIC
   else if (qc) { .. }
   #endif

Implement ssl_sock_get_listener() to return the listener from an SSL object.
Implement ssl_sock_get_conn() to return the connection from an SSL object
and optionally a pointer to the ssl_sock_ctx struct attached to the connections
or the quic_conns.

Use this functions where applicable:
   - ssl_tlsext_ticket_key_cb() calls ssl_sock_get_listener()
   - ssl_sock_infocbk() calls ssl_sock_get_conn()
   - ssl_sock_msgcbk() calls ssl_sock_get_ssl_conn()
   - ssl_sess_new_srv_cb() calls ssl_sock_get_conn()
   - ssl_sock_srv_verifycbk() calls ssl_sock_get_conn()

Also modify qc_ssl_sess_init() to initialize the ssl_qc_app_data_index index for
the QUIC backends.

include/haproxy/ssl_sock.h
src/quic_ssl.c
src/ssl_sock.c

index 7c53947b1b794845c172abd3e1350a83429ef693..d885a1ba0ae0f437f1ba8f14e225cbedc2875e56 100644 (file)
@@ -28,6 +28,7 @@
 #include <haproxy/openssl-compat.h>
 #include <haproxy/pool-t.h>
 #include <haproxy/proxy-t.h>
+#include <haproxy/quic_conn-t.h>
 #include <haproxy/ssl_sock-t.h>
 #include <haproxy/thread.h>
 
@@ -188,6 +189,55 @@ static inline void cert_ignerr_bitfield_set_all(unsigned long long *bitfield)
        memset(bitfield, -1, IGNERR_BF_SIZE*sizeof(*bitfield));
 }
 
+/* Listener only function.
+ * Return the listener attached to <s> SSL object.
+ */
+static inline struct listener *ssl_sock_get_listener(const SSL *s)
+{
+       struct connection *conn = SSL_get_ex_data(s, ssl_app_data_index);
+#ifdef USE_QUIC
+       struct quic_conn *qc = SSL_get_ex_data(s, ssl_qc_app_data_index);
+#endif
+
+       if (conn)
+               return __objt_listener(conn->target);
+#ifdef USE_QUIC
+       else if (qc)
+               return qc->li;
+#endif
+       return NULL;
+}
+
+/* Return the connection from <s> SSL object.
+ * Note that for QUIC, this function must be called with very much attention.
+ * Indeed, for QUIC frontends, qc->conn is not always initialized.
+ * For QUIC backends, this is always the case if the SSL object is released
+ * at the same time as the connection.
+ */
+static inline struct connection *ssl_sock_get_conn(const SSL *s, struct ssl_sock_ctx **ctx)
+{
+       struct connection *ret = NULL;
+       struct connection *conn = SSL_get_ex_data(s, ssl_app_data_index);
+#ifdef USE_QUIC
+       struct quic_conn *qc = SSL_get_ex_data(s, ssl_qc_app_data_index);
+#endif
+
+       if (conn) {
+               ret = conn;
+               if (ctx)
+                       *ctx = conn_get_ssl_sock_ctx(conn);
+       }
+#ifdef USE_QUIC
+       else if (qc) {
+               ret = qc->conn;
+               if (ctx)
+                       *ctx = qc->xprt_ctx;
+       }
+#endif
+       return ret;
+}
+
+
 #endif /* USE_OPENSSL */
 #endif /* _HAPROXY_SSL_SOCK_H */
 
index 7e20a906b272e6dd81bea7c64f4384a505bc318e..60e79a5166faa29b4840846bec75b0f2b8158db8 100644 (file)
@@ -1179,7 +1179,6 @@ static int qc_ssl_sess_init(struct quic_conn *qc, SSL_CTX *ssl_ctx, SSL **ssl,
        }
 
        if (!SSL_set_ex_data(*ssl, ssl_qc_app_data_index, qc) ||
-           (!server && !SSL_set_ex_data(*ssl, ssl_app_data_index, conn)) ||
            !quic_ssl_set_tls_cbs(*ssl)) {
                SSL_free(*ssl);
                *ssl = NULL;
index e1aa2936db7287a629c2ea3857fcbae2def8bbf2..b973a3967ee9f73835a413514bedf525072ba81e 100644 (file)
@@ -1121,27 +1121,17 @@ static int ssl_hmac_init(MAC_CTX *hctx, unsigned char *key, int key_len, const E
 
 static int ssl_tlsext_ticket_key_cb(SSL *s, unsigned char key_name[16], unsigned char *iv, EVP_CIPHER_CTX *ectx, MAC_CTX *hctx, int enc)
 {
-       struct tls_keys_ref *ref = NULL;
        union tls_sess_key *keys;
        int head;
        int i;
        int ret = -1; /* error by default */
-       struct connection *conn = SSL_get_ex_data(s, ssl_app_data_index);
-#ifdef USE_QUIC
-       struct quic_conn *qc = SSL_get_ex_data(s, ssl_qc_app_data_index);
-#endif
-
-       if (conn)
-               ref  = __objt_listener(conn->target)->bind_conf->keys_ref;
-#ifdef USE_QUIC
-       else if (qc)
-               ref =  qc->li->bind_conf->keys_ref;
-#endif
+       struct listener *l;
+       struct tls_keys_ref *ref;
 
-       if (!ref) {
-               /* must never happen */
-               ABORT_NOW();
-       }
+       l = ssl_sock_get_listener(s);
+       BUG_ON(!l);
+       ref = l->bind_conf->keys_ref;
+       BUG_ON(!ref);
 
        HA_RWLOCK_RDLOCK(TLSKEYS_REF_LOCK, &ref->lock);
 
@@ -1613,28 +1603,16 @@ out:
 
 void ssl_sock_infocbk(const SSL *ssl, int where, int ret)
 {
-       struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
-#ifdef USE_QUIC
-       struct quic_conn *qc = SSL_get_ex_data(ssl, ssl_qc_app_data_index);
-#endif /* USE_QUIC */
+       struct connection *conn;
        struct ssl_sock_ctx *ctx = NULL;
 
        BIO *write_bio;
        (void)ret; /* shut gcc stupid warning */
+       (void)conn;
 
-       if (conn)
-               ctx = conn_get_ssl_sock_ctx(conn);
-#ifdef USE_QUIC
-       else if (qc)
-               ctx = qc->xprt_ctx;
-#endif /* USE_QUIC */
-
-       if (!ctx) {
-               /* must never happen */
-               ABORT_NOW();
-               return;
-       }
-
+       conn = ssl_sock_get_conn(ssl, &ctx);
+       /* must never happen */
+       BUG_ON(!ctx);
 #ifndef SSL_OP_NO_RENEGOTIATION
        /* Please note that BoringSSL defines this macro to zero so don't
         * change this to #if and do not assign a default value to this macro!
@@ -2128,7 +2106,7 @@ static void ssl_init_keylog(struct connection *conn, int write_p, int version,
 /* Callback is called for ssl protocol analyse */
 void ssl_sock_msgcbk(int write_p, int version, int content_type, const void *buf, size_t len, SSL *ssl, void *arg)
 {
-       struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
+       struct connection *conn = ssl_sock_get_conn(ssl, NULL);
        struct ssl_sock_msg_callback *cbk;
 
        /* Try to call all callback functions that were registered by using
@@ -3862,10 +3840,11 @@ static int sh_ssl_sess_store(unsigned char *s_id, unsigned char *data, int data_
 /* SSL callback used when a new session is created while connecting to a server */
 static int ssl_sess_new_srv_cb(SSL *ssl, SSL_SESSION *sess)
 {
-       struct connection *conn = SSL_get_ex_data(ssl, ssl_app_data_index);
+       struct connection *conn = ssl_sock_get_conn(ssl, NULL);
        struct server *s;
        uint old_tid;
 
+       BUG_ON(!conn);
        s = __objt_server(conn->target);
 
        /* RWLOCK: only read lock the SSL cache even when writing in it because there is
@@ -4548,7 +4527,8 @@ static int ssl_sock_srv_verifycbk(int ok, X509_STORE_CTX *ctx)
                return ok;
 
        ssl = X509_STORE_CTX_get_ex_data(ctx, SSL_get_ex_data_X509_STORE_CTX_idx());
-       conn = SSL_get_ex_data(ssl, ssl_app_data_index);
+       conn = ssl_sock_get_conn(ssl, NULL);
+       BUG_ON(!conn);
        ssl_ctx = __conn_get_ssl_sock_ctx(conn);
 
        /* We're checking if the provided hostnames match the desired one. The