=pod =head1 NAME openssl-quic - OpenSSL QUIC =head1 DESCRIPTION OpenSSL 3.2 and later features support for the QUIC transport protocol. Currently, only client connectivity is supported. This man page describes the usage of QUIC client functionality for both existing and new applications. QUIC functionality uses the standard SSL API. A QUIC connection is represented by an SSL object in the same way that a TLS connection is. Only minimal changes are needed to existing applications making use of the libssl APIs to make use of QUIC client functionality. To make use of QUIC, use the SSL method L or L with L. When a QUIC connection is created, by default, it operates in default stream mode, which is intended to provide compatibility with existing non-QUIC application usage patterns. In this mode, the connection has a single stream associated with it. Calls to L and L on the QUIC connection SSL object read and write from that stream. Whether the stream is client-initiated or server-initiated from a QUIC perspective depends on whether L or L is called first. See the MODES OF OPERATION section for more information. The default stream mode is intended for compatibility with existing applications. New applications using QUIC are recommended to disable default stream mode and use the multi-stream API; see the MODES OF OPERATION section and the RECOMMENDATIONS FOR NEW APPLICATIONS section for more information. The remainder of this man page discusses, in order: =over 4 =item Default stream mode versus multi-stream mode; =item The changes to existing libssl APIs which are driven by QUIC-related implementation requirements, which existing applications should bear in mind; =item Aspects which must be considered by existing applications when adopting QUIC, including potential changes which may be needed. =item Recommended usage approaches for new applications. =item New, QUIC-specific APIs. =back =head1 MODES OF OPERATION =head2 Default Stream Mode A QUIC client connection can be used in either default stream mode or multi-stream mode. By default, a newly created QUIC connection SSL object uses default stream mode. In default stream mode, a stream is implicitly created and bound to the QUIC connection SSL object; L and L calls to the QUIC connection SSL object work by default and are mapped to that stream. When default stream mode is used, any API function which can be called on a QUIC stream SSL object can also be called on a QUIC connection SSL object, in which case it affects the default stream bound to the connection. The identity of a QUIC stream, including its stream ID, varies depending on whether a stream is client-initiated or server-initiated. In default stream mode, if a client application calls L first before any call to L on the connection, it is assumed that the application protocol is using a server-initiated stream, and the L call will not complete (either blocking, or failing appropriately if nonblocking mode is configured) until the server initiates a stream. Conversely, if the client application calls L before any call to L on the connection, it is assumed that a client-initiated stream is to be used and such a stream is created automatically. Default stream mode is intended to aid compatibility with legacy applications. New applications adopting QUIC should use multi-stream mode, described below, and avoid use of the default stream functionality. It is possible to use additional streams in default stream mode using L and L; note that the default incoming stream policy will need to be changed using L in order to use L in this case. However, applications using additional streams are strongly recommended to use multi-stream mode instead. Calling L or L before a default stream has been associated with the QUIC connection SSL object will inhibit future creation of a default stream. =head2 Multi-Stream Mode The recommended usage mode for new applications adopting QUIC is multi-stream mode, in which no default stream is attached to the QUIC connection SSL object and attempts to call L and L on the QUIC connection SSL object fail. Instead, an application calls L or L to create individual stream SSL objects for sending and receiving application data using L and L. To use multi-stream mode, call L with an argument of B; this function must be called prior to initiating the connection. The default stream mode cannot be changed after initiating a connection. When multi-stream mode is used, meaning that no default stream is associated with the connection, calls to API functions which are defined as operating on a QUIC stream fail if called on the QUIC connection SSL object. For example, calls such as L or L will fail. =head1 CHANGES TO EXISTING APIS Most SSL APIs, such as L and L, function as they do for TLS connections and do not have changed semantics, with some exceptions. The changes to the semantics of existing APIs are as follows: =over 4 =item Since QUIC uses UDP, L, L and L function as before, but must now receive a BIO with datagram semantics. There are broadly four options for applications to use as a network BIO: =over 4 =item L, recommended for most applications, replaces L and provides a UDP socket. =item L provides BIO pair-like functionality but with datagram semantics, and is recommended for existing applications which use a BIO pair or memory BIO to manage libssl's communication with the network. =item L provides a simple memory BIO-like interface but with datagram semantics. Unlike L, it is unidirectional. =item An application may also choose to implement a custom BIO. The new L and L APIs must be supported. =back =item L, L and L traditionally instantiate a L. For QUIC, these functions instead instantiate a L. This is equivalent to instantiating a L and using L and L. =item Traditionally, whether the application-level I/O APIs (such as L and L operated in a blocking fashion was directly correlated with whether the underlying network socket was configured in a blocking fashion. This is no longer the case; applications must explicitly configure the desired application-level blocking mode using L. See L for details. =item Network-level I/O must always be performed in a nonblocking manner. The application can still enjoy blocking semantics for calls to application-level I/O functions such as L and L, but the underlying network BIO provided to QUIC (such as a L) must be configured in nonblocking mode. For application-level blocking functionality, see L. =item L has been changed to automatically use a L when used with QUIC, therefore applications which use this do not need to change the BIO they use. =item L cannot be used with QUIC and applications must change to use L instead. =item L has significant changes in relation to how QUIC connections must be shut down. In particular, applications should be advised that the full RFC-conformant QUIC shutdown process may take an extended amount of time. This may not be suitable for short-lived processes which should exit immediately after their usage of a QUIC connection is completed. A rapid shutdown mode is available for such applications. For details, see L. =item L, L and L no longer reflect the I/O state of the network BIO passed to the QUIC SSL object, but instead reflect the flow control state of the QUIC stream associated with the SSL object. When used in nonblocking mode, B indicates that the receive part of a QUIC stream does not currently have any more data available to be read, and B indicates that the stream's internal buffer is full. To determine if the QUIC implementation currently wishes to be informed of incoming network datagrams, use the new function L; likewise, to determine if the QUIC implementation currently wishes to be informed when it is possible to transmit network datagrams, use the new function L. Only applications which wish to manage their own event loops need to use these functions; see B for further discussion. =item The use of ALPN is mandatory when using QUIC. Attempts to connect without configuring ALPN will fail. For information on how to configure ALPN, see L. =item Whether QUIC operates in a client or server mode is determined by the B used, rather than by calls to L or L. It is not necessary to call either of L or L before connecting, but if either of these are called, the function called must be congruent with the B being used. Currently, only client mode is supported. =item The L and L APIs are not used and the values passed to them are ignored, as OpenSSL QUIC currently always uses TLS 1.3. =item The following libssl functionality is not available when used with QUIC. =over 4 =item Async functionality =item B =item Record Padding and Fragmentation (L, etc.) =item L support =item SRTP functionality =item TLSv1.3 Early Data =item TLS Next Protocol Negotiation cannot be used and is superseded by ALPN, which must be used instead. The use of ALPN is mandatory with QUIC. =item Post-Handshake Client Authentication is not available as QUIC prohibits its use. =item QUIC requires the use of TLSv1.3 or later, therefore functionality only relevant to older TLS versions is not available. =item Some cipher suites which are generally available for TLSv1.3 are not available for QUIC, such as B. Your application may need to adjust the list of acceptable cipher suites it passes to libssl. =item CCM mode is not currently supported. =back The following libssl functionality is also not available when used with QUIC, but calls to the relevant functions are treated as no-ops: =over 4 =item Readahead (L, etc.) =back =back =head1 CONSIDERATIONS FOR EXISTING APPLICATIONS Existing applications seeking to adopt QUIC should apply the following list to determine what changes they will need to make: =over 4 =item An application wishing to use QUIC must use L or L as its SSL method. For more information on the differences between these two methods, see B. =item Determine how to provide QUIC with network access. Determine which of the below apply for your application: =over 4 =item Your application uses L to construct a BIO which is passed to the SSL object to provide it with network access. Changes needed: Change your application to use L instead when using QUIC. The socket must be configured in nonblocking mode. You may or may not need to use L to set the initial peer address; see the B section for details. =item Your application uses L to construct a BIO which is passed to the SSL object to provide it with network access. Changes needed: No changes needed. Use of QUIC is detected automatically and a datagram socket is created instead of a normal TCP socket. =item Your application uses any other I/O strategy in this list but combines it with a L, for example using L. Changes needed: Disable the usage of L when using QUIC. Usage of such a buffer is incompatible with QUIC as QUIC requires datagram semantics in its interaction with the network. =item Your application uses a BIO pair to cause the SSL object to read and write network traffic to a memory buffer. Your application manages the transmission and reception of buffered data itself in a way unknown to libssl. Changes needed: Switch from using a conventional BIO pair to using L instead, which has the necessary datagram semantics. You will need to modify your application to transmit and receive using a UDP socket and to use datagram semantics when interacting with the L instance. =item Your application uses a custom BIO method to provide the SSL object with network access. Changes needed: The custom BIO must be re-architected to have datagram semantics. L and L must be implemented. These calls must operate in a nonblocking fashion. Optionally, implement the L and L methods if desired. Implementing these methods is required if blocking semantics at the SSL API level are desired. =back =item An application must explicitly configure whether it wishes to use the SSL APIs in blocking mode or not. Traditionally, an SSL object has automatically operated in blocking or nonblocking mode based on whether the underlying network BIO operates in blocking or nonblocking mode. QUIC requires the use of a nonblocking network BIO, therefore the blocking mode at the application level must be explicitly configured by the application using the new L API. The default mode is blocking. If an application wishes to use the SSL object APIs at application level in a nonblocking manner, it must add a call to L to disable blocking mode. =item If your application does not choose to use thread assisted mode, it must ensure that it calls an I/O function on the SSL object (for example, L or L), or the new function L, regularly. If the SSL object is used in blocking mode, an ongoing blocking call to an I/O function satisfies this requirement. This is required to ensure that timer events required by QUIC are handled in a timely fashion. Most applications will service the SSL object by calling L or L regularly. If an application does not do this, it should ensure that L is called regularly. L can be used to determine when L must next be called. If the SSL object is being used with an underlying network BIO which is pollable (such as L), the application can use L, L to obtain resources which can be used to determine when L should be called due to network I/O. Applications which use thread assisted mode do not need to be concerned with this requirement, as the QUIC implementation ensures timeout events are handled in a timely manner. See B for details. =item Ensure that your usage of L, L and L reflects the API changes described in B. In particular, you should use these APIs to determine the ability of a QUIC stream to receive or provide application data, not to to determine if network I/O is required. =item Evaluate your application's use of L in light of the changes discussed in B. Depending on whether your application wishes to prioritise RFC conformance or rapid shutdown, consider using the new L API instead. See B for details. =back =head1 RECOMMENDED USAGE IN NEW APPLICATIONS The recommended usage in new applications varies depending on three independent design decisions: =over 4 =item Whether the application will use blocking or nonblocking I/O at the application level (configured using L). If the application does nonblocking I/O at the application level it can choose to manage its own polling and event loop; see B. =item Whether the application intends to give the QUIC implementation direct access to a network socket (e.g. via L) or whether it intends to buffer transmitted and received datagrams via a L or custom BIO. The former is preferred where possible as it reduces latency to the network, which enables QUIC to achieve higher performance and more accurate connection round trip time (RTT) estimation. =item Whether thread assisted mode will be used (see B). =back Simple demos for QUIC usage under these various scenarios can be found at L. Applications which wish to implement QUIC-specific protocols should be aware of the APIs listed under B which provide access to QUIC-specific functionality. For example, L can be used to indicate the end of the sending part of a stream, and L can be used to provide a QUIC application error code when closing a connection. Regardless of the design decisions chosen above, it is recommended that new applications avoid use of the default stream mode and use the multi-stream API by calling L; see the MODES OF OPERATION section for details. =head1 QUIC-SPECIFIC APIS This section details new APIs which are directly or indirectly related to QUIC. For details on the operation of each API, see the referenced man pages. The following SSL APIs are new but relevant to both QUIC and DTLS: =over 4 =item L Determines when the QUIC implementation should next be woken up via a call to L (or another I/O function such as L or L), if ever. This can also be used with DTLS and supersedes L for new usage. =item L This is a non-specific I/O operation which makes a best effort attempt to perform any pending I/O or timeout processing. It can be used to advance the QUIC state machine by processing incoming network traffic, generating outgoing network traffic and handling any expired timeout events. Most other I/O functions on an SSL object, such as L and L implicitly perform event handling on the SSL object, so calling this function is only needed if no other I/O function is to be called. This can also be used with DTLS and supersedes L for new usage. =back The following SSL APIs are specific to QUIC: =over 4 =item L, L Configures whether blocking semantics are used at the application level. This determines whether calls to functions such as L and L will block. =item L, L These functions facilitate operation in nonblocking mode. When an SSL object is being used with an underlying network read BIO which supports polling, L outputs an OS resource which can be used to synchronise on network readability events which should result in a call to L. L works in an analogous fashion for the underlying network write BIO. The poll descriptors provided by these functions need only be used when L and L return 1, respectively. =item L, L These functions facilitate operation in nonblocking mode and are used in conjunction with L and L respectively. They determine whether the respective poll descriptor is currently relevant for the purposes of polling. =item L This function can be used to set the initial peer address for an outgoing QUIC connection. This function must be used in the general case when creating an outgoing QUIC connection; however, the correct initial peer address can be autodetected in some cases. See L for details. =item L This augments L by allowing an application error code to be specified. It also allows a client to decide how quickly it wants a shutdown to be performed, potentially by trading off strict RFC compliance. =item L This allows an application to indicate the normal end of the sending part of a QUIC stream. This corresponds to the FIN flag in the QUIC RFC. The receiving part of a stream remains usable. =item L This allows an application to indicate the non-normal termination of the sending part of a stream. This corresponds to the RESET_STREAM frame in the QUIC RFC. =item L and L This allows an application to determine the current stream states for the sending and receiving parts of a stream respectively. =item L and L This allows an application to determine the application error code which was signalled by a peer which has performed a non-normal stream termination of the respective sending or receiving part of a stream, if any. =item L This allows an application to determine the error code which was signalled when the local or remote endpoint terminated the QUIC connection. =item L Gets the QUIC connection SSL object from a QUIC stream SSL object. =item L Returns 1 if an SSL object is not a QUIC stream SSL object. =item L Provides information on the kind of QUIC stream which is attached to the SSL object. =item L Returns the QUIC stream ID which the QUIC protocol has associated with a QUIC stream. =item L Creates a new QUIC stream SSL object representing a new, locally-initiated QUIC stream. =item L Potentially yields a new QUIC stream SSL object representing a new remotely-initiated QUIC stream, blocking until one is available if the connection is configured to do so. =item L Provides information on the number of pending remotely-initiated streams. =item L Configures how incoming, remotely-initiated streams are handled. The incoming stream policy can be used to automatically reject streams created by the peer, or allow them to be handled using L. =item L Used to configure or disable default stream mode; see the MODES OF OPERATION section for details. =back The following BIO APIs are not specific to QUIC but have been added to facilitate QUIC-specific requirements and are closely associated with its use: =over 4 =item L This is a new BIO method which is similar to a conventional BIO pair but provides datagram semantics. =item L, L This is a new BIO API which allows a BIO to expose a poll descriptor. This API is used to implement the corresponding SSL APIs L and L. =item L, L This is a new BIO API which can be implemented by BIOs which implement datagram semantics. It is implemented by L and L. It is used by the QUIC implementation to send and receive UDP datagrams. =item L, L By default, L has semantics comparable to those of Berkeley sockets being used with datagram semantics. This allows an alternative mode to be enabled in which datagrams will not be silently truncated if they are too large. =item L, L These functions are used to allow the user of one end of a L to indicate its capabilities to the other end of a L. In particular, this allows an application to inform the QUIC implementation of whether it is prepared to handle local and/or peer addresses in transmitted datagrams and to provide the applicable information in received datagrams. =item L, L, L Local addressing support refers to the ability of a BIO with datagram semantics to allow a source address to be specified on transmission and to report the destination address on reception. These functions can be used to determine if a BIO can support local addressing and to enable local addressing support if it can. =item L This is used to determine if an error while calling L or L is ephemeral in nature, such as "would block" errors. =back =head1 THREAD ASSISTED MODE The optional thread assisted mode can be used with L. In this mode, a background thread is created automatically. The OpenSSL QUIC implementation then takes responsibility for ensuring that timeout events are handled on a timely basis even if no SSL I/O function such as L or L is called by the application for a long time. All necessary locking is handled automatically internally, but the thread safety guarantees for the public SSL API are unchanged. Therefore, an application must still do its own locking if it wishes to make concurrent use of the public SSL APIs. Because this method relies on threads, it is not available on platforms where threading support is not available or not supported by OpenSSL. However, it does provide the simplest mode of usage for an application. The implementation may or may not use a common thread or thread pool to service multiple SSL objects in the same B. =head1 APPLICATION-DRIVEN EVENT LOOPS OpenSSL's QUIC implementation is designed to facilitate applications which wish to use the SSL APIs in a blocking fashion, but is also designed to facilitate applications which wish to use the SSL APIs in a nonblocking fashion and manage their own event loops and polling directly. This is useful when it is desirable to host OpenSSL's QUIC implementation on top of an application's existing nonblocking I/O infrastructure. This is supported via the concept of poll descriptors; see L for details. Broadly, a B is a structure which expresses some kind of OS resource which can be used to synchronise on I/O events. The QUIC implementation provides a B based on the poll descriptor provided by the underlying network BIO. This is typically an OS socket handle, though custom BIOs could choose to implement their own custom poll descriptor format. Broadly, an application which wishes to manage its own event loop should interact with the SSL object as follows: =over 4 =item It should provide read and write BIOs with nonblocking datagram semantics to the SSL object using L and L. This could be a BIO abstracting a network socket such as L, or a BIO abstracting some kind of memory buffer such as L. Use of a custom BIO is also possible. =item It should configure the SSL object into nonblocking mode by calling L. =item It should configure the SSL object as desired, set an initial peer as needed using L, and trigger the connection process by calling L. =item If the network read and write BIOs provided were pollable (for example, a L, or a custom BIO which implements L and L), it should perform the following steps repeatedly: =over 4 =item The application should call L and L to identify OS resources which can be used for synchronisation. =item It should call L and L to determine whether the QUIC implementation is currently interested in readability and writability events on the underlying network BIO which was provided, and call L to determine if any timeout event will become applicable in the future. =item It should wait until one of the following events occurs: =over 4 =item The poll descriptor returned by L becomes readable (if L returned 1); =item The poll descriptor returned by L becomes writable (if L returned 1); =item The timeout returned by L (if any) expires. =back Once any of these events occurs, L should be called. =back =item If the network read and write BIOs provided were not pollable (for example, in the case of L), the application is responsible for managing and synchronising network I/O. It should call L after it writes data to a L or otherwise takes action so that the QUIC implementation can read new datagrams via a call to L on the underlying network BIO. The QUIC implementation may output datagrams via a call to L and the application is responsible for ensuring these are transmitted. The application must call L after every call to L (or another I/O function on the SSL object), and ensure that a call to L is performed after the specified timeout (if any). =back =head1 SEE ALSO L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L, L =head1 COPYRIGHT Copyright 2022-2023 The OpenSSL Project Authors. All Rights Reserved. Licensed under the Apache License 2.0 (the "License"). You may not use this file except in compliance with the License. You can obtain a copy in the file LICENSE in the source distribution or at L. =cut