From 2695f7b19b3dba8a89b7081e2427cdf2f66d232f Mon Sep 17 00:00:00 2001 From: Hugo Landau Date: Fri, 19 Jan 2024 12:52:26 +0000 Subject: [PATCH] QUIC: Add optimised FIN API Reviewed-by: Neil Horman Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/23343) --- doc/man3/SSL_write.pod | 66 +++++++++++++++++++++++++++++++++------- include/openssl/ssl.h.in | 6 ++++ util/libssl.num | 1 + 3 files changed, 62 insertions(+), 11 deletions(-) diff --git a/doc/man3/SSL_write.pod b/doc/man3/SSL_write.pod index 46427d7059..3a63ff1fec 100644 --- a/doc/man3/SSL_write.pod +++ b/doc/man3/SSL_write.pod @@ -2,13 +2,19 @@ =head1 NAME -SSL_write_ex, SSL_write, SSL_sendfile - write bytes to a TLS/SSL connection +SSL_write_ex2, SSL_write_ex, SSL_write, SSL_sendfile, SSL_WRITE_FLAG_CONCLUDE - +write bytes to a TLS/SSL connection =head1 SYNOPSIS #include + #define SSL_WRITE_FLAG_CONCLUDE + ossl_ssize_t SSL_sendfile(SSL *s, int fd, off_t offset, size_t size, int flags); + int SSL_write_ex2(SSL *s, const void *buf, size_t num, + uint64_t flags, + size_t *written); int SSL_write_ex(SSL *s, const void *buf, size_t num, size_t *written); int SSL_write(SSL *ssl, const void *buf, int num); @@ -18,6 +24,10 @@ SSL_write_ex() and SSL_write() write B bytes from the buffer B into the specified B connection. On success SSL_write_ex() will store the number of bytes written in B<*written>. +SSL_write_ex2() functions similarly to SSL_write_ex() but can also accept +optional flags which modify its behaviour. Calling SSL_write_ex2() with a +I argument of 0 is exactly equivalent to calling SSL_write_ex(). + SSL_sendfile() writes B bytes from offset B in the file descriptor B to the specified SSL connection B. This function provides efficient zero-copy semantics. SSL_sendfile() is available only when @@ -26,6 +36,39 @@ It is provided here to allow users to maintain the same interface. The meaning of B is platform dependent. Currently, under Linux it is ignored. +The I argument to SSL_write_ex2() can accept zero or more of the +following flags. Note that which flags are supported will depend on the kind of +SSL object and underlying protocol being used: + +=over 4 + +=item B + +This flag is only supported on QUIC stream SSL objects (or QUIC connection SSL +objects with a default stream attached). + +If this flag is set, and the call to SSL_write_ex2() succeeds, and all of the +data passed to the call is written (meaning that C<*written == num>), the +relevant QUIC stream's send part is concluded automatically as though +L was called (causing transmission of a FIN for the +stream). + +While using this flag is semantically equivalent to calling +L after a successful call to this function, using this +flag enables greater efficiency than making these two API calls separately, as +it enables the written stream data and the FIN flag indicating the end of the +stream to be scheduled as part of the same QUIC STREAM frame and QUIC packet. + +Setting this flag does not cause a stream's send part to be concluded if not all +of the data passed to the call was consumed. + +=back + +A call to SSL_write_ex2() fails if a flag is passed which is not supported or +understood by the given SSL object. An application should determine if a flag is +supported (for example, for B, that a QUIC stream SSL +object is being used) before attempting to use it. + =head1 NOTES In the paragraphs below a "write function" is defined as one of either @@ -89,16 +132,17 @@ the peer. =head1 RETURN VALUES -SSL_write_ex() will return 1 for success or 0 for failure. Success means that -all requested application data bytes have been written to the SSL connection or, -if SSL_MODE_ENABLE_PARTIAL_WRITE is in use, at least 1 application data byte has -been written to the SSL connection. Failure means that not all the requested -bytes have been written yet (if SSL_MODE_ENABLE_PARTIAL_WRITE is not in use) or -no bytes could be written to the SSL connection (if -SSL_MODE_ENABLE_PARTIAL_WRITE is in use). Failures can be retryable (e.g. the -network write buffer has temporarily filled up) or non-retryable (e.g. a fatal -network error). In the event of a failure call L to find out -the reason which indicates whether the call is retryable or not. +SSL_write_ex() and SSL_write_ex2() return 1 for success or 0 for failure. +Success means that all requested application data bytes have been written to the +SSL connection or, if SSL_MODE_ENABLE_PARTIAL_WRITE is in use, at least 1 +application data byte has been written to the SSL connection. Failure means that +not all the requested bytes have been written yet (if +SSL_MODE_ENABLE_PARTIAL_WRITE is not in use) or no bytes could be written to the +SSL connection (if SSL_MODE_ENABLE_PARTIAL_WRITE is in use). Failures can be +retryable (e.g. the network write buffer has temporarily filled up) or +non-retryable (e.g. a fatal network error). In the event of a failure call +L to find out the reason which indicates whether the call is +retryable or not. For SSL_write() the following return values can occur: diff --git a/include/openssl/ssl.h.in b/include/openssl/ssl.h.in index b22522d006..8f1aff9fc0 100644 --- a/include/openssl/ssl.h.in +++ b/include/openssl/ssl.h.in @@ -1944,6 +1944,12 @@ long SSL_callback_ctrl(SSL *, int, void (*)(void)); long SSL_CTX_ctrl(SSL_CTX *ctx, int cmd, long larg, void *parg); long SSL_CTX_callback_ctrl(SSL_CTX *, int, void (*)(void)); +# define SSL_WRITE_FLAG_CONCLUDE (1U << 0) + +__owur int SSL_write_ex2(SSL *s, const void *buf, size_t num, + uint64_t flags, + size_t *written); + # define SSL_EARLY_DATA_NOT_SENT 0 # define SSL_EARLY_DATA_REJECTED 1 # define SSL_EARLY_DATA_ACCEPTED 2 diff --git a/util/libssl.num b/util/libssl.num index 22b31fb012..c58d3330fb 100644 --- a/util/libssl.num +++ b/util/libssl.num @@ -577,3 +577,4 @@ SSL_handle_events 577 3_2_0 EXIST::FUNCTION: SSL_get_event_timeout 578 3_2_0 EXIST::FUNCTION: SSL_get0_group_name 579 3_2_0 EXIST::FUNCTION: SSL_is_stream_local 580 3_2_0 EXIST::FUNCTION: +SSL_write_ex2 ? 3_3_0 EXIST::FUNCTION: -- 2.39.2