On this page

Protocol Evolution and Compatibility

Once a protocol is deployed, it is hard to change—TCP’s fixed header caused extensions to take ten years, and TLS middleboxes’ buggy behavior toward unknown extensions led to ossification. QUIC has built-in version negotiation and GREASE (random insertion of meaningless extensions) to combat middlebox ossification from the start—this is a required course for all new protocols.

Overview

Protocols are not immutable—once deployed, they are hard to change. The textual flexibility of HTTP/1.1 headers allowed new features (Cache-Control, CORS) to be added painlessly, but TCP’s fixed header made extensions difficult (TCP Fast Open took 10 years to become widespread). QUIC has built-in version negotiation and GREASE (random insertion of meaningless extensions) from the start—to combat protocol ossification caused by middleboxes’ buggy behavior toward unknown fields. All newly designed protocols should implement GREASE and explicit extension points.

Forward vs Backward

Forward compatible (new client, old server):
  Unknown fields: skip (protobuf, TLV)
  Unknown frame type: ignore (HTTP/2)
  → Implementation: "be liberal in what you accept"

Backward compatible (old client, new server):
  Default value filling
  Version negotiation
  Capability bitmaps (TLS cipher suites)

Negotiation and Fallback

Negotiation and Fallback: Three Mechanisms, Who Can Change the Current Connection, Who Can Only Change the Next One

HTTP Upgrade GET / HTTP/1.1 + Upgrade: h2c 101 Switching or ignored

TLS ALPN ClientHello ALPN=[h2, http/1.1] ServerHello ALPN="h2"

HTTP Alt-Svc Alt-Svc: h3=":443" Use HTTP/3 for the next connection (Does not upgrade the current connection)

HTTP Upgrade and TLS ALPN are real-time negotiations within the same connection; Alt-Svc is merely a hint to "switch protocols next time"— it does not upgrade the current connection, which is the difference between "negotiation" and "fallback".

GREASE

Problem: Middleboxes (firewalls, NATs) only recognize byte patterns they know
  → New protocol extension → Dropped (unrecognized) → Protocol cannot evolve

GREASE: Client randomly inserts meaningless extensions/values:
  TLS: Random cipher suites in ClientHello
  HTTP/2: Random SETTINGS parameters
  QUIC: Random transport parameters

Purpose: Middleboxes must correctly handle unknown values (ignore, not reject)
  → Future real extensions will not be blocked by middleboxes

Lessons from QUIC

Lessons from QUIC: Four Old Problems of TCP, Reversed One by One in Design ① Plaintext Headers → Middlebox modification → Ossification QUIC: Flags fully encrypted Middleboxes only see Connection ID ② No Version Negotiation → Slow evolution QUIC: Version in the first packet Server can reject and propose another version ③ 5-tuple Binding → NAT rebinding → Disconnect QUIC: Connection ID Independent of IP / port ④ Extension Detection QUIC: GREASE built-in In every QUIC implementation The common logic of these four lessons: Reverse the designs that caused TCP ossification— plaintext, no negotiation, address binding, and extension detection—in QUIC one by one. This is a required course in "Protocol Evolution".

References

  • GREASE: RFC 8701
  • QUIC Appendix A: RFC 9000 (design rationale)

Keywords: forward compatibility, backward compatibility, GREASE, ossification, QUIC, Alt-Svc