欢迎您访问 最编程 本站为您分享编程语言代码,编程技术文章!
您现在的位置是: 首页

QUIC协议解析进阶2:理解QUIC的package结构与种类

最编程 2024-07-31 15:49:08
...

1、数据包开头:QUIC Common

所有QUIC数据包均以QUIC Common格式开头,如下
+---------+------------------------------+
| Flags(8) | Connection ID (64) (optional)|
+---------+------------------------------+

1.1、Flag含义

  • 0x01 = VERSION 版本 ➡️0000000_
    (1)若该QUIC数据包由客户端发送:使用这个flag并包含一个确切的建议版本
    (2)若该QUIC数据包由服务器发送:不支持客户端建议的版本,并提供给客户端一系列可接受的版本
  • 0x02 = PUBLIC_RESET ➡️000000_0
    指明这个packet是一个公共重置数据包 Public Reset packet.
  • 0x04 = DIVERSIFICATION_NONCE = 00000?00
    指明header中存在32位的多样化随机数
  • 0x08 = CONNECTION_ID ➡️0000_000
    指明数据包中存在连接ID,
  • 0x30 = PACKET_NUMBER_SIZE ➡️00_ _0000
    指明每个数据包中存在的数据包编号的低位字节数。
    11:存在6个字节的数据包编号
    10:存在4个字节的数据包编号
    01:存在2个字节的数据包编号
    00:存在1个字节的数据包编号
  • 0x40 = MULTIPATH ➡️0_000000
    保留给多路复用使用
  • 0x80 ➡️_0000000
    暂未使用,常为0

1.2、Connection ID含义

由客户端选择的64位无符号随机数,用于作为连接标识符
每个Connection ID与一个QUIC连接绑定,在客户端和/或服务器IP和端口更改之间保持一致。

2、数据包类型

Regular packets:常规数据包
Version Negotiation packets:版本协商数据包
Public Reset packets:公共重置数据包


判断数据包类型

2.1 Regular packets:常规数据包

Common Header + 常规数据包专用字段


常规数据包
  • Version
    QUIC版本,仅存在于客户端->服务器方向。与VERSION flag和版本协商相关。
  • Diversification Nonce
    服务器生成的32字节的随机数,仅存在于服务器->客户端方向。目的是确保服务器能为每一个QUIC连接生成独一无二的key。
    具体来说,当使用QUIC当0-RTT加密握手时,具有完全相同的连接ID和CHLO的、重复的CHLO可以为该连接生成相同的中间初始加密密钥。服务器生成的随机数不允许客户端导致为两个不同的连接派生相同的密钥。一旦连接是前向安全的,该随机数不再存在于数据包中。
  • Packer Number
    数据包编号,它的低8、16、32、48位号码基于PACKET_NUMBER_SIZE标志。发送方给每个常规数据包分配了一个数据包号码。端点(C/S)发送的第一个数据包务必具有值为1的Packer Number。
  • AEAD Data
    常规数据包的header,包括common header, Version, Diversification Nonce, and Packet Number fields,已通过身份验证,但未加密

2.1.1 数据包编号的压缩和重构

完整的数据包号是一个64位无符号号,用作数据包加密的加密随机数的一部分。为减少表示线路上的数据包号所需的位数,最多只有48位数据包号通过有线传输。
一个QUIC端点不能在一个相同的连接中(即在相同的加密密钥下)重复使用

2.2.2 常规数据包的框架(frame)和框架类型

常规数据包至少含有一个框架,而且可能还有多个/多种框架。框架必须适合单个QUIC数据包,并且不得跨越QUIC数据包边界。


每个frame格式

以下为QUIC Frames的类型,注意其中的STREAM和ACK类型用于承载other frame-specific flags


QUIC Frames的类型

2.2 Version Negotiation packets:版本协商数据包

版本协商数据包仅由服务器发送,必须具有VERSION标志集,并且必须包含完整的64位连接ID。版本协商数据包的其余部分是一系列服务器支持的版本的4字节的列表。


版本协商协议包格式

2.3 Public Reset packets:公共重置数据包

需要PUBLIC_RESET被置1,且必须包括完整的64位连接ID,其余部分被编码为标签PRST的加密握手消息。


公共重置数据包格式

图中的tag value map包括以下tag-values:
o RNON (public reset nonce proof 公共重置随机数证明) - a 64-bit unsigned integer.
o RSEQ (rejected packet number 被拒绝的数据包编号) - a 64-bit packet number.
o CADR (client address 客户端地址) - the observed client IP address and port number. This is currently for debugging purposes only and hence is optional. 观察到的客户端IP地址和端口数。当前这仅用于调试目的,因此是可选的。

推荐阅读