QUIC的packet分为Special Packets和Regular Packets两种,其中各自又有两种不同的packet

特殊报文:
版本协商报文(Version Negotiation Packets)
公共重置报文(Public Reset Packets)

普通报文:
常规报文(Regular Packets)
FEC(Forward Error Correction)报文

QUIC报文的大小需要满足路径MTU (最大传输单元Maximum Transmission Unit) 的大小以避免被分片。当前QUIC在IPV6下的最大报文长度为1350,IPV4下的最大报文长度为1370.

所有的Quic包都是以一个1~51字节的公共头开始的。其格式如下

红色部分是认证的报文头部,绿色部分是加密的报文内容

QUIC Public Packet Header

其中最重要的就是Public Flags,占一个字节,8个bit

0x01: 如果Bit0位被置为1, 0x01 = PUBLIC_FLAG_VERSION) ,该字段的含义取决于报文是客户端发送的还是服务端发送的。如果是客户端发送,这一位被置上表示QUIC Version字段不为空,且QUIC Version字段被填充为客户端的QUIC版本。在客户端收到服务端同意建立该版本的连接报文之前,客户端发送的所有报文的这一位都必须被设置。如果服务端同意建立该版本的连接,那么之后这一位就不用设置了。
如果这一位是被服务端发送的报文设置的,那么就表示该报文是版本协商报文(Version Negotiation Packet)

0x02: 如果Bit1被置上 (0x02 = PUBLIC_FLAG_RESET),表明该报文是公共重置报文(Public Reset packet)

0x04: Bit2被置上就表示包头包含了32字节的 Diversification Nonce

0x08: Bit3被置上就表示header中包含8字节的connection id 这个标志位在所有的包中都应该被设置

0x30上的两位(Bit4,Bit5)表示packet number 的长度,只有在含有Frame Packets的时候这两位才会使用到,也就是说Reset 包和版本协商包都是不需要packet number的 (因为packet number是为了解决TCP重传歧义性的问题)

  • 0x30(Bit5及Bit4均为1)表示:packet number是6个字节
  • 0x20(Bit5为1,Bit4为0)表示:packet number是4个字节
  • 0x10(Bit5为0,Bit4为1)表示:packet numbe是2个字节
  • 0x00(Bit5及Bit4均为0)表示:packet numbe是1个字节

0x40: Bit6 是预留给多路径使用的

0x80: Bit7未使用,必须置为0

connection ID: 64位无符号整型,由client随机产生,用来标识一个连接, 之所以使用Connection ID而不使用四元组标识(源 IP,源端口,目的 IP,目的端口),是为了就算 IP 或者端口发生变化时,只要 ID 不变,这条连接依旧可以维持,上层业务逻辑感知不到变化,不会中断,也就不需要重连。

Quic Version : 32位,用来表示Quic 协议版本.只有当PUBLIC_FLAG_VERSION 被设置才会存在这个字段。server 只有在不支持客户端携带的版本时,才会设置PUBLIC_FLAG_VERSION并且其后不会再附带其他信息(也就是版本协商包)。

Packet Number : 可能为8,16,32,48位的packet number,具体的长度由public flags决定 。每个常规包(Regular Packet)都会被分配一个packet number, 各端发送的第一个包的packet number是1,之后的数据包中的packet number都会大于前一个包的packet number(单调递增)

Public Flags的解析流程如下:

版本协商包报文


版本协商报文只能由服务端发送。版本协议报文以1字节的Public Flag及8字节的Connection ID开始。且public flag 必须置为PUBLIC_FLAG_VERSION,并标识Connection ID长度为8字节,剩下的部分,每4个字节表示server端 所支持的Quic版本信息

公共重置包 (Public Reset Packet)

Reset packets are sent by a server that does not have state for the connection, which may happen due to a routing change or due to a server restart.

Public Reset Packet的public flags必须设置PUBLIC_FLAG_RESET且标识Connection ID长度为8字节,剩余的部分是QUIC Tag。

