QUIC协议详解
声明
本文可以自由转载但需注明原始链接。本文为本人原创,作者LightningStar,原文发表在博客园。本文主体内容参考论文[1]完成。
介绍
QUIC,发音同quick,是"Quick UDP Internet Connections"的简称,是一种通用的传输层网络协议。QUIC与TCP相同,是一种有连接的传输协议。但是与TCP不同的是QUIC是建立在UDP传输层协议之上的,实现了在两个端点之间的多路复用。QUIC的是在用户空间实现的,TCP/UDP则是在内核空间实现的。[2]
QUIC所处的网络层次如下图所示。图源文献[1:1]。
优势
Quic 相比现在广泛应用的 http2+tcp+tls 协议有如下优势:
1、减少了 TCP 三次握手及 TLS 握手时间。
2、改进的拥塞控制。
3、避免队头阻塞的多路复用。
4、连接迁移。
5、前向安全。
建立连接(握手)
QUIC实现了快速握手,并把握手过程分为两种情况,分别是1-RTT和0-RTT。在介绍这两种握手过程之前,读者需自行熟悉Diffie-Hellman算法的基本原理[3]。
在上图(文献[1:2])中显示了三种不同情况的连接过程。其中最左边的图表示的是第一次连接时的情况,中间的图表示重复连接的情况(在一定条件下,客户端可以重新连接服务器而不需要从初始化情况连接),最右边的图则是重连失败之后从初始话连接的情况。最后一种情况是第一种情况的组会,0-RTT也是1-RTT的一部分,后文中将重点介绍1-RTT的连接过程。
1-RTT
第一次握手:
- 客户端主动向服务器发送Inchoate CHLO报文
- 服务器会向客户端发送REJ报文。REJ报文包含了服务器的配置信息,如长期的Diffie-Hellman值,服务器配置的签名,source-address-token(stk, 用于验证的加密块,包含有服务器看到的客户端的IP地址和服务器当前的时间戳,之后客户端会将该stk发回)等,为了进行身份证明还会使用私钥进行签名,同时也可以防篡改;
- 在收到服务器的配置信息后,客户端会通过证书链机制验签,并实现对服务器的身份认证。
第二次握手:
- 客户端在通过对服务器的验证之后,客户端会生成一个Diffie-Hellman值。此时客户端有了自身和对方的Diffie-Hellman值,就可以计算出初始密钥(initial key, ik);
- 客户端将包含有DH公开之的明文Complete CHLO发送至服务器;
- 客户端使用ik对请求数据加密,发送至服务器;
- 服务器收到Complete CHLO之后就可以获得客户端的Diffie-Hellman的值,就可以计算出初始密钥。
- 服务器立即向客户端发送SHLO报文(ik加密的)。SHLO报文含有一个服务器临时Diffie-Hellman值,可以用于计算前向安全的密钥(会话密钥);
- 服务器收到加密的请求数据,使用初始密钥进行解密;
- 服务器使用会话密钥对响应数据进行加密,发回给客户端。
- 客户端在收到SHLO之后使用初始密钥解密得到服务器的临时DH公开值,根据该临时值计算出会话密钥;
- 客户端收到加密的响应数据后,使用会话密钥进行解密。
整个握手过程会在2个RTT内完成。
0-RTT
客户端在重连同一个服务器时,会使用已经缓存的服务器相关配置信息(stk,DH公开值等信息),并直接向服务器发送Complete CHLO报文,并使用ik对请求报文进行加密。但是服务器方面会标识相应的stk等信息已经过期,这时服务器会发送REJ信息,客户端需要重新与服务器进行连接。
如果没有过期的话,就可以直接建立连接,省下了重新建立连接的开销。
前向安全性
所谓前向安全性就是指,在最后一次握手时,会生成一个会话密钥sk。这样即使服务器的长期DH值被破获,且生成了初始密钥ik,也无法对会话中的数据进行解密。
多路复用机制
基于TCP的应用程序会在TCP单字节流抽象层中实现多路复用。为了避免由于TCP顺序传递导致的头部阻塞(head-of-line blocking)[4],QUIC支持在单个UDP连接中复用多个流,并保证UDP报文的丢失仅影响相应的流,而不会影响其他的流(stream)。
可以在QUIC流上构建任意大小的应用程序报文,最多支持\(2^{64}\)的字节。并且stream的实现是轻量级的,即使消息报文很小也可以为它们使用单独的流。每一个Stream都有stream ID唯一标识。这些流ID由客户端/服务器进行静态分配。客户端主动发起的流的ID永远是奇数,服务器发起的流的ID是偶数。这样可以避免冲突。当在一个未使用过的流上发送数据时,流会自动创建;当需要关闭时,就会在最后一帧数据上设置一个FIN的标志指示接收方关闭流。如果发送方或接收方确定不再需要流上的数据,则可以取消流,而无需断开整个 QUIC 连接。尽管流是可靠的抽象,但 QUIC 不会为已取消的流重新传输数据。
一个QUIC包是由一个公共的头后面跟着一个或多个帧组成的,如下图(图源[1:3])所示。QUIC流复用是通过将流数据封装在一个或多个流帧中来实现的,单个QUIC包可以携带来自多个流的流帧.
报文丢失重传
TCP 序列号有助于提高可靠性,并表示在接收方传送字节的顺序。这种混淆会导致“重传模糊”(retransmission ambiguity)问题,因为重传的 TCP 段携带与原始数据包相同的序列号 。 TCP ACK 的接收者无法确定 ACK 是为原始传输还是为重传而发送,并且通常通过昂贵的超时来检测重传段的丢失。每个 QUIC 数据包都携带一个新的数据包编号,包括那些携带重传数据的数据包。这种设计不需要单独的机制来区分重传的 ACK 和原始传输的 ACK,从而避免了 TCP 的重传模糊问题。流帧中的流偏移用于传递排序,数据包编号表示一个明确的时间顺序,这使得丢失检测比 TCP 更简单、更准确。
QUIC的ACK显示地记录了接收的数据报文和ACK之间的延迟。单调增加的报文编号一起,可以精确估算RTT,有助于丢失检测。QUIC的确认报文支持多达256个ACK,这是使得QUIC比带有SACK的TCP更能适应重新排序或丢失的情况下在线路上保留更多字节。
更多内容参见[5]。
流量控制(Flow Control)
当应用程序从QUIC的接收缓冲区中读取数据较慢时,留恋控制就会限制接收者必须保持的接收缓冲区大小。一个缓慢耗尽的stream会逐渐耗尽整个连接connection的缓冲区,因此必须要限制QUIC连接上的每个流可以消耗的缓冲区大小,避免消耗其他流的缓冲区的大小。这样可以改善流之间潜在的队头阻塞(head-of-line blocking)。因此QUIC采用连接级别的流量控制(connection-level flow control),这样可以限制发送者在所有流中接收者使用的聚合缓冲区;采用流级别的流量控制(stream-level flow control)可以限制发送者在任何给定流上使用的缓冲区。
与HTTP/2类似,QUIC采用基于信用的流量控制。QUIC接收器在每个流中通告接收器愿意接收数据的绝对字节偏移量。在特定流上发送、接收和传递数据时,接收器会定期发送窗口更新帧,以增加该流的窗口偏移限制,从而允许对等方在该流上发送更多数据。连接级流量控制的工作方式与流级流量控制相同,但传递的字节数和接收到的最高偏移量是所有流的。
拥塞控制(Congestion Control)
QUIC支持的拥塞控制算法有:
Reno(TCP用的)、基于Pacing的拥塞控制算法(PBCCA)、TCP CUBIC等。
连接迁移
QUIC连接使用随机生成的64bit的cid唯一确定。cid允许客户机在网络之间漫游,而不受网络或传输层参数变化的影响。
cid使得客户端能够独立于网络地址转换(network address translation, NAT)之外。cid 在路由中起着重要作用,特别是用于连接标识的目的。此外,使用 cids 可以通过探测连接的新路径实现多路径。
在连接迁移期间,端点假设对等方愿意在其当前地址接受数据包。因此,端点可以迁移到新的 IP 地址,而无需首先验证对等方的 IP 地址。新的路由路径可能不支持端点的当前发送速率。在这种情况下,端点需要重新构建它的拥塞控制器。另一方面,从一个新的对等地址接收非探测包 ,确认对等地址已迁移到新的 IP 地址。
实现参考
- Google Quic Project[6]
拓展阅读
Implementation and analysis of QUIC for MQTT[7]
RFC 9000 QUIC: A UDP-Based Multiplexed and Secure Transport
QUIC的初步标准定义。
参考文献
LANGLEY A, RIDDOCH A, WILK A, 等. The QUIC Transport Protocol: Design and Internet-Scale Deployment[C/OL]//Proceedings of the Conference of the ACM Special Interest Group on Data Communication. Los Angeles CA USA: ACM, 2017: 183-196[2022-03-05]. https://dl.acm.org/doi/10.1145/3098822.3098842. DOI:10.1145/3098822.3098842. ︎ ︎ ︎ ︎
J. Iyengar and I. Swett. 2016. QUIC Loss Detection and Congestion Control.IETF Internet Draft, draft-ietf-quic-recovery ︎
KUMAR P, DEZFOULI B. Implementation and analysis of QUIC for MQTT[J/OL]. Computer Networks, 2019, 150: 28-45. DOI:10.1016/j.comnet.2018.12.012. ︎
QUIC协议详解的更多相关文章
- QUIC协议详解之Initial包的处理
从服务器发起请求开始追踪,细说数据包在 QUIC 协议中经历的每一步.大量实例代码展示,简明易懂了解 QUIC. 前言 本文介绍了在 QUIC 服务器在收到 QUIC 客户端发起的第一个 UDP 请求 ...
- HTTP协议详解(转)
转自:http://blog.csdn.net/gueter/archive/2007/03/08/1524447.aspx Author :Jeffrey 引言 HTTP是一个属于应用层的面向对象的 ...
- HTTP协议详解
Author :Jeffrey 引言 HTTP 是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和 扩展. ...
- 动态选路、RIP协议&&OSPF协议详解
动态选路.RIP协议&&OSPF协议详解 概念 当相邻路由器之间进行通信,以告知对方每个路由器当前所连接的网络,这时就出现了动态选路.路由器之间必须采用选路协议进行通信,这样的选路协议 ...
- ASP.NET知识总结(3.HTTP协议详解)
引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1. ...
- 接口测试之HTTP协议详解
引言 HTTP是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和扩展.目前在WWW中使用的是HTTP/1. ...
- 计算机网络(12)-----HTTP协议详解
HTTP协议详解 http请求 http请求由三部分组成,分别是:请求行.消息报头.请求正文 (1)请求行 请求行以一个方法符号开头,以空格分开,后面跟着请求的URI和协议的版本,格式如下:Metho ...
- OSPF协议详解
CCNP OSPF协议详解 2010-02-24 20:30:22 标签:CCNP 职场 OSPF 休闲 OSPF(Open Shortest Path Fitst,ospf)开放最短路径优先协议,是 ...
- HTTP协议详解(真的很经典)
HTTP 是一个属于应用层的面向对象的协议,由于其简捷.快速的方式,适用于分布式超媒体信息系统.它于1990年提出,经过几年的使用与发展,得到不断地完善和 扩展.目前在WWW中使用的是HTTP/1.0 ...
随机推荐
- Java 锁 概念介绍
一 Java中的锁是什么? /* * 一 Java锁定义? * 在计算机科学中,锁(lock)或互斥(mutex)是一种同步机制,用于在有许多执行线程的环境中强制对资源的访问限制. * 锁旨在强制 ...
- Idea内存设置idea.vmoptions无效的解决办法
原因:貌似是因为maven的问题 解决办法 结果
- 洛谷P7814 「小窝 R3」心の記憶
题意 第一行给定两个数字\(n\) \(m\) \((m \ge n)\)分别代表给定字符串长度以及需要构造出的字符串长度 第二行给定一个长度为\(n\)的字符串 (假设原来的字符串是\(a\) 需要 ...
- 阿里四面:你知道Spring AOP创建Proxy的过程吗?
Spring在程序运行期,就能帮助我们把切面中的代码织入Bean的方法内,让开发者能无感知地在容器对象方法前后随心添加相应处理逻辑,所以AOP其实就是个代理模式. 但凡是代理,由于代码不可直接阅读,也 ...
- 再见丑陋的 SwaggerUI,这款开源的API文档生成神器界面更炫酷,逼格更高!
一般在使用 Spring Boot 开发前后端分离项目的时候,都会用到 Swagger.Swagger 是一个规范和完整的框架,用于生成.描述.调试和可视化 RESTful 风格的 Web API 服 ...
- JAVA类加载器二 通过类加载器读取资源文件
感谢原文作者:不将就! 原文链接:https://www.cnblogs.com/byron0918/p/5770684.html 一.getResourceAsStream方法 getResourc ...
- C预备知识_001
程序由什么构成? 1.对数据的描述:在程序中要指定用到哪些数据以及这些数据的类型和数据的组织形式,其实这就是数据结构(data structure). 2.对操作的描述:即要求计算机就行操作的步骤,也 ...
- AppiumForMac安装2
安装了两天的Python和Appium,各种不成功,到现在还不知道要怎么才能使用,两者之间的关联性还是没找到. 虽然很乱,还是把这期间用到的知识汇总下: 1.爬墙很重要,下载东西慢的很. 2.最新的M ...
- Ubuntu下pip3的安装、升级、卸载
1.安装 sudo apt-get install python3-pip 2.升级 sudo pip3 install --upgrade pip 3.卸载 sudo apt-get remove ...
- 系统C盘空间严重的不足的几个清理方法
大家在电脑使用久了以后,往往会遇到C盘空间不足的问题,这很可能进一步导致磁盘空间不足,软件无法正常运行,甚至电脑严重卡顿等问题. 下面给大家分享一些我自己在C盘空间不足过程中搜集的一些清理C盘空间的实 ...