PROTOCOLS-FUN . DENIAL OF SERVICE

Attack Anatomy: the bytes

Four denial-of-service attacks at the packet level.

A SYN costs the sender 40 bytes and costs the server a half-open connection entry, held until the handshake times out. The table is finite and the traffic volume is small.

the segment, 20 bytes
the flags byte, bit by bit

The TCP flags byte, with only SYN set.

SYN cookies. Instead of allocating on the SYN, the server encodes the connection parameters into the sequence number it sends back and keeps nothing. If an ACK returns, the cookie is decoded and the connection is rebuilt from it. The backlog stops being a resource an attacker can exhaust.
What SYN cookies cost. The sequence number has room for very little, so options negotiated in the original SYN are lost unless the timestamp option can carry them. Window scaling and SACK are the casualties. A connection accepted by cookie can be measurably slower than one accepted normally, which is why cookies are usually armed on backlog pressure rather than left on.
Why the source address is forged. A real source would receive the SYN-ACK and its kernel would answer with a RST, tearing down the half-open entry the attacker just paid for. Spoofing at unallocated address space avoids that. The attack needs the reply to go nowhere.

Reflection, amplification and most volumetric floods depend on spoofed source addresses. IP does not verify the source. Only the network the packet leaves can filter it (BCP 38), and that network gets no direct benefit from doing so.

an IPv4 header with a forged source
Why spoofing persists. Ingress filtering protects everyone except the network that deploys it. An operator who filters spends effort so that somebody else does not get attacked, and sees no benefit on their own traffic. BCP 38 was published in 1998 and remains partially deployed for that reason, not a technical one.
TTL as a signal. Common initial values are 64, 128 and 255. A packet claiming to be from a host two hops away, arriving with a TTL consistent with fifteen, is lying about something. It is weak evidence per packet and useful in aggregate.
Why UDP. Reflection needs a protocol that answers an unverified first packet. TCP will not: its handshake is an address-validation mechanism, whatever else it is for. Every entry in the amplifier tables is UDP, apart from the middlebox case where censorship equipment answers a TCP packet it should have ignored.

Amplification is the ratio of response size to request size. In both protocols here, fields in the request tell the server how much to send, and the attacker writes the request.

the query header, 12 bytes
the OPT record, where the ceiling is set

EDNS0 lifted DNS's 512-byte UDP limit. It is the field that allows large reflected answers.

DNSSEC and response size. A signed zone returns RRSIG records alongside the data, and the DO bit above asks for them. The security extension that authenticates DNS is the same one that made it a better amplifier. Both facts are true and neither argues against deploying it.
NTP monlist, the 8-byte request

A vendor-private NTP command that returns the last 600 clients the server talked to. It was used in the 400 Gbps attack of 2014.

How monlist was fixed. monlist was removed in ntpd 4.2.7p26 rather than filtered or rate limited. The reflector population aged out as operators upgraded. Compare memcached, where providers blocked 11211/udp wholesale, and DNS, where Response Rate Limiting shrank the amplifier pool without removing the feature. Three shapes of the same answer: make the reflector stop being one.

Layer 7 attacks use well-formed requests and put the cost on the origin. The field that matters here is in a control frame, not in the data.

RST_STREAM, the frame behind Rapid Reset
Why the stream limit did not hold. HTTP/2 limits how many streams may be open at once, and that limit is what is supposed to cap concurrent work. Open a stream and reset it immediately and the server starts the work while the stream is already closed, so it never counts. One connection can queue far more work than the limit nominally allows.
Why signatures miss it. Every frame is valid, the error code is a polite CANCEL, and each individual exchange is something a real client does when a user navigates away. The fix was not a signature: it was accounting, tracking the reset ratio per connection and sending GOAWAY when it goes wrong.
Slow attacks. Slowloris and RUDY hold connections open by sending just enough to avoid a timeout, exhausting a worker pool with almost no bandwidth. Rapid Reset exhausts by cycling as fast as possible. Both target the same resource from opposite directions, which is why a read timeout helps against one and rate accounting against the other.

When each technique on the other tabs first appeared. Most follow the same pattern: a protocol reaches a large population of internet-facing hosts, someone finds a response much larger than its request, and the fix is to shrink the exposed population.

denial-of-service/
├─ prehistory
│  ├─ 1974Commonly cited as the first DoS.
│  ├─ 1988Not designed as DoS.
│  ├─ 1995First organised political DoS.
│  └─ Sep 1996The first attack that forced a protocol-level fix.
├─ malformed packets
│  ├─ 1996ICMP echo fragmented so that reassembly exceeds the 65,535-byte IP maximum.
│  ├─ Nov 1997IP fragments with overlapping offsets.
│  ├─ 1997TCP SYN with source address and port identical to destination.
│  ├─ 1997TCP segment with URG flag and out-of-band pointer sent to NetBIOS port 139 Killed by:
│  ├─ 1997-98Teardrop variants.
│  └─ 2000Endless stream of identical fragments, never completing.
├─ the toolkits
│  ├─ Jun 1999First widely deployed DDoS toolkit.
│  ├─ 1999Multi-vector:
│  ├─ Late 1999German for "barbed wire".
│  ├─ Dec 1999Decoy packets, randomised protocols, no acknowledgements from agents.
│  └─ 2000Trinity was IRC-controlled, which became the dominant C2 pattern for the next decade
├─ politics and infrastructure
│  ├─ Oct 2002First strike at the internet's own control plane.
│  ├─ Feb 2007Proof that anycast dispersion works.
│  ├─ Apr-May 2007The first time DDoS was treated as a possible Article 5 matter.
│  ├─ Aug 2008First DDoS synchronised with conventional military operations
│  ├─ Dec 2010Voluntary botnet.
│  └─ 2012-13Compromised web servers, not consumer PCs.
├─ the amplification race
│  ├─ Mar 2013120 Gbps measured.
│  ├─ Feb 2014~400 Gbps.
│  ├─ 2014-15100+ Gbps routine.
│  ├─ 20155 days.
│  └─ Feb 28 20181.35 Tbps, 126.9 Mpps.
└─ iot and the terabit era
   ├─ Sep 20 2016623 Gbps (Akamai's own figure; 620 is Krebs's contemporaneous number).
   ├─ Sep 2016~1.1 Tbps claimed, 145,000 devices
   ├─ Sep 30 2016Every major botnet since is built on this code
   ├─ Oct 21 2016~1.2 Tbps.
   ├─ Feb 20202.3 Tbps
   ├─ Sep 202121.8 Mrps vs Yandex, 17.2 Mrps vs a Cloudflare customer.
   ├─ Oct 2023Google 398 Mrps, Cloudflare 201 Mrps, AWS 155 Mrps.
   ├─ Apr-Oct 20256.5 Tbps (Apr) → 7.3 Tbps (May) → 11.5 Tbps (Sep 1) → 22.2 Tbps / 10.6 Bpps (Sep 22) → 14.1 Bpps (Oct 7) → 29.7 Tbps (Oc
   ├─ Dec 19 202531.4 Tbps sustained for 35 seconds, and 205 Mrps at L7
   └─ H1 2026Terabit attacks are now routine
Which fixes held. monlist was deleted from ntpd, open recursion was turned off by default, providers filtered 11211/udp, and the malformed-packet era ended when the reassembly bugs were patched out of every stack. The fixes that did not hold were the ones that tried to out-spend the attacker.
Mirai. Releasing the source in September 2016 turned a single botnet into a base that everything since has been built on. The device population it targets has only grown, and the 2025 records come from its descendants.