]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: ssl-sample: add ssl_fc_early_rcvd() to detect use of early data
authorWilly Tarreau <w@1wt.eu>
Wed, 29 Oct 2025 07:03:01 +0000 (08:03 +0100)
committerWilly Tarreau <w@1wt.eu>
Wed, 29 Oct 2025 07:13:29 +0000 (08:13 +0100)
We currently have ssl_fc_has_early() which says that early data are still
unconfirmed by a final handshake, but nothing to see if a client has been
able to use early data at all, which is a problem because such mechanisms
generally depend on multiple factors and it's hard to know when they start
to work. This new sample fetch function will indicate that some early data
were seen over that front connection, i.e. this can be used to confirm
that at some point the client was able to push some. This is essentially
a debugging tool that has no practical use case other than debugging.

doc/configuration.txt
src/ssl_sample.c

index 4bcf4ea6b2756b82ebcfe877c45d748f8c668533..136a7b749854f80c3fffacdf150bf66522864f42 100644 (file)
@@ -25028,6 +25028,15 @@ ssl_fc_curve : string
   connection was made over an SSL/TLS transport layer. This requires
   OpenSSL >= 3.0.0.
 
+ssl_fc_early_rcvd : boolean
+  Returns true if early data were seen over that connection, regardless of the
+  fact that the handshake has since completed. It has no practical use case for
+  traffic processing, however it's about the only way to "see" that a client
+  used 0-RTT to send early data, and is sometimes useful when debugging, since
+  the only other alternatives are network traffic captures or logging the front
+  connection's flags and matching them in the code. It may also be useful to
+  get statistics on clients' capabilities. See also "ssl_fc_has_early".
+
 ssl_fc_early_exporter_secret : string
   Return the EARLY_EXPORTER_SECRET as an hexadecimal string for the
   front connection when the incoming connection was made over an TLS 1.3
@@ -25133,7 +25142,8 @@ ssl_fc_has_crt : boolean
 ssl_fc_has_early : boolean
   Returns true if early data were sent, and the handshake didn't complete yet.
   As it has security implications, it is useful to be able to refuse those, or
-  wait until the handshake completes (via the "wait-for-handshake" action).
+  wait until the handshake completes (via the "wait-for-handshake" action). See
+  also "ssl_fc_early_rcvd".
 
 ssl_fc_has_sni : boolean
   This checks for the presence of a Server Name Indication TLS extension (SNI)
index c64522d240f89c58a944a2812745415cee5a08f7..4746b8c0c2844ea35945166c4db5dfff3576fde2 100644 (file)
@@ -574,6 +574,27 @@ smp_fetch_ssl_fc_has_early(const struct arg *args, struct sample *smp, const cha
        return 1;
 }
 
+static int
+smp_fetch_ssl_fc_early_rcvd(const struct arg *args, struct sample *smp, const char *kw, void *private)
+{
+       SSL *ssl;
+       struct connection *conn;
+
+       conn = objt_conn(smp->sess->origin);
+       ssl = ssl_sock_get_ssl_object(conn);
+       if (!ssl)
+               return 0;
+
+       smp->flags = 0;
+       smp->data.type = SMP_T_BOOL;
+#ifdef OPENSSL_IS_BORINGSSL
+       smp->data.u.sint = SSL_early_data_accepted(ssl);
+#else
+       smp->data.u.sint = !!(conn->flags & CO_FL_EARLY_DATA);
+#endif
+       return 1;
+}
+
 /* boolean, returns true if client cert was present */
 static int
 smp_fetch_ssl_fc_has_crt(const struct arg *args, struct sample *smp, const char *kw, void *private)
@@ -2515,6 +2536,7 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, {
 #if (HA_OPENSSL_VERSION_NUMBER >= 0x3000000fL)
         { "ssl_fc_curve",           smp_fetch_ssl_fc_ec,          0,                   NULL,    SMP_T_STR,  SMP_USE_L5CLI },
 #endif
+       { "ssl_fc_early_rcvd",      smp_fetch_ssl_fc_early_rcvd,  0,                   NULL,    SMP_T_BOOL, SMP_USE_L5CLI },
        { "ssl_fc_has_crt",         smp_fetch_ssl_fc_has_crt,     0,                   NULL,    SMP_T_BOOL, SMP_USE_L5CLI },
        { "ssl_fc_has_early",       smp_fetch_ssl_fc_has_early,   0,                   NULL,    SMP_T_BOOL, SMP_USE_L5CLI },
        { "ssl_fc_has_sni",         smp_fetch_ssl_fc_has_sni,     0,                   NULL,    SMP_T_BOOL, SMP_USE_L5CLI },