Here is a screenshot of Medium homepage requests. Most of them are through the HTTP/3 protocol noting as h3-29
.
The h3
stands for HTTP/3, and the 29
is the implemented draft's version.
Though the latest draft is version 34, all known teams choose version 29 as it was a significant update. The differences in later versions are minimal.
Why we need HTTP/3? An important reason is solving the head-of-line blocking issue.
Head-of-Line Blocking on HTTP/2
HTTP/2 resolves the head-of-line issue on the HTTP-level with frames and streams. However, the problem remains at the TCP level.
After receiving frames from its upper level, TCP breaks them down into segments.
If everything goes well, all segments will arrive at the other end.
However, the internet could be unstable. Some segments could be lost during the process.
TCP has a feature to guarantee delivery. It puts received segments in a buffer and waits for the lost segments’ retransmission, leading to the head-of-line blocking.
To resolve the issue, we need to find a replacement for TCP — QUIC, and UDP.
An Updated Protocol Stack
We see a significant change from the protocol stack: TCP is replaced by UDP.
Different from TCP, UDP does not guarantee delivery and no dependencies among segments. It means no more head-of-line blocking.
Besides, since UDP is a connectionless protocol, no handshakes are required. It runs faster than TCP.
On top of the UDP, a new protocol, QUIC, is introduced. It inherits good parts of TCP, including connection management and flow control. Also, QUIC implements features to guarantee data delivery to make up for the shortcoming of UDP.
Another change is that TLS is implemented inside of QUIC, and all its security features are inherited simultaneously. Since TLS 1.3 is production-ready, QUIC starts with this version.
Last but not least, QPACK replaces HPACK, further improve the performance of the header compression algorithm. Its entries in the static table are increased from 61 to 98, and it is now 0-indexed.
QUIC Packets, Frames, and Stream
QUICK is made of packets and frames. A packet composes of multiple frames.
Here is the structure of a QUIC packet.
In the packet header, QUIC uses connection IDs to mark its destination and source.
The browser and the server can choose their IDs. With them, we decouple the connection from IP and port, achieving a smooth connection migration.
The following story may happen to you every day.
When you leave home, your mobile switches from WiFi to 4G (soon 5G). Since the IP changes, TCP reconnects. You will lose connection for a moment before reconnecting to the internet.
With QUIC, the connection IDs remain the same, so the connection remains conceptually. Though IP changes, the connection is reused — no reconnection cost.
Let’s take a look at a QUIC Packet example.
QUIC IETF
QUIC Connection information
[Packet Length: 1350]
1... .... = Header Form: Long Header (1)
.1.. .... = Fixed Bit: True
..00 .... = Packet Type: Initial (0)
.... 00.. = Reserved: 0
.... ..00 = Packet Number Length: 1 bytes (0)
Version: draft-29 (0xff00001d)
Destination Connection ID Length: 8
Destination Connection ID: 45fb5955dfaa8914
Source Connection ID Length: 0
Token Length: 0
Length: 1332
Packet Number: 1
Payload: 5a99e5b29413627619ca3b5add4cf8b6ce348355b1c1a2be9874c7961e7996a24aeec860…
TLSv1.3 Record Layer: Handshake Protocol: Client Hello
PADDING Length: 997
From the public flags 1100 0000
, we can tell it is a Long Header, and its type is Initial. Following is the QUIC version: draft-29, succeeded by the Destination Connection ID and its length.
Next, let’s take a look at the QUICK Frame structure.
Similar to the HTTP/2 frame, there are various frame types in QUIC.
For example, the STREAM
frame is for carrying streams, and the ACK
frame is for control.
Fields in the header use variable length coding up to 8 bytes.
Stream Identifier could reach 2⁶² with two bits are reserved as markers.
- Its least significant bit marks the sender: 0 means client, and 1 means server.
- Its 2nd least significant bit marks the stream’s direction: 0 means two-way stream, and 1 means one-way stream.
Here is an example of the frame.
TLSv1.3 Record Layer: Handshake Protocol: Client Hello
Frame Type: CRYPTO (0x0000000000000006)
Offset: 0
Length: 314
Crypto Data
Handshake Protocol: Client Hello
The Frame Type is CRYPTO
, a type designed for the handshake, and the payload is crypto data.
Here is another example of the Server Hello.
TLSv1.3 Record Layer: Handshake Protocol: Server Hello
Frame Type: CRYPTO (0x0000000000000006)
Offset: 0
Length: 90
Crypto Data
Handshake Protocol: Server Hello
Handshake Type: Server Hello (2)
Length: 86
Version: TLS 1.2 (0x0303)
Random: 0f58bdbd934450c7aa98242121447bef2fe0733aa5fc3beffab6513c7177f9a4
Session ID Length: 0
Cipher Suite: TLS_AES_128_GCM_SHA256 (0x1301)
Compression Method: null (0)
Extensions Length: 46
Extension: key_share (len=36)
Extension: supported_versions (len=2)
Except for the new fields from the QUIC frame, the rest are mentioned in the TLS 1.3 handshake.
HTTP/3 Protocol and Frame
QUIC can do so much. It lightens the HTTP/3 workload.
For example, unlike HTTP/2, HTTP/3 takes advantage of the QUIC streams instead of defining and controlling streams itself.
Most of the frame types managed in HTTP/2 are moved to QUIC, such as the RST_STREAM
frame and the WINDOW_UPDATE
frame.
Thanks to it, the HTTP/3 frame structure is simplified to merely 2 fields — Frame Type and Length.
There is one thing worth mentioning. HTTP/3 doesn’t have a designated port as 443 for HTTPS.
A browser first connects the server with HTTP/2 To discover the service. The server responses with an Alt-Svc
header, including the port for HTTP/3, such as Alt-Svc: h3-29=":443"
. With it, the browser uses QUIC asynchronously links to the port. Once the connection is created, HTTP/3 will be used for future communication.
Join Medium
Purchasing Medium Membership through the above link means that I can get income through the referral link. This does not mean that you have to buy from the link, nor does I deny or oppose other channels. It is your right to know.
References
- The latest version 34 draft: https://tools.ietf.org/html/draft-ietf-quic-http-34
- Wanna try HTTP/3? Here is a demo site from NGINX: https://quic.nginx.org/. The latest Chrome and Canary browsers support QUIC.