Quic Protocal Part 3:包和帧

2019-11-19 143 Words Quic Web

Quic 协议——第三部分

QUIC 的通信采用了包(Package)和帧(frame)的双重结构。

一个 UDP 包中可能包含有多个 QUIC 包,其中每一个 QUIC 包中可以包含多个帧(frame)。

一个 UDP 报文包的 QUIC 包必须是同一个连接中的多个 QUIC 数据包。

帧是完整某项功能的基本单位,比如之前所述的 STREAM 帧用于发送流数据、CONNECTION_CLOSE 帧用于关闭连接等。

一、 QUIC Package

如前所述,QUIC 协议有长报文头和短报文头两种,在建立连接过程中使用的长报文头。这包括如下一些报文:初始数据包、0RTT数据包、握手数据包、重试数据包等。

除了版本协商数据包和重试数据包之外,其他数据包均使用 AEAD 算法提供机密性、完整性和身份认证保护。

包的 Package Number 是 0-2^62-1 的序列号,在实际报文中,可能被重新映射到 1-4字节。

Package Number 被分配为:初始空间、握手空间和应用空间三个部分。每次都从对应空间的 0 号开始,而后以此递增。

当 2^62 -1 时,必须关闭连接。

1.1 长包头数据包

长包头中包括了版本号,Package Number,源和目的 Connection ID 以及子类型,有如下几种类型:

1.1.1 版本协商包 Version Negotation Package

当客户端版本不被接收的时候,由服务器端发送。

1.1.2 初始数据包 Initial Package

它携带客户端和服务器发送的第一个CRYPTO帧来执行密钥交换,并携带两个方向的ACK。

1.1.3 0RTT 数据包

0-RTT数据包使用类型值为0x1的长报头,后跟长度和数据包号字段。第一个字节包含保留和数据 包号长度位。它用于在握手完成之前,将“早期”数据从客户端传送到服务器,作为第一次传输的 一部分。作为TLS握手的一部分,服务器可以接受或拒绝此早期数据。

1.1.4 握手数据包 Handshake Package

握手数据包使用类型值为0x2的长报头,后跟长度和数据包号字段。第一个字节包含保留和数据包号 长度位。它用于传送来自服务器和客户端的确认和加密握手消息。

1.1.5 Retry Package

携带一个 token 用于无状态关闭连接

1.2短包头数据包

短包头数据包头包括 Version, Package Number, 目的CONNECTION ID,

二、QUIC Frame

每个帧头部表示了帧的类型(Frame Type) 而后是帧的具体内容。QUIC 报文至少包括一个帧,且帧不可以跨域多个 QUIC 报文。

  • PADDING: 填充报文长度到指定长度
  • PING: 判断对端是否存活
  • ACK:用于报文 Package Number 确认
  • RESET_STREAM: 中止流
  • STOP_SENDING: 接收方不再接收流数据
  • CRYPTO: 握手协商
  • NEW_TOKEN: 新建token
  • STREAM:传输数据
  • MAX_DATA: 连接流量控制
  • MAX_STREAM_DATA: 流流量控制
  • MAX_STREAMS: 最大流的个数
  • DATA_BLOCKS: 提示发送方希望发送数据但是连接层面阻塞了
  • STREAM_DATA_BLOCKS: 提示发送方希望发送数据但是流层面阻塞了
  • STREAMS_BLOCKS: 提示达到最大流的个数了
  • NEW_CONNECTION_ID: 建立新的 connection id
  • RETIRE_CONNECTION_ID: 取消一个 connection id
  • PATH_CHALLENGE: 路径检测的挑战帧
  • PATH_RESPONSE: 路径检测的应答帧
  • CONNNECTION_CLOSE: 立即终止连接帧
  • EXTENSION FRAMES:QUIC 协议不规范,由双方规定