本页目录

UDP 与 QUIC 传输层

UDP 本身只是一个"带端口号的 IP",QUIC 在它之上用 UDP 封装了一套完整的可靠传输:0-RTT 握手、stream multiplexing 无队头阻塞、连接迁移——TCP 花了 30 年学到的东西,QUIC 一次做对。

概述

UDP 是最简单的传输层协议——8 字节 header,无连接、无重传、无流控。其"简陋"恰恰是优势:DNS 查询(1 个包往返)、实时音视频(丢几帧不影响体验)、VPN(WireGuard)都选择 UDP。QUIC 在 UDP 之上实现了一个完整的现代传输层,将 TCP 的流控/拥塞控制和 TLS 1.3 加密合并到单一协议中,解决了 TCP 的队头阻塞和连接迁移问题。HTTP/3 即运行在 QUIC 上。

UDP

UDP Header (fixed 8 bytes):

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          Source Port          |       Destination Port        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            Length             |           Checksum            |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Length: UDP header + payload 总长度 (最小 8 = header only, 最大 65535)
Checksum: IPv4 可选 (0=no checksum), IPv6 强制 — 覆盖 pseudo-header (src/dst IP +
          protocol + length) + UDP header + payload

UDP 提供"端口 + 长度 + optional checksum"之外什么都不做——无连接、无重传、无流控、无拥塞控制。应用层如果需可靠性,得自己实现。QUIC 正是"应用层自己实现传输层"的案例。

QUIC 传输层

QUIC 不是"UDP + 可靠性包装"——它是在 UDP 之上实现的全新传输层,将 TCP 的流控/拥塞控制 和 TLS 的加密认证合并到了一个协议里。

QUIC Packet 结构

QUIC Long Header (Initial/Handshake/0-RTT packets):

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1|   Type  |     Version (32 bits)                             |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| DCID Len  |  Destination Connection ID (0-20 bytes)          ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SCID Len  |  Source Connection ID (0-20 bytes)               ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

QUIC Short Header (1-RTT data packets):

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|1|S|R|R|R|        Destination Connection ID (...)           ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

Header Form (bit 0): 1=Long, 0=Short
Fixed Bit (bit 1): 始终 1 — 用于 version negotiation 检测 (中间件不能设这个 bit)
Spin Bit (bit 2 in Short): 每个 RTT 翻转 1 次 — 观察者可以测量 RTT
Reserved Bits: 0, 中间件如果改这些 bits → GREASE 检测到 → connection close

QUIC 连接: Connection ID

TCP 连接 = 5-tuple (src_ip, dst_ip, src_port, dst_port)。IP 换了 → 连接断开。

QUIC 连接 = Destination Connection ID + Source Connection ID。端点可以随时换 Connection ID (通过 NEW_CONNECTION_ID frame) → IP/port 完全可变。

Connection Migration:

QUIC 连接迁移:Connection ID 不变,IP 换了连接不断 客户端 · WiFi IP 192.168.1.x · QUIC flow 用 CID_A → CID_B 标识连接 switch to 4G(网络切换) 客户端 · 4G IP 10.10.10.x · 发送 PATH_CHALLENGE(新 IP,同样的 CID_A → CID_B) Server 响应 PATH_RESPONSE 验证新路径可达 → 迁移确认 连接无缝迁移!应用层看不到任何中断—— QUIC 连接靠 Connection ID(非 IP/port)识别,换网不断线。

Stream Multiplexing

一个 QUIC 连接有多个 stream:

Stream ID (62-bit, variable-length encoding):
  Bit 0: 0=client-initiated, 1=server-initiated
  Bit 1: 0=bidi, 1=unidirectional
  Bits 2-61: stream number (0, 1, 4, 8, 12, ... — client starts at 0, server at 1,
             bidi-only: even client, odd server)

每个 stream 独立:
  - 有独立的 flow control (MAX_STREAM_DATA / STREAM_DATA_BLOCKED)
  - Stream 1 丢包 → 只阻塞 Stream 1 的数据, Stream 3 继续交付
  - 解决 TCP 队头阻塞: TCP 中所有 stream 的字节在同一个 byte stream → 一个丢包阻塞所有

连接级 flow control: MAX_DATA / DATA_BLOCKED — 限制所有 stream 的总接收量

0-RTT

首次连接:
  1-RTT: ClientHello → ServerHello → EncryptedExtensions → Finished → (data)

后续连接 (PSK mode):
  Client: 缓存上次的 session ticket (含 PSK + transport parameters + server address)
  0-RTT: ClientHello + PSK + early data — 在收到 ServerHello 之前就开始发数据
  Server: 验证 PSK → 接受 early data → 直接处理

0-RTT 安全风险 — Replay:
  攻击者重放 0-RTT 包 → server 重复处理 → 重复副作用 (如扣款两次)

QUIC 缓解:
  - 应用层: 只允许幂等操作 (GET, HEAD, OPTIONS) 在 0-RTT 中
  - 传输层: server 可以发送 REJECTED 帧 → client 必须重发 0-RTT 数据
  - AEAD limits: 同一个 key 不能用于太多 0-RTT 包 → 限制重放窗口

QUIC Loss Detection

QUIC 的丢包检测比 TCP 更精确:

TCP: 3 duplicate ACKs → retransmit (但对 SACK, 区分 reordering vs loss)

QUIC: 
  - 每个包有独立的 packet number (单调递增, 即使是重发包也用新号)
  - 接收方 ACK frame: 最大收到 + missing ranges → 精确知道哪些包丢了
  - Loss detection:
    1. Time threshold: 超过 kTimeThreshold (9/8) × latest RTT → 丢包
    2. Packet threshold: 超过 kPacketThreshold (3) 个更大的包被 ACK 了 → 丢包

QUIC 应用

HTTP/3: QUIC 的最大用户 (RFC 9114)
DNS/DoQ: DNS over QUIC (RFC 9250) — 0-RTT query
SMB over QUIC: Windows Server 2022
RDP over QUIC: 远程桌面抗丢包

参考

  • RFC: 768, 8999-9002, 9000 Appendix A (design rationale), 9250
  • 实现⁠: quiche (Cloudflare), lsquic (LiteSpeed), quinn (Rust), ngtcp2 (C)
  • LWN: "QUIC and HTTP/3"

Keywords: UDP, QUIC, connection migration, 0-RTT, stream multiplexing, head-of-line blocking, spin bit, GREASE