Why was QUIC developed? To make internet traffic faster and more secure.
How does switching from a reliable delivery like TCP to unreliable delivery make it better? With QUIC, although the transport is UDP, loss and congestion are dealt with at the application layer, and encryption is included in the protocol.
Why couldn’t we just improve TCP/HTTP ? TCP is dealt with in the kernel, and making changes to kernel code is slower and more complex (in terms of rolling it out), since QUIC is handled in user space, it can be developed an iterated faster. In addition there are a lot of TCP terminating devices, like firewalls, load balancers etc, that make changing TCP difficult. (ossification)
So What is QUIC? It’s a transport protocol that allows rapid, encrypted connection establishment, avoids head of line blocking, and provides encryption by default (using TLS1.3) QUIC also implements independent data streams at the transport layer, removing the need for things like HTTP/2 streams.
QUIC also separates connections form the underlying transport, making dealing with a change in the client’s IP address much more graceful.
What’s HTTP/3 then – it’s essentially HTTP/2, - a binary transport with header compression and server push but with out streams (as these are supplied by QUIC)
Let’s look at this in a bit more detail
On the left here we have the existing stack, with IP supplying addressing ##, TCP## managing data transport and reliable delivery, ## TLS providing encryption, and HTTP ## managing requests and responses.
Now over here let’s look at the new stack, still with IP ## managing addressing, but UDP is providing transport##, and QUIC ## is managing reliable delivery, encryption(still via TLS) and HTTP/3 ## dealing with requests and responses.
Just a quick comparison of HTTP/1,2, and 3 ##
With HTTP1 we had only 1 request at a time per connection, so browsers would make multiple connections, and there were wacky techniques like domain sharding to improve connections
HTTP/2 give us streams to multiplex multiple requests on the same connection, but as the underlying transport was not streams aware, if there was a network problem, there was still a big impact. In HTTP/3, the streams are handled by the transport, which delivers multiple requests on the same connection, but in a transport aware way (we will look at this in detail next)
## Server push – where content is pushed to the client before it’s requested was implemented in HTTP/2 and remains in HTTP/3
##HTTP/2 and 3 have header compression using HPAC, which is more like a deduplication than compression really
## Finally HTTP/3 keeps the change to a binary transport that was developed for HTTP/2
OKStreams,
In HTTP/2 we could multiplex multiple requests on a single connection, but if we lost a packet ## (very careless) the whole connection stopped,## including al the streams until we could recover that missing packet, because everything needed to be delivered to the server in order.
With Streams in QUIC ## We can still multiplex, but in the event of a packet getting lost ##, only streams in those lost packet are stopped,## and other streams will still deliver content. The timeouts to detect packet loss are and retransmission algorithms are similar to TCP.
OK, Another significant improvement is a low latency connection setup. With quic, there is a single roundtrip## to both establish the connection and exchange encryption keys, ##compared to the three way hand shake## and then TLS session set up in TCP+TLS – this obviously improves the user experience, especially in higher latency environments
Although this is great, it does leave open some DDoS vectors – since UDP packets source IP can be spoofed, we can mount a reflections attack ## where a target device gets flooded with responses it did not initiate##,
Another problem is that the CPU intensive work happens on the server before addresses are validated, ## so the QUIC server might be an easy target.
A solution to this is the QUIC. Retry packet, ## where the server sends the client a response with a token, which they must reply with before the server performs the crypto set up ( the initial parts are still encrypted, but with a well known key) ##
In addition client hello packets need to be a minimum of 1200 bytes##, making a DoS attack harder work.
OK, but most (all?) web clients will connect over TCP ## to a new web service? How do we get them to switch to QUIC?
The answer is the Alt-Svc header, which the server will respond with in the first request## The Alt-scv header will tell the clint that the same service is available over HTTP/3 and can optionally supply a new address and port to use.
## the client then connects back over QUIC (there is also a timeout saying how long this service will be available for.
NGIX acts as a QUIC proxy, creating a multi-stream HTTP/3 connection on the server side ## and using multiple HTTP1.1 connections on the backend. In our lab we will simply be serving content from NGINX, but the principle is the same.
Talk through
Here’s a simple config note the ## http3 listen line and ## the add_header directive – it’s realty as simple as that.
Talk through these directives (briefly)
And again note that $server _protocol is better tan $http3 in practice.