Recently, an internet friend and I were talking about QUIC, Google’s new protocol to replace TCP as an underlying transport for the internet. QUIC itself runs over UDP/80. Given traditional experiences with protocols over UDP, Carrollr protested:

< carrollr> Sargun: How does QUIC avoid a) spoofing of source, b) overloading congested links on the path

It turns out, the latter is still in flux, but Google has taken interesting approach to the earlier problem, and there’s a lot we can learn from it.

On UDP

TCP 3-way Handshake

TCP combats this problem via two mechanisms. First, in order to bring up a TCP connection, one must first have a three-way handshake occur. This mechanism allows for a very low cost way to ensure bidirectional communication over the underlying channel before exchanging potentially large application data. This, introduces another problem, where the server has to store state while it waits for the client to respond to its SYN+ACK. This introduces a new type of attack, called a “SYN Flood” — which we’ve developed defences against via using SYN cookies. SYN cookies are devices to make the first delay stateless, and it enables the server to restore the state it would have stored statefully based upon the response from the SYN+ACK.

QUIC, being designed from the ground-up has taken an alternative approach. But, first a quick background on QUIC. QUIC, rather than traditional TCP, takes something that looks closer to the SCTP approach. Each connection is then multiplexed into a variety of streams, which map to SPDY streams. This enables long-lived state across what would traditionally be multiple transactions going over different TCP connections. In doing this, there can be a slightly higher overhead to connect, but connections are few and far between.

First, QUIC defends against reflection attacks by making it more expensive for the client to initiate a connection. Initial hello packets are padded to the full size of a packet. This is typically somewhere between 1280 bytes (minimum MTU for IPv6), and 1500 bytes (typical MTU for the internet). This approach is incredibly simple, because bandwidth has an inherent cost, and always will. Given this, the invariant that the client hello will always be larger than, or equal to the size of the server response stands. This immediately rules out naive reflection attacks.

On resumption of the connection at a later point, information exchanged in the hello sequence can be used to make a lower cost reconnection. The server doesn’t need to store all of the state, because it can hand it off to the client, after signing it with its private key. In a state where the server is stressed out, either due to high load, or DDoS, it can require the client to regenerate the proof-of-ownership, therefore mitigating DDoS attacks.

Generalized Anti-DDoS

Proof-of-Work

The way these protocols work is that typically, there is some NP-hard problem, like generating a hash that fulfills some criterion such as having a number of leading 0s that can quickly be verified (as NP-hard problem are), yet cannot easily be sped up. In addition, in order to keep up with Moore’s Law, these problem have an adjustable difficulty. As time goes on, these problem become more and more difficult to solve, and therefore negate the speed increase of processors. This is slightly complicated by the massive delta in bandwidth, memory, and compute capability from mobile devices to traditional desktops.

Part of the proof-of-work research has been in problems that are not in fact NP-hard by nature. On example of this is ReCAPTCHA. When ReCAPTCHA was invented, CV systems hadn’t developed to the capability to solve the provided captchas. ReCAPTCHA could then provide a solved captcha that had been obfuscated, with the addition of an actual unsolved captcha. By forcing the user to solve both, and using only half of the information to verify the authenticity of the user, it solved a multi-million human hour problem.

The Future