From b317583f4ad8a8e742781381fa10db5bcd072585 Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Wed, 14 Feb 2024 08:44:36 +0000 Subject: [PATCH] QUIC: Add stream write buffer queries Reviewed-by: Tim Hudson Reviewed-by: Neil Horman (Merged from https://github.com/openssl/openssl/pull/23584) --- doc/man3/SSL_get_value_uint.pod | 54 +++++++++++++++++++++++++++++++-- include/openssl/ssl.h.in | 13 ++++++++ ssl/quic/quic_impl.c | 49 ++++++++++++++++++++++++++++++ util/other.syms | 6 ++++ 4 files changed, 119 insertions(+), 3 deletions(-) diff --git a/doc/man3/SSL_get_value_uint.pod b/doc/man3/SSL_get_value_uint.pod index 2a4e01c7e2..9ea744f4c5 100644 --- a/doc/man3/SSL_get_value_uint.pod +++ b/doc/man3/SSL_get_value_uint.pod @@ -17,7 +17,13 @@ SSL_VALUE_EVENT_HANDLING_MODE_INHERIT, SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT, SSL_VALUE_EVENT_HANDLING_MODE_IMPLICIT, SSL_get_event_handling_mode, -SSL_set_event_handling_mode - +SSL_set_event_handling_mode, +SSL_VALUE_STREAM_WRITE_BUF_SIZE, +SSL_get_stream_write_buf_size, +SSL_VALUE_STREAM_WRITE_BUF_USED, +SSL_get_stream_write_buf_used, +SSL_VALUE_STREAM_WRITE_BUF_AVAIL, +SSL_get_stream_write_buf_avail - manage negotiable features and configuration values for a SSL object =head1 SYNOPSIS @@ -45,6 +51,10 @@ manage negotiable features and configuration values for a SSL object #define SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT #define SSL_VALUE_EVENT_HANDLING_MODE_IMPLICIT + #define SSL_VALUE_STREAM_WRITE_BUF_SIZE + #define SSL_VALUE_STREAM_WRITE_BUF_USED + #define SSL_VALUE_STREAM_WRITE_BUF_AVAIL + The following convenience macros can also be used: int SSL_get_generic_value_uint(SSL *ssl, uint32_t id, uint64_t *value); @@ -64,6 +74,10 @@ The following convenience macros can also be used: int SSL_get_event_handling_mode(SSL *ssl, uint64_t *value); int SSL_set_event_handling_mode(SSL *ssl, uint64_t value); + int SSL_get_stream_write_buf_size(SSL *ssl, uint64_t *value); + int SSL_get_stream_write_buf_avail(SSL *ssl, uint64_t *value); + int SSL_get_stream_write_buf_used(SSL *ssl, uint64_t *value); + =head1 DESCRIPTION SSL_get_value_uint() and SSL_set_value_uint() provide access to configurable @@ -131,11 +145,16 @@ SSL_get_feature_negotiated_uint() for brevity. =back -=head1 CONFIGURABLE VALUES FOR QUIC CONNECTIONS +=head1 CONFIGURABLE VALUES FOR QUIC OBJECTS The following configurable values are supported for QUIC SSL objects. Whether a value is supported for a QUIC connection SSL object or a QUIC stream SSL object -is indicated in the heading for each value: +is indicated in the heading for each value. Values supported for QUIC stream SSL +objects are also supported on QUIC connection SSL objects if they have a default +stream attached. + +SSL_get_value() does not cause internal event processing to occur unless the +documentation for a specific value specifies otherwise. =over 4 @@ -251,6 +270,35 @@ does happen as a result of an API call to an object related to a connection, processing of background events (for example, received QUIC network traffic) may also affect the state of any other object related to a connection. +=item B (stream object) + +Generic read-only statistical value. The size of the write buffer allocated to +hold data written to a stream with L until it is transmitted +and subsequently acknowledged by the peer. This value may change at any time, as +buffer sizes are optimised in response to network conditions to optimise +throughput. + +Can be queried using the convenience macro SSL_get_stream_write_buf_size(). + +=item B (stream object) + +Generic read-only statistical value. The number of bytes currently consumed +in the write buffer which have yet to be acknowledged by the peer. Successful +calls to L which accept data cause this number to increase. +This number will then decrease as data is acknowledged by the peer. + +Can be queried using the convenience macro SSL_get_stream_write_buf_used(). + +=item B (stream object) + +Generic read-only statistical value. The number of bytes available in the write +buffer which have yet to be consumed by calls to L. Successful +calls to L which accept data cause this number to decrease. +This number will increase as data is acknowledged by the peer. It may also +change if the buffer is resized automatically to optimise throughput. + +Can be queried using the convenience macro SSL_get_stream_write_buf_avail(). + =back No configurable values are currently defined for non-QUIC SSL objects. diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in index 0667fc3ec8..988e637dda 100644 --- a/include/openssl/ssl.h.in +++ b/include/openssl/ssl.h.in @@ -2381,6 +2381,9 @@ __owur int SSL_get_conn_close_info(SSL *ssl, # define SSL_VALUE_QUIC_STREAM_UNI_REMOTE_AVAIL 4 # define SSL_VALUE_QUIC_IDLE_TIMEOUT 5 # define SSL_VALUE_EVENT_HANDLING_MODE 6 +# define SSL_VALUE_STREAM_WRITE_BUF_SIZE 7 +# define SSL_VALUE_STREAM_WRITE_BUF_USED 8 +# define SSL_VALUE_STREAM_WRITE_BUF_AVAIL 9 # define SSL_VALUE_EVENT_HANDLING_MODE_INHERIT 0 # define SSL_VALUE_EVENT_HANDLING_MODE_IMPLICIT 1 @@ -2422,6 +2425,16 @@ int SSL_set_value_uint(SSL *s, uint32_t class_, uint32_t id, uint64_t v); SSL_set_generic_value_uint((ssl), SSL_VALUE_EVENT_HANDLING_MODE, \ (value)) +# define SSL_get_stream_write_buf_size(ssl, value) \ + SSL_get_generic_value_uint((ssl), SSL_VALUE_STREAM_WRITE_BUF_SIZE, \ + (value)) +# define SSL_get_stream_write_buf_used(ssl, value) \ + SSL_get_generic_value_uint((ssl), SSL_VALUE_STREAM_WRITE_BUF_USED, \ + (value)) +# define SSL_get_stream_write_buf_avail(ssl, value) \ + SSL_get_generic_value_uint((ssl), SSL_VALUE_STREAM_WRITE_BUF_AVAIL, \ + (value)) + # define SSL_POLL_EVENT_NONE 0 # define SSL_POLL_EVENT_F (1U << 0) /* F (Failure) */ diff --git a/ssl/quic/quic_impl.c b/ssl/quic/quic_impl.c index 31548c1b1d..d24769bfc2 100644 --- a/ssl/quic/quic_impl.c +++ b/ssl/quic/quic_impl.c @@ -3371,11 +3371,50 @@ err: return ret; } +QUIC_TAKES_LOCK +static int qc_get_stream_write_buf_stat(QCTX *ctx, uint32_t class_, + uint64_t *p_value_out, + size_t (*getter)(QUIC_SSTREAM *sstream)) +{ + int ret = 0; + size_t value = 0; + + quic_lock(ctx->qc); + + if (class_ != SSL_VALUE_CLASS_GENERIC) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE_CLASS, + NULL); + goto err; + } + + if (ctx->xso == NULL) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_NO_STREAM, NULL); + goto err; + } + + if (!ossl_quic_stream_has_send(ctx->xso->stream)) { + QUIC_RAISE_NON_NORMAL_ERROR(ctx, SSL_R_STREAM_RECV_ONLY, NULL); + goto err; + } + + if (ossl_quic_stream_has_send_buffer(ctx->xso->stream)) + value = getter(ctx->xso->stream->sstream); + + ret = 1; +err: + quic_unlock(ctx->qc); + *p_value_out = (uint64_t)value; + return ret; +} + QUIC_NEEDS_LOCK static int expect_quic_for_value(SSL *s, QCTX *ctx, uint32_t id) { switch (id) { case SSL_VALUE_EVENT_HANDLING_MODE: + case SSL_VALUE_STREAM_WRITE_BUF_SIZE: + case SSL_VALUE_STREAM_WRITE_BUF_USED: + case SSL_VALUE_STREAM_WRITE_BUF_AVAIL: return expect_quic(s, ctx); default: return expect_quic_conn_only(s, ctx); @@ -3411,6 +3450,16 @@ int ossl_quic_get_value_uint(SSL *s, uint32_t class_, uint32_t id, case SSL_VALUE_EVENT_HANDLING_MODE: return qc_getset_event_handling(&ctx, class_, value, NULL); + case SSL_VALUE_STREAM_WRITE_BUF_SIZE: + return qc_get_stream_write_buf_stat(&ctx, class_, value, + ossl_quic_sstream_get_buffer_size); + case SSL_VALUE_STREAM_WRITE_BUF_USED: + return qc_get_stream_write_buf_stat(&ctx, class_, value, + ossl_quic_sstream_get_buffer_used); + case SSL_VALUE_STREAM_WRITE_BUF_AVAIL: + return qc_get_stream_write_buf_stat(&ctx, class_, value, + ossl_quic_sstream_get_buffer_avail); + default: return QUIC_RAISE_NON_NORMAL_ERROR(&ctx, SSL_R_UNSUPPORTED_CONFIG_VALUE, NULL); diff --git a/util/other.syms b/util/other.syms index e8a813c9bb..84e6bb6ba3 100644 --- a/util/other.syms +++ b/util/other.syms @@ -687,6 +687,9 @@ SSL_get_quic_stream_uni_local_avail define SSL_get_quic_stream_uni_remote_avail define SSL_get_event_handling_mode define SSL_set_event_handling_mode define +SSL_get_stream_write_buf_size define +SSL_get_stream_write_buf_used define +SSL_get_stream_write_buf_avail define SSL_CONN_CLOSE_FLAG_LOCAL define SSL_CONN_CLOSE_FLAG_TRANSPORT define SSLv23_client_method define @@ -752,6 +755,9 @@ SSL_VALUE_EVENT_HANDLING_MODE define SSL_VALUE_EVENT_HANDLING_MODE_INHERIT define SSL_VALUE_EVENT_HANDLING_MODE_IMPLICIT define SSL_VALUE_EVENT_HANDLING_MODE_EXPLICIT define +SSL_VALUE_STREAM_WRITE_BUF_SIZE define +SSL_VALUE_STREAM_WRITE_BUF_USED define +SSL_VALUE_STREAM_WRITE_BUF_AVAIL define TLS_DEFAULT_CIPHERSUITES define deprecated 3.0.0 X509_CRL_http_nbio define deprecated 3.0.0 X509_http_nbio define deprecated 3.0.0