Tag value map包含如下的tag-values:
RNON (public reset nonce proof):64位的无符号整数,必填
RSEQ (rejected packet number) :64位,必填
CADR (client address):客户端的IP地址及端口。当前用于调试用途,可选

Regular Packet

常规包是经过认证和加密的,公共头(Public Header)只经过认证,并没有加密,包的剩余部分都是经过加密的。一个常规包会包含一系列的Frames

帧包有一系列不同的类型, 一般帧包的格式如下:

也分为普通帧包和特殊帧包

Stream Frame

STREAM Frame既用于隐式创建一条流,也用于发送数据,格式如下

Stream Frame的type是1fdooossB,这是一个8bit的值,包含各种flags
最左边的bit 必须设置为1,表示这是一个STREAM frame, ‘f’ bit位表示 Fin 位,当该位被设置为1时,表示发送方已经发完了,连接将处于半关闭状态。‘d’ bit表示在STREAM header中是否包含有数据长度,
当被设置为0时,表示 直到包尾都是STREAM Frame,后续的三个’ooo’bit表示Offset 长度,分别为 0,16,24,32,40,48,58,64位 ,再接下来的两个’ss’表示stream id的长度,取值为8,16,24,32

Stream ID: 可变的无符号整型,唯一区分这条流
Offset: 可变长度,表示这块数据在整个stream 中的偏移。
Data Length: 可选的16位无符号整型,表示在这个stream frame中数据的长度。

WINDOW_UPDATE Frame


用于告知对端接收窗口增加了,如果Stream ID 等于0,表示这是Connection的流量控制,否则就是Stream级别的流量控制,表示在指定的流上应该增加其流量控制窗口

Frame Type:8bit,必须设置成0x04 ,表示是WINDOW_UPDATE Frame
Stream ID: 0表示是Connection级别的流量控制,非0则表示对应Stream ID的流级别的流量控制
Byte offset: 64位,表示指定流上数据的绝对偏移量。

FEC(Forward Error Correction) packet

QUIC为了减少数据包丢失时的重传,传递数据包时还会带上其他数据包的校验信息,即将N个包的校验和(异或)建立一个单独的数据包发送
P=D1 xor D2 xor D3 … xor Dn (D1,D2,D3 … Dn为数据块,P为校验,xor为异或运算)

假如D3 数据包丢失,可以通过p和其他参数异或恢复出来。并且还可以用来校验记录的数据包的有效性。

其他版本的报文格式

上述的报文格式都基于version 43及以下的版本,后面的版本在报文格式方面有一些改动

Version 44- 48:
为了推进Google QUIC的IETF标准化,在version46之后发生了如下改动
将Header分成两种不同的类型,在1RTT连接建立和版本协商成功之前的packets 使用Long Header,其余的时候Short-Header

主要是在Long Header中增加了一个Source Connection ID并对格式进行了一些调整
DCIL:Destination Connection ID Length
SCIL:Source Connection ID Length

参考资料;
version 43:
QUIC Wire Layout Specification
version 46:
Use IETF Packet Header Wire Format in Google QUIC
version 49:
https://tools.ietf.org/html/draft-ietf-quic-invariants-07

