OSSL-GUIDE-QUIC-INTRODUCTION(7ossl)

πŸ’… ossl-guide-quic-introduction β€” the OpenSSL Guide, QUIC intro edition πŸ¦‹

okay so this is ossl-guide-quic-introduction, page 7ossl, bestie. it's literally the beginner-friendly intro to QUIC vibes inside OpenSSL, and it ate. ✨


🌸 INTRODUCTION 🌸

So like, this page gives you the whole intro to basic QUIC concepts and background, plus how QUIC is used inside OpenSSL. it does assume a couple things about you though, no cap: you've gotta have a basic understanding of UDP/IP and sockets, and you should already be familiar with some OpenSSL and TLS fundamentals β€” go peek at ossl-guide-libraries-introduction(7) and ossl-guide-tls-introduction(7) first if you need the lore. 🫢


πŸ”₯ WHAT IS QUIC? πŸ”₯

QUIC is a general purpose protocol that lets applications securely communicate over a network. it's defined in RFC9000 (like, <https://datatracker.ietf.org/doc/rfc9000/> if you wanna read the source material πŸ’€). QUIC integrates parts of the TLS protocol for connection establishment, but it independently protects packets. it gives you similar security guarantees to TLS β€” confidentiality, integrity and authentication β€” see ossl-guide-tls-introduction(7).

QUIC delivers a number of advantages, and honestly? iconic behavior:

  • Multiple streams β€” it supports multiple streams of communication (see "QUIC STREAMS" below), which lets application protocols built on QUIC create arbitrarily many bytestreams for communication between a client and server. this lets an application protocol dodge the whole problem where one packet of data is held up waiting on another packet being delivered β€” commonly referred to as "head-of-line blocking", and yeah that name is as cursed as it sounds 😭. it also means an application can open additional logical streams without needing a round-trip exchange of packets between the client and server, which is what you'd need when opening an additional TLS/TCP connection. slay.
  • HTTP/3 β€” since QUIC is the basis of HTTP/3, supporting QUIC also enables applications to use HTTP/3 using a suitable third-party library. πŸ‘‘
  • Fast connection initiation β€” future versions of OpenSSL will offer support for 0-RTT connection initiation, allowing a connection to be initiated to a server and application data to be transmitted without any waiting time. this is similar to TLS 1.3's 0-RTT functionality, but it also avoids the round trip needed to open a TCP socket β€” so it's giving a combination of TLS 1.3 0-RTT and TCP Fast Open. ⚑
  • Connection migration β€” future versions of OpenSSL will offer support for connection migration, allowing connections to seamlessly survive IP address changes. main character energy fr fr.
  • Datagram based use cases β€” future versions of OpenSSL will offer support for the QUIC datagram extension, allowing support for both TLS and DTLS-style use cases on a single connection. two vibes, one connection. 🌈
  • Implemented as application library β€” because most QUIC implementations, including OpenSSL's implementation, are implemented as an application library rather than by an operating system, an application can gain the benefit of QUIC without needing to wait for an OS update to be deployed. future evolutions and enhancements to the QUIC protocol can be delivered as quickly as an application can be updated, with no dependency on an OS update cadence. literally the dream. πŸ’–
  • Multiplexing over a single UDP socket β€” because QUIC is UDP-based, it's possible to multiplex a QUIC connection on the same UDP socket as some other UDP-based protocols, such as RTP. sharing is caring bestie. πŸŽ€

⏰ QUIC TIME BASED EVENTS ⏰

A key difference between the TLS implementation and the QUIC implementation in OpenSSL is how time is handled. The QUIC protocol requires various actions to be performed on a regular basis regardless of whether application data is being transmitted or received. yes, it's needy, but it's worth it. πŸ™ˆ

OpenSSL introduces a new function SSL_handle_events(3) that will automatically process any outstanding time based events that must be handled. Alternatively, calling any I/O function such as SSL_read_ex(3) or SSL_write_ex(3) will also process these events. There's also SSL_get_event_timeout(3) which tells an application the amount of time that remains until SSL_handle_events(3) (or any I/O function) must be called. clock is ticking, bestie ⏳

Fortunately, a blocking application that does not leave the QUIC connection idle, and is regularly calling I/O functions, does not typically need to worry about this. However, if you are developing a nonblocking application or one that may leave the QUIC connection idle for a period of time, then you will need to arrange to call these functions. no skipping! 🚨

OpenSSL provides an optional "thread assisted mode" that will automatically create a background thread and will regularly call SSL_handle_events(3) in a thread safe manner. This provides a simple way for an application to satisfy the QUIC requirements for time based events without having to implement special logic to accomplish it. it's giving "we hired someone to do it for you" and honestly? obsessed. πŸ’…


