Summary of blog post

tl;dr A new encrypted-by-default Internet transport protocol built on top of UDP. Goal is to accelerate and secure HTTP traffic. Eventual goal is to replace TCP and TLS on the web.

History

“Google QUIC” (gQUIC) is original protocol deisnged by Google.

After experimentation, adpted by Internet Engineering Task Force (IETF) for standardization as “IETF QUIC” (QUIC).

Built-in security (and performance)

TCP is vulnerable now. QUIC’s radical design goal is a secure-by-default transport protocol. Authentication and encryption are typically handled in high layer protocol (ex. TLS). QUIC provides these in the transport protocol.

QUIC handshake combines TCP handshake with TLC 1.3 handshake — provides authentication of endpoints and negotiation of cryptographic parameters. Connection is always authenticated and encrypted. Initial connection establishment is faster as a result: typical QUIC handshake takes single round-trip, compared to two for TCP + TLS.

QUIC encrypts additional medadata that could be abused by middle-boxes. Ex. encrypting packet numbers ensures they can’t be used to correlate activity other than endpoints in connection.

Head-of-line blocking

New connections means repeating initial handshakes multiple times.

Big improvement in HTTP/2: ability to multiplex different HTTP requests onto same TCP connection – apps can process requests concurrently and better utilize network bandwidth. Downside: all requests in a connection are equally affected by packet loss, called “head-of-line blocking”.

QUIC provides first class multiplexing support so different HTTP streams can be mapped to different QUIC transport streams, but share the same QUIC connection so no additional handshakes required. Solves head-of-line blocking in most cases.

Decreases time to render complete webpages especially in congested networks.

Not so easy

QUIC needs to break some of the assumptions that were taken for granted by many network apps.

Designed to be delivered on top of UDP datagrams to ease deployment and avoid network appliance dropping packets from unknown protocols (UDP mostly supported). QUIC implementations can live in user-space: browsers able to implement new protocol features without waiting for OS updates.

Intended goal: avoid breakage. But this makes preventing abuse and correctly routing packets to correct endpoints more challenging.

One NAT to bring them all and in the darkness bind them

Typical NAT router tracks TCP connections using 4 tuple (source IP/port, destination IP/port). By observing TCP SYN, ACK, and FIN packets, can detect when connections are established and terminated. Precisely manages lifetime of NAT bindings, the association between internal and external IP/port.

Currently not possible with QUIC, since NAT routers don’t understand QUIC. Typical handling of UDP flows is less precise and uses arbitrary (short) timeouts which can affect long-running connections.

In NAT rebinding (due to timeout), endpoint outside of NAT perimeter sees packets from a different source port than when the connection was established, so it’s impossible to track connections only using the 4-tuple.

One intended QUIC feature is “connection migration”. QUIC endpoints can migrate connections to different IP address and network paths. Ex. mobile client migrates QUIC connection between cellular data and wifi.

Done by introducing concept of connection ID: arbitrary blob of variable length carried by QUIC packets. Endpoints use this to track connections without 4-tuple.

This poses a problem for anycast addressing and ECMP (equal cost multi path) routing since single destination IP can identify hundreds of servers. Edge routers can’t handle QUIC, so UDP packets of same QUIC connection but with different 4-tuple can be routed to different servers.

Smart layer 4 load balancer in software (ex. katran).

QPACK

HTTP/2 introduced header compression (HPACK) which employs dynamic tables of headers from previous HTTP traffic. Endpoints can refer to previous headers in new requests. HPACK dynamic tables must be sync’d between sender/encoder and receiver/decoder. Synchronization is transparent in HTTP/2 over TCP since TCP guarantees HTTP requests are received in correct order.

QUIC has no order guarantees across multiple streams. gQUIC solved this by serializing HTTP headers (but not bodies). Allows implementation to reuse a lot of HTTP/2 code, but it increases the head-of-line blocking QUIC was meant to reduce. IETF QUIC designed new mapping between HTTP and QUIC (“HTTP/QUIC”) and new header compression QPACK.

In newest spec, each HTTP request/response exchange uses its own bidirectional QUIC stream, so no head-of-line blocking. Each peer creates two additional unidirectional QUIC streams – one to send QPACK table updates, one to acknowledge updates received by the other side.

Detecting Reflection

UDP-based protocols are susceptible to reflection attacks – attacker tricks server into sending large amounts of data to a third-party victim by spoofing source IP of packets targeted to the server to look like they came from the victim. Effective when response sent by server is larger than the request received (amplification).

TCP is safe since initial handshake packets have same length, so no amplification potential.

QUIC handshake is asymmetrical. QUIC server sends its own certificate chain (large), while client only sends a few bytes. Initial QUIC packet sent by client has to be padded to a minimum length, but typical server response spans multiple packets – much larger than padded client packet.

QUIC defines explicit source-address verification. The server sends a small “retry” packet with a unique cryptographic token instead of its long response. The server has a higher confidence the client is not spoofing its own IP address (since it received the retry packet) and can complete the handshake. However this increases initial handshake to two round-trips.

Alternatively, can reduce server’s response so a reflection attack is less effective. Can also compress TLS certificates.

UDP performance

Recurring issue with QUIC is that current hardware/software won’t understand it. A lot of work has gone into optimizing TCP like building off-loading capabilities. None of that is available for UDP.

Recent effort to implement Generic Segmentation Offloading for UDP on Linux would allow apps to bundle and transfer multiple UDP segments between user and kernel-space network stack at the cost of one. Another effort to add zerocopy socket support also on Linux allows apps to avoid cost of copying user-space memory to kernel-space.

Conclusion

QUIC set to deliver more secure and performant websites. IETF is set to deliver first version of the QUIC spec by the end of year.