From: Hugo Landau Date: Mon, 16 Jan 2023 15:24:17 +0000 (+0000) Subject: QUIC: Implement SSL_has_pending X-Git-Tag: openssl-3.2.0-alpha1~525 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9280d26a3a14e2aa79ad26cc25e4f41fbaa828ec;p=thirdparty%2Fopenssl.git QUIC: Implement SSL_has_pending Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell Reviewed-by: Paul Dale (Merged from https://github.com/openssl/openssl/pull/20061) --- diff --git a/include/internal/quic_channel.h b/include/internal/quic_channel.h index deade706af5..8cc165ee8fd 100644 --- a/include/internal/quic_channel.h +++ b/include/internal/quic_channel.h @@ -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 diff --git a/include/internal/quic_demux.h b/include/internal/quic_demux.h index 1e5a85f9d74..d439fa67be2 100644 --- a/include/internal/quic_demux.h +++ b/include/internal/quic_demux.h @@ -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 diff --git a/include/internal/quic_ssl.h b/include/internal/quic_ssl.h index 48f05bfb7cb..837c3ba7b53 100644 --- a/include/internal/quic_ssl.h +++ b/include/internal/quic_ssl.h @@ -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 diff --git a/ssl/quic/quic_channel.c b/ssl/quic/quic_channel.c index 1aa14175e7f..fe04dffa34d 100644 --- a/ssl/quic/quic_channel.c +++ b/ssl/quic/quic_channel.c @@ -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 * ================================================================ diff --git a/ssl/quic/quic_demux.c b/ssl/quic/quic_demux.c index 94e4a3e27a5..160bf28168d 100644 --- a/ssl/quic/quic_demux.c +++ b/ssl/quic/quic_demux.c @@ -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; +} diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index 3374045c37e..07f759522ab 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -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); } /* diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index cad4e5f6877..948501a56b2 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -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;