QUIC Streams and Toolchain¶
QUIC runs over UDP, but gives your application reliable, ordered streams rather than raw datagrams. Before sending anything, check that your Raspberry Pi can build both sides of the upcoming QUIC exercises.
Outcome: Build a C++ probe that constructs QUIC client and listener objects, reports the headers and loaded OpenSSL library, and explicitly does not claim HTTP/3 support.
Before you start¶
- Complete verified TLS and review TCP message boundaries.
- Use Linux, a C++20 compiler, CMake 3.28 or newer, and OpenSSL 3.5 or newer development files with QUIC enabled. The client API appeared earlier, but this chapter also builds a server.
- No extra hardware, router changes, public server or administrator access is needed for the probe itself. Installing missing system development packages may need an administrator.
Standalone example on GitHub · OpenSSL QUIC methods
QUIC is not just encrypted UDP¶
| Interface | What you must distinguish |
|---|---|
| UDP socket | Datagram boundaries, missing messages, duplicates and reordering |
| QUIC stream | Ordered bytes within that stream, application framing, FIN or reset |
| HTTP/3 library | HTTP fields, request streams, response status and body completion |
QUIC handles loss recovery and ordering within each stream. It does not preserve the boundaries of your SSL_write_ex() calls. A single read can contain part of a write or bytes from several writes, just as with the TCP exercise.
Different streams have separate ordering. Waiting for missing bytes on stream A does not itself require withholding ready bytes on stream B. They still share a connection, congestion control, network capacity and connection-level flow control: this is not a promise that streams never affect each other.
QUIC uses the TLS 1.3 handshake to establish keys and authenticate the server, but does not put ordinary TLS records around application data. It protects QUIC packets. DTLS is a different protocol, not the encryption layer for QUIC. See QUIC transport and TLS in QUIC.
Check the development toolchain, not only the commands¶
These describe those particular command-line programs. Neither proves which headers CMake will find or which libssl your C++ program will load.
Likewise, look for HTTP3 in curl's feature list, not just an OpenSSL or HTTP2 entry. QUIC support in OpenSSL does not provide HTTP/3 framing, control streams or QPACK. The later HTTP/3 lesson checks that separate layer.
On the course's Pi 4B, the inspected runtime was OpenSSL 3.5.7; the host runtime was 3.5.5. Those are verification records, not required patch versions or a recommendation to downgrade. Use maintained packages for your OS.
If development files are absent on Raspberry Pi OS, check the candidate before installing:
The candidate must meet the 3.5 requirement for this chapter. An older OS can legitimately offer an older OpenSSL. Do not replace its system libraries by hand or mix headers and libraries from unrelated releases. The prior TLS/DTLS examples remain available without enabling this optional chapter.
Build and run the QUIC probe¶
From the examples checkout:
The chapter is opt-in. Leaving NETWORK_BUILD_QUIC off keeps the earlier lessons' OpenSSL 3.0 minimum; turning it on checks for 3.5 development files.
The virtual environment supplies the independent peer for this chapter's later
communication tests; the probe itself does not use it. For a probe-only build
without Python test dependencies, configure with -DBUILD_TESTING=OFF and omit
the ctest command. CMake never downloads packages or silently skips a missing
independent peer.
Example output on the Pi used for verification:
The version/date lines can differ. The last four lines are the important outcome. This is object construction only: no socket, certificate, handshake, stream data or HTTP exchange has been tested yet.
Read the probe¶
The client uses SSL_new() with OSSL_QUIC_client_method(). The server uses SSL_new_listener() with OSSL_QUIC_server_method(): a listener is not a data stream or an accepted connection. Both objects enter nonblocking mode, which the following exercises need to enforce deadlines.
Each successful allocation is freed explicitly, including partial setup failures. The compile-time checks detect old or QUIC-disabled headers; the runtime check and actual object construction catch additional configuration problems. If the loader cannot resolve a required symbol, it can fail before main(): the version printout is not a substitute for a consistent installation.
Full standalone probe: app/quic-tools/main.cpp
If it does not work¶
| Symptom | Next check |
|---|---|
| CMake reports an unsuitable OpenSSL version | Confirm the development package candidate, not only openssl version |
openssl/quic.h or the server method is missing |
Check the compiler include path and the 3.5 minimum |
| Linker reports an undefined QUIC symbol | Inspect CMake's selected SSL/Crypto libraries and remove unintended custom search paths |
| Dynamic loader reports a missing symbol | Check ldd ./build/native/debug/quic_tools for a conflicting runtime installation |
| Objects are ready but curl lacks HTTP3 | Expected: transport support and HTTP/3 support are separate |
When correcting a cached library selection, configure a new build directory or deliberately update the relevant CMake cache entries. Do not delete unrelated build trees or alter the system library search path to suppress an error.
Check your understanding¶
- If QUIC uses UDP, must your application retry each missing stream byte?
- Can one successful write be assumed to produce one matching read?
- Why does a ready QUIC listener not prove HTTP/3 support?
Answers
- No. QUIC's transport handles stream delivery and loss recovery, subject to failure and timeout. Your application still needs meaningful completion/error handling.
- No. Stream bytes need application framing. A FIN marks the end of one sending direction, not every individual message.
- HTTP/3 is a separate application protocol with HTTP frames and QPACK. This probe constructs transport objects without exchanging packets.
Continue the course¶
Continue with Your First Verified QUIC Stream, using a custom application protocol, not HTTP/3. Return to the course overview for the full path.