HTTP/3 is the third official version of the popular hypertext transfer protocol used to exchange binary information on the World Wide Web. The most notable HTTP/3 enhancements come from QUIC, a new network layer protocol developed by Google.
On 28 October 2018, Mark Nottingham, Chair of the HTTP and QUIC Working Groups of the IETF, made the official request to rename HTTP-over-QUIC as HTTP/3 and in the next discussions that followed and lasted for several days, Nottingham’s proposal was accepted by other IETF members, who in November 2018 gave their official seal of approval for HTTP-over-QUIC to become HTTP/3.
Introduction to QUIC
QUIC (Quick UDP Internet Connection) supports a set of multiplexed connections over UDP and has been designed to provide equivalent security to TLS/SSL by reducing latency in both connection and data transport.
QUIC solves some of the problems detected in TCP. For example, TCP examines each packet in a single data flow and instead, QUIC uses the concept of streams, originally used in protocols such as HTTP/2 and SCTP. When each resource is assigned an individual conceptual flow, the transport layer may know that when a packet is lost, subsequent packets can still be used if they contain data from another resource that was not in the lost packet. Another example of problems that QUIC solves is the slow establishment of the TLS/SSL connection, which requires several information exchanges (round trip times, RTTs), while QUIC reduces this connection cost to practically zero RTTs.
The improvement in QUIC’s handshake is based, among others, on a change in the way connections are identified. TCP, during the negotiation process, uses a tuple of 4 elements that contain the IP’s and the ports used in the connection. A common problem for TCP is that the connection does not survive when any of the IPs or ports of the endpoints change (for example, when the client changes from 4G to WiFi). When this happens, the packets cannot be identified by the other endpoint and the connection is terminated when a timeout is reached. If the connection is still desired by either endpoint, the negotiation process must be started again, which leads to an increase in traffic load.
QUIC solves this problem by using a unique and independent identifier for each end of the connection. This connection ID has a size between four and eighteen bytes, which is created specifically for each endpoint implementation, ensuring that the endpoint can identify its own ID in a QUIC packet, as the destination connection ID is present in each packet. The fact that this ID is dynamic makes it possible to reduce packet overload when using QUIC for simpler configurations (e.g., P2P) by using a small connection ID. However, in more complex situations (e.g. load balancing) it is possible to store additional information in the connection ID.
The handshake of QUIC starts when a client sends a “Hello” to the server, which is an initial packet containing the connection identifiers and the version of QUIC with which the client wishes to initiate that connection. In the payload of the packet are the data that are used by TLS to negotiate the set of encryption and other secrets. This payload is encrypted using the default encryption algorithm of the version of QUIC used. All packets, except version negotiation and stateless restoration, are encrypted using an authentication with associated data encryption algorithm (AEAD). As for the keys of this encryption algorithm, the version, the connection ID, the packet number, and the entire header are used to generate them.
Then, when the server receives the “Hello” packet from the client, it first checks the version used in the packet header. The version field is one of the fixed fields of the headers in QUIC, so it will be present in the headers of all versions of QUIC. If the given version is not in its own list of supported versions, the server creates a version negotiation package and sends it to the client. If the version is compatible, the server responds to the package with a negotiation package, which is used to send data related to the handshake, which contains the “Hello”. When receiving the “Hello” from the client and generating the “Hello” back, the server has finished the negotiation.
However, the client still needs to finish this process by receiving the “Hello” message from the server. When the client receives this negotiation packet, the handshake is completed on the client and can derive keys from its TLS stack to protect the payload of all transmitted packets. Packages that are encrypted with these new keys are called protected 1-RTT packets.
The client still needs to tell the server that it has finished the handshake. This data, from your TLS stack, is sent with a negotiation packet. All data after this packet is sent with a protected 1-RTT packet. After receiving the last handshake packet from the client, the server knows that the client has finished the negotiation. The server can also send a session ticket to the client to make it possible to resume the session at the next connection to be made.
QUIC provides a way for connections to start exchanging data without waiting for a single RTT for the handshake (0-RTT). This is possible when the client initiates a connection to a server with which it has already contacted previously, so the connection is initiated with additional information from the session of the previous connection. Using this information, it is possible to export encryption keys that can be used to encrypt the payload. The server that receives this payload can export the same encryption keys from the session information provided in the client’s “Hello” package. The server can then decrypt the payload using the first data keys.
This mechanism is possible because QUIC uses TLS/1.3 for data encryption.
Since Chrome 29 and Opera 16, support for QUIC is already implemented, which means that these two web browsers are ready for the transition.
By this, I don’t mean that QUIC will be a success from the beginning and immediately win a big part of the cake, but my opinion is that the deployment quota will grow slowly, although I hope it will be faster than with IPv6 🙂