QUIC: Add stream write buffer queries
authorHugo Landau <hlandau@openssl.org>
Wed, 14 Feb 2024 08:44:36 +0000 (08:44 +0000)
committerHugo Landau <hlandau@openssl.org>
Sat, 9 Mar 2024 08:56:59 +0000 (08:56 +0000)
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Neil Horman <nhorman@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/23584)

doc/man3/SSL_get_value_uint.pod
include/openssl/ssl.h.in
ssl/quic/quic_impl.c
util/other.syms

index 2a4e01c7e2e437c4ebc105b2a34d2068a7ee5774..9ea744f4c53fa6da9274746124b9f7aa03364465 100644 (file)
@@ -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<SSL_VALUE_STREAM_WRITE_BUF_SIZE> (stream object)
+
+Generic read-only statistical value. The size of the write buffer allocated to
+hold data written to a stream with L<SSL_write_ex(3)> 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<SSL_VALUE_STREAM_WRITE_BUF_USED> (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<SSL_write_ex(3)> 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<SSL_VALUE_STREAM_WRITE_BUF_AVAIL> (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<SSL_write_ex(3)>. Successful
+calls to L<SSL_write_ex(3)> 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.
index 0667fc3ec8134b28f265b43a47ea6a6d08848a05..988e637dda98fffc61b7eb3baa6633463b618b6b 100644 (file)
@@ -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) */
index 31548c1b1d7b4f721ac77afad020fc5d64d252eb..d24769bfc269089162a8d8207f6ea037fddc9d33 100644 (file)
@@ -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);
index e8a813c9bb0a42fa44b3d74a3c7626594ee3635c..84e6bb6ba3efe1ef9f1a4beafba0961abfa3b281 100644 (file)
@@ -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