• 忘掉天地
  • 仿佛也想不起自己
bingliaolongBingliaolong  2025-03-24 00:39 Aet 隐藏边栏 |   抢沙发  4 
文章评分 2 次,平均分 5.0

概述

  1. QUICQuick UDP Internet Connections)是一种基于 UDP 的传输层协议,由 Google2012 年提出,旨在解决 TCPTLS 的性能瓶颈,提供更快的连接建立、更低的延迟和更强的可靠性
  2. 2018 年,QUIC 被标准化为 IETF QUICRFC 9000),并成为 HTTP/3 的底层协议

设计目标

  1. 减少延迟:消除 TCP 的三次握手和 TLS 的额外往返时间(RTT
  2. 避免队头阻塞(Head-of-Line Blocking):通过多路复用独立的数据流
  3. 连接迁移:在网络切换(如 Wi-Fi4G)时保持连接
  4. 改进拥塞控制:灵活支持多种算法(如 BBRCUBIC
  5. 默认加密:所有数据均加密传输,整合 TLS 1.3

QUIC 的核心特性

基于 UDP

  1. 绕过操作系统和中间设备对 TCP 的优化限制,直接在 UDP 上实现可靠传输
  2. 避免 TCP 的队头阻塞问题(TCP 将数据视为单一有序流)

多路复用(Multiplexing

  1. 在单个连接上并行传输多个独立的流(Stream),每个流的数据包丢失不会阻塞其他流
  2. 例如:网页加载时,图片、CSSJavaScript 可以并行传输

0-RTT1-RTT 连接建立

  1. 1-RTT 连接:
    1. 首次连接时,客户端和服务端通过一次往返完成密钥协商(TLS 1.3
  2. 0-RTT 连接:
    1. 后续连接时,客户端可直接发送加密数据,无需握手(类似 TCP Fast Open

连接迁移

  1. 使用连接 IDConnection ID)标识连接,而非传统的 IP + 端口。
  2. 即使设备切换网络,连接仍可保持

前向纠错(FEC

  1. 发送冗余数据包(如 XOR 编码),在部分丢包时无需重传即可恢复数据(可选功能)

灵活的拥塞控制

  1. 默认使用 CUBICBBR 算法,并允许动态调整策略

QUIC 协议结构

概述

  1. QUIC 数据包分为两个层次:
    1. QUIC 数据包(Packet):包含头部和负载
    2. QUIC 帧(Frame):负载中的最小数据单元,承载实际信息

数据包头部

  1. 长头部:用于初始握手,包含版本、连接 ID 等信息
  2. 短头部:用于已建立的连接,仅包含连接 ID 和包号

帧类型

  1. STREAM:传输流数据

  1. ACK:确认接收到的包

  1. CRYPTO:传输 TLS 握手数据
  2. CONNECTION_CLOSE:关闭连接

  1. 单向或双向,支持优先级设置
  2. 每个流独立处理,保证数据有序性和可靠性

QUIC协议核心机制拆解

QUIC协议连接过程

首次连接

  1. Client Hello:客户端生成临时密钥(Ephemeral Key),发送 Client Hello(包含支持的 TLS 版本、密钥参数等)
  2. Server Hello:服务端生成密钥,返回 Server Hello、证书和加密的 Finished 消息
  3. 密钥计算:双方通过 HKDF 算法生成会话密钥,后续通信加密
  4. QUIC 细节:所有握手消息通过 CRYPTO 帧传输,而非传统的 TLS Record

0-RTT连接

  1. Session Resumption:客户端使用之前缓存的会话密钥(PSK)直接发送加密数据
  2. 防重放攻击:服务端通过限制 0-RTT 数据的有效期和一次性令牌(Token)防御重放

关键问题

  1. 如何保证 0-RTT 安全性?
    1. 服务端需验证客户端 Token 的有效性,且 0-RTT 数据不应用于敏感操作(如支付)

流(Stream)与多路复用

流类型

  1. 单向流(Unidirectional):客户端到服务端或反之,用于推送数据
  2. 双向流(Bidirectional):两端可同时读写,用于请求-响应模式

流标识符

  1. 编码为 62 位整数,支持超过 4 亿个并发流
  2. 奇偶性规则:客户端发起的流 ID 为偶数,服务端为奇数,避免冲突

流控制

  1. 流量窗口(Flow Control):每个流独立控制接收窗口(类似 HTTP/2
  2. 动态调整:通过 MAX_STREAM_DATA 帧通知对端窗口大小

队头阻塞的彻底解决

  1. 流间独立:每个流的数据包独立传输和重传
  2. 示例:流 1 的数据包丢失不会阻塞流 2 的数据处理

可靠传输与丢包恢复

包编号(Packet Number

  1. 每个 QUIC 包有独立的递增编号,不因网络路径变化重置
  2. 加密保护:包号在加密后被隐藏,防止中间设备篡改

确认机制(ACK Frames

  1. 显式确认:接收方通过 ACK 帧告知已接收的包范围
  2. 延迟确认:允许接收方批量确认多个包,减少开销

快速重传(Fast Retransmit

  1. 基于包号的空洞检测:若发现包号不连续,立即触发重传
  2. 示例:若包 345 中丢失了包 4,接收方会在收到包 5 时触发重传请求

连接迁移与 NAT 穿透

连接 IDConnection ID

  1. 由服务端分配,用于唯一标识连接(替代传统 TCP4 元组)
  2. 动态更新:支持在连接过程中切换 Connection ID 以增强隐私

NET穿透

  1. Keep-Alive 机制:定期发送探测包维持 NAT 映射表
  2. 端口跳跃(Port Hopping):通过 Connection ID 保持连接,即使客户端 IP 或端口变化

QUIC 安全性

  1. 默认加密:所有头部和负载均加密(除少量公共字段)
  2. TLS 1.3 整合:密钥协商与传输层协议深度集成,减少握手步骤
  3. 防重放攻击:0-RTT 数据通过限制重放窗口和单次使用令牌(Token)增强安全性

QUIC应用场景

  1. HTTP/3QUICHTTP/3 的传输层协议,提升网页加载速度
  2. 实时通信:视频会议、在线游戏等低延迟场景
  3. 移动网络:应对频繁的网络切换和高丢包率
  4. CDN 优化:通过多路复用和快速重传提升内容分发效率

QUIC相关库与调试

quiche

  1. Rust 实现,支持 HTTP/3

lsquic

  1. C 语言实现,轻量高效

Neqo

  1. Rust 实现,用于 Firefox

Google QUIC

  1. C++ 实现,Chrome 浏览器底层
  2. 关键目录

  1. 核心类
    1. QuicSession:管理连接生命周期、流控制和多路复用
    2. QuicStream:单个流的实现,处理数据的收发和有序性
    3. QuicPacketCreator:构建 QUIC 数据包,处理包编号和帧封装

调试

  1. Wireshark
    1. 需安装 QUIC 插件,过滤 udp.port == 443
  2. qlog
    1. QUIC 专用日志格式,记录连接事件和状态变化

QUIC 的底层问题与优化

QUIC 的性能挑战

  1. UDP 缓冲区限制:操作系统默认 UDP 接收缓冲区较小,需手动调优

  1. CPU 密集型加密:通过硬件加速(如 AES-NI)优化 TLS 1.3 计算

对抗网络干扰

  1. PMTUD(路径 MTU 发现):QUIC 支持动态 MTU 探测,避免分片
  2. FEC(前向纠错):通过 XOR 冗余包在丢包时快速恢复数据(需权衡带宽开销)

相关文档

  1. RFC9000
    1. RFC 9000: QUIC传输协议
  2. RFC9114
    1. RFC 9114: HTTP/3

本文为原创文章,版权归所有,欢迎分享本文,转载请保留出处!

bingliaolong
Bingliaolong 关注:0    粉丝:0 最后编辑于:2025-03-30
Everything will be better.

发表评论

表情 格式 链接 私密 签到
扫一扫二维码分享