QUIC报文格式详解相关推荐

  1. icmp报文格式_TCP/IP(二):IP报文格式详解

    1. IP 报文格式 0bit是指位于最左边的最高位,31bit是指位于最右边的最低位,4个字节的32bit按照 bigendian(大端格式:低字节位于高地址)字节序传输:首先是0~7bit,其次 ...

  2. ICMP报文格式详解

    1 引言 2 ICMP报文的类型 3 ICMP地址掩请求与应答 4 ICMP时间戳请求与应答 5 ICMP端口不可达差错 1 引言 ICMP经常被认为是IP层的一个组成部分.它传递差错以及其他需要注意 ...

  3. IPv4 和 IPv6 报文格式详解

    文章目录 1 概述 2 报文格式 2.1 IPv4 2.2 IPv6 2.3 两者区别 3 网工软考真题 1 概述 2 报文格式 2.1 IPv4 中文名 英文名 长度 bit(位) 解释 版本 Ve ...

  4. HTTP 请求报文、响应报文格式详解

    HTTP请求报文格式: 图片只做参考 HTTP请求报文主要由请求行.请求头部.请求正文(附属体)3部分组成 1,请求行 由3部分组成,分别为:请求方法.URL(见备注1)以及协议版本,之间由空格分隔 ...

  5. Bacnet协议报文格式详解(一)

    系统实现基于BACnet/IP(又称B/IP)网络进行通讯.BACnet虚拟链路层(BVLL)提供了BACnet网络层和某指定的通讯子系统的接口,本文指定了BACnet虚拟链路控制(BVLC)要求支持 ...

  6. 54.UDP报文格式详解

    相比 TCP 协议,UDP 协议的报文结构相对简单.本节将详细讲解 UDP 报文的格式. UDP 报文格式 每个 UDP 报文分为 UDP 报头和 UDP 数据区两部分.报头由 4 个 16 位长(2 ...

  7. tcp报文格式udp报文格式详解

    http://blog.csdn.net/a19881029/article/details/29557837 TCP(Transmission Control Protocol)传输控制协议是一种面 ...

  8. 数据帧、IP数据包、TCP、UDP报文格式详解----网络通信原理

    数据链路层.网络层.传输层----网络通信原理 物理层 数据链路层 eNSP抓包实验 网络层 ICMP协议概述 eNSP抓包实验 ARP协议概述 eNSP抓包实验 传输层 TCP协议 eNSP抓包 三 ...

  9. TCP/IP(五):UDP 报文格式详解

    1.概述 UDP 是User Datagram Protocol的简称, 中文名是用户数据报协议,是OSI(Open System Interconnection,开放式系统互联) 参考模型中一种无连 ...

最新文章

  1. 脸红是因为缺乏乙醛分解酶导致的酒精中毒
  2. [翻译] TWRPickerSlider
  3. 计算机与网络应用基础知识下上机考试,计算机应用基础知识考试
  4. 安卓开发笔记(二十二):读取本地(内置)html文件并实现和Javascript交互
  5. 随想录(单片机和步进电机学习笔记)
  6. 不说“安全”俩字,如何证明自己是做安全的?
  7. iphone(苹果)手机登陆Exchange 2013邮箱帐号的配置
  8. 解决Zarp报错,成功运行
  9. 学习 WebService 第三步:一个简单的实例(SoapUI测试REST项目)
  10. 五、谈扩展方法的理解
  11. 基于php046学校固定资产管理系统
  12. Windows子系统(GUI)
  13. 手机内存垃圾不会清理?学会删除这几个文件夹,瞬间腾出几个G
  14. 算法笔记002_我读《The Emperor’s New Mind》
  15. 全国强制安装H6S国六柴油车载排放OBD诊断系统在线检测类终端
  16. python里的apply,applymap和map
  17. 什么是核函数?如何理解?
  18. sublime:下载免费历史版本
  19. 00 C++ UML类图详解
  20. 我们公司放弃了微服务,重回单体架构

热门文章

  1. 跳转控制语句之break
  2. 共模电压和差模电压-(定义及测量)
  3. 我的ASP.NET AJAX控件——PopupNotificationExtender:实现OWA或Messenger样式的信息提示窗口...
  4. oracle数据库中对varchar类型求max的解决方法
  5. Windows8/Silverlight/WPF/WP7/HTML5周学习导读(1月1日-1月6日)
  6. 果断收藏!六大主流大数据采集平台架构分析
  7. StackOverflow 每月5.6亿PV,但只用25台服务器
  8. js 对 URL 参数进行 加密 解密
  9. Java中关于枚举的7种用法
  10. bash特性之四、五