QUIC: Implement SSL_has_pending
authorHugo Landau <hlandau@openssl.org>
Mon, 16 Jan 2023 15:24:17 +0000 (15:24 +0000)
committerPauli <pauli@openssl.org>
Tue, 4 Jul 2023 23:02:26 +0000 (09:02 +1000)
Reviewed-by: Tomas Mraz <tomas@openssl.org>
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Paul Dale <pauli@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/20061)

include/internal/quic_channel.h
include/internal/quic_demux.h
include/internal/quic_ssl.h
ssl/quic/quic_channel.c
ssl/quic/quic_demux.c
ssl/quic/quic_impl.c
ssl/ssl_lib.c

index deade706af5a0cedcf3a1f8a95e4fa6a7ed41c78..8cc165ee8fd605429ecc16491772f508b98c782f 100644 (file)
@@ -340,6 +340,7 @@ uint64_t ossl_quic_channel_get_rx_key_epoch(QUIC_CHANNEL *ch);
 
 /* Artificially trigger a spontaneous TXKU if possible. */
 int ossl_quic_channel_trigger_txku(QUIC_CHANNEL *ch);
+int ossl_quic_channel_has_pending(const QUIC_CHANNEL *ch);
 
 # endif
 
index 1e5a85f9d740bfe1a96b049518a44a3aa06fbc7a..d439fa67be214fec388e71827d22aa1dc6a46aeb 100644 (file)
@@ -333,6 +333,11 @@ int ossl_quic_demux_inject(QUIC_DEMUX *demux,
                            const BIO_ADDR *peer,
                            const BIO_ADDR *local);
 
+/*
+ * Returns 1 if there are any pending URXEs.
+ */
+int ossl_quic_demux_has_pending(const QUIC_DEMUX *demux);
+
 # endif
 
 #endif
index 48f05bfb7cb0a88da385ee1db19f64696f49f0c4..837c3ba7b53454846de3a85fef41d69bb6a8a7a8 100644 (file)
@@ -117,6 +117,10 @@ void ossl_quic_conn_force_assist_thread_wake(SSL *s);
 
 /* For use by tests only. */
 QUIC_CHANNEL *ossl_quic_conn_get_channel(SSL *s);
+uint64_t ossl_quic_set_options(SSL *s, uint64_t opts);
+uint64_t ossl_quic_clear_options(SSL *s, uint64_t opts);
+uint64_t ossl_quic_get_options(SSL *s);
+int ossl_quic_has_pending(const SSL *s);
 
 # endif
 
index 1aa14175e7f8938c1563eb0e224ec485a156eaf6..fe04dffa34d156b98f98701068aa28f88e4ece7a 100644 (file)
@@ -486,6 +486,12 @@ CRYPTO_MUTEX *ossl_quic_channel_get_mutex(QUIC_CHANNEL *ch)
     return ch->mutex;
 }
 
+int ossl_quic_channel_has_pending(const QUIC_CHANNEL *ch)
+{
+    return ossl_quic_demux_has_pending(ch->demux)
+        || ossl_qrx_processed_read_pending(ch->qrx);
+}
+
 /*
  * QUIC Channel: Callbacks from Miscellaneous Subsidiary Components
  * ================================================================
index 94e4a3e27a5a2caec01821602c5ed62c01353c4a..160bf28168d83bf0619135e5f3cc1447dc021434 100644 (file)
@@ -629,3 +629,8 @@ void ossl_quic_demux_reinject_urxe(QUIC_DEMUX *demux,
     ossl_list_urxe_insert_head(&demux->urx_pending, e);
     e->demux_state = URXE_DEMUX_STATE_PENDING;
 }
+
+int ossl_quic_demux_has_pending(const QUIC_DEMUX *demux)
+{
+    return ossl_list_urxe_head(&demux->urx_pending) != NULL;
+}
index 3374045c37ef64103de8060a6d20779d7412d3f3..07f759522ab706f4e7fd121037d682d903a79bf8 100644 (file)
@@ -2116,6 +2116,7 @@ int ossl_quic_peek(SSL *s, void *buf, size_t len, size_t *bytes_read)
  * SSL_pending
  * -----------
  */
+
 QUIC_TAKES_LOCK
 static size_t ossl_quic_pending_int(const SSL *s)
 {
@@ -2145,7 +2146,8 @@ size_t ossl_quic_pending(const SSL *s)
 
 int ossl_quic_has_pending(const SSL *s)
 {
-    return ossl_quic_pending_int(s) > 0;
+    /* Do we have app-side pending data or pending URXEs or RXEs? */
+    return ossl_quic_pending_int(s) > 0 || ossl_quic_channel_has_pending(qc->ch);
 }
 
 /*
index cad4e5f68774d915fd9d1e519cd05db907329fec..948501a56b2d58a6249506b3be7d19e4425cd97b 100644 (file)
@@ -1872,6 +1872,10 @@ int SSL_pending(const SSL *s)
 
 int SSL_has_pending(const SSL *s)
 {
+#ifndef OPENSSL_NO_QUIC
+    const QUIC_CONNECTION *qc = QUIC_CONNECTION_FROM_SSL(s);
+#endif
+
     /*
      * Similar to SSL_pending() but returns a 1 to indicate that we have
      * processed or unprocessed data available or 0 otherwise (as opposed to the
@@ -1889,6 +1893,11 @@ int SSL_has_pending(const SSL *s)
 
     sc = SSL_CONNECTION_FROM_CONST_SSL(s);
 
+#ifndef OPENSSL_NO_QUIC
+    if (qc != NULL)
+        return ossl_quic_has_pending(qc);
+#endif
+
     /* Check buffered app data if any first */
     if (SSL_CONNECTION_IS_DTLS(sc)) {
         TLS_RECORD *rdata;