🀝 QUIC AND TLS 🀝

QUIC reuses parts of the TLS protocol in its implementation. Specifically, the TLS handshake also exists in QUIC. The TLS handshake messages are wrapped up in QUIC protocol messages in order to send them to the peer. Once the TLS handshake is complete, all application data is sent entirely using QUIC protocol messages without using TLS β€” although some TLS handshake messages may still be sent in some circumstances. (yeah, they still text sometimes πŸ’€)

This relationship between QUIC and TLS means that many of the API functions in OpenSSL that apply to TLS connections also apply to QUIC connections, and applications can use them in exactly the same way. Some functions do not apply to QUIC at all, and others have altered semantics. You should refer to the documentation pages for each function for information on how it applies to QUIC. Typically, if QUIC is not mentioned in the manual pages, then the functions apply to both TLS and QUIC. so check the docs before you assume, iykyk. πŸ”


🌊 QUIC STREAMS 🌊

QUIC introduces the concept of "streams". A stream provides a reliable mechanism for sending and receiving application data between the endpoints. The bytes transmitted are guaranteed to be received in the same order they were sent, without any loss of data or reordering of the bytes. no chaos, no shuffle, just vibes in order. ✨

A TLS application effectively has one bi-directional stream available to it per TLS connection. A QUIC application can have multiple uni-directional or bi-directional streams available to it for each connection. glow up tbh.

In OpenSSL, an SSL object is used to represent both connections and streams. A QUIC application creates an initial SSL object to represent the connection (known as the connection SSL object). Once the connection is complete, additional SSL objects can be created to represent streams (known as stream SSL objects). Unless configured otherwise, a "default" stream is also associated with the connection SSL object, so you can still write data and read data to/from it. Some OpenSSL API functions can only be used with connection SSL objects, and some can only be used with stream SSL objects. Check the documentation for each function to confirm what type of SSL object can be used in any particular context. A connection SSL object that has a default stream attached to it can be used in contexts that require a connection SSL object or in contexts that require a stream SSL object. versatile queen πŸ‘‘


πŸ”Œ SOCKETS AND BLOCKING πŸ”Œ

TLS assumes "stream" type semantics for its underlying transport layer protocol (usually achieved by using TCP). However, QUIC assumes "datagram" type semantics by using UDP. An OpenSSL application using QUIC is responsible for creating a BIO to represent the underlying transport layer. This BIO must support datagrams and is typically BIO_s_datagram(3), but other BIO choices are available. See bio(7) for an introduction to OpenSSL's BIO concept. 🧚

A significant difference between OpenSSL TLS applications and OpenSSL QUIC applications is the way that blocking is implemented. In TLS, if your application expects blocking behaviour, then you configure the underlying socket for blocking. Conversely, if your application wants nonblocking behaviour, then the underlying socket is configured to be nonblocking. simple, right?

With an OpenSSL QUIC application, the underlying socket must always be configured to be nonblocking. However, the SSL object will, by default, still operate in blocking mode. So, from an application's perspective, calls to functions such as SSL_read_ex(3), SSL_write_ex(3) and other I/O functions will still block. OpenSSL itself provides that blocking capability for QUIC instead of the socket. If nonblocking behaviour is desired, then the application must call SSL_set_blocking_mode(3).

⚠️ bestie this is the one to tattoo on your brain: socket = always nonblocking for QUIC. the blocking illusion comes from the SSL object, not the socket. don't fight it, just call SSL_set_blocking_mode(3) if you want nonblocking. πŸ’€

πŸ“š FURTHER READING πŸ“š


πŸ‘€ SEE ALSO πŸ‘€

ossl-guide-introduction(7), ossl-guide-libraries-introduction(7), ossl-guide-libssl-introduction(7), ossl-guide-tls-introduction(7), ossl-guide-tls-client-block(7), ossl-guide-quic-client-block(7), ossl-guide-quic-client-non-block(7), ossl-guide-quic-multi-stream(7), ossl-guide-quic-server-block(7), ossl-guide-quic-server-non-block(7), bio(7)


Copyright 2023-2025 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 <https://www.openssl.org/source/license.html>.


that's the whole page bestie, go build something iconic πŸ’–βœ¨ and yeah β€” this was version 3.5.9, dated 2026-09-2, brought to you by the OpenSSL gang. mwah πŸŽ€πŸ¦‹πŸ’œ

πŸ“¦ where this page comes from