目录
TCP/UDP缺点
TCP的不足
UDP的不足
握手导致的连接成本
TCP的可靠成本
中间设备的僵化
依赖于操作系统的实现导致协议僵化
队头阻塞
QUIC的特点
QUIC原理
QUIC使用场景
QUIC报文格式概述
参考资料
QUIC(Quick UDP Internet Connection)是谷歌提出的一种基于UDP的低时延的互联网传输层协议。
QUIC解决了现代网站应用的一系列的传输层级应用层的问题,但是只需要应用开发者几乎不用做出或者只做出很小的改变。QUIC和TCP+TLS+HTTP很类似,但是基于UDP实现,基于QUIC实现的HTTP协议被提议为HTTP3。
为什么会有QUIC,那么得从两大主流协议TCP/UDP协议的不足说起。
1. 握手导致的连接成本
2. 队头阻塞
3. 连接不能迁移(手机以及Wifi的场景)
4. 协议历史悠久导致中间设备僵化
5. 依赖于操作系统的实现导致协议本身僵化。
1. 不可靠
2. 不稳定
不管是 HTTP1.0/1.1 还是 HTTPS,HTTP2,都使用了 TCP 进行传输。HTTPS 和 HTTP2 还需要使用 TLS 协议来进行安全传输,TCP的缺点HTTP及TLS都有。
这就出现了两个握手延迟:
1. TCP 三次握手导致的 TCP 连接建立的延迟;
2. TLS 完全握手需要至少 2 个 RTT 才能建立,简化握手需要 1 个 RTT 的握手延迟。
对于很多短连接场景,这样的握手延迟影响很大,且无法消除。
在数据传递时,确认机制、重传机制、拥塞控制机制等都会消耗大量的时间,而且要在每台设备上维护所有的传输连接,事实上,每个连接都会占用系统的CPU、内存等硬件资源。 而且,因为TCP有确认机制、三次握手机制,这些也导致TCP容易被人利用,实现DOS、DDOS、CC等攻击。
TCP 协议使用得太久,也非常可靠。所以我们很多中间设备,包括防火墙、NAT 网关,整流器等出现了一些约定俗成的动作。
比如有些防火墙只允许通过 80 和 443,不放通其他端口。NAT 网关在转换网络地址时重写传输层的头部,有可能导致双方无法使用新的传输格式。整流器和中间代理有时候出于安全的需要,会删除一些它们不认识的选项字段。
TCP 协议本来是支持端口、选项及特性的增加和修改。但是由于 TCP 协议和知名端口及选项使用的历史太悠久,中间设备已经依赖于这些潜规则,所以对这些内容的修改很容易遭到中间环节的干扰而失败。而这些干扰,也导致很多在 TCP 协议上的优化变得小心谨慎,步履维艰。
TCP 是由操作系统在内核系统层面实现的,应用程序只能使用,不能直接修改。虽然应用程序的更新迭代非常快速和简单。但是 TCP 的迭代却非常缓慢,原因就是操作系统升级很麻烦。
服务端系统不依赖用户升级,但是由于操作系统升级涉及到底层软件和运行库的更新,所以也比较保守和缓慢。这也就意味着即使 TCP 有比较好的特性更新,也很难快速推广。比如 TCP Fast Open。它虽然 2013 年就被提出了,但是 Windows 很多系统版本依然不支持它。
队头阻塞主要是 TCP 协议的可靠性机制引入的。TCP 使用序列号来标识数据的顺序,数据必须按照顺序处理,如果前面的数据丢失,后面的数据就算到达了也不会通知应用层来处理。
另外 TLS 协议层面也有一个队头阻塞,因为 TLS 协议都是按照 record 来处理数据的,如果一个 record 中丢失了数据,也会导致整个 record 无法正确处理。
概括来讲,TCP 和 TLS1.2 之前的协议存在着结构性的问题,如果继续在现有的 TCP、TLS 协议之上实现一个全新的应用层协议,依赖于操作系统、中间设备还有用户的支持。部署成本非常高,阻力非常大。
所以 QUIC 协议选择了 UDP,因为 UDP 本身没有连接的概念,不需要三次握手,优化了连接建立的握手延迟,同时在应用程序层面实现了 TCP 的可靠性,TLS 的安全性和 HTTP2 的并发性,只需要用户端和服务端的应用程序支持 QUIC 协议,完全避开了操作系统和中间设备的限制
1. 连接建立很快
2. 更加灵活的拥塞控制
3. 没有队头阻塞的多路复用
4. 身份认证和加密的头部和负载
5. 流和连接的流量控制
6. 前项纠错
7. 连接转移
QUIC通过减少握手时间,改进拥塞控制,提供可靠的传输等方式避免TCP等协议的不足,相当于站在了巨人的肩膀上,在基于UDP提供可靠可靠的数据传输,并且传输的数据几乎都通过DH算法协商加密密钥,进行进行加密,保证了数据传输的安全性。
QUIC当前是针对Web提出的方案,适用于Web。
QUIC是居于UDP实现,因此未涉及到内核层面,迭代更新都比较容易,基于QUIC的HTTP被提议为HTTP3,前途不可限量。
TCP 协议头部没有经过任何加密和认证,所以在传输过程中很容易被中间网络设备篡改,注入和窃听。比如修改序列号、滑动窗口。这些行为有可能是出于性能优化,也有可能是主动攻击。但是 QUIC 的 packet 可以说是武装到了牙齿。除了个别报文比如 PUBLIC_RESET 和 CHLO,所有报文头部都是经过认证的,报文 Body 都是经过加密的。这样只要对 QUIC 报文任何修改,接收端都能够及时发现,有效地降低了安全风险。
如图 1所示,红色部分是 Stream Frame 的报文头部,有认证。绿色部分是报文内容,全部经过加密。
QUIC报文分为特殊报文和普通报文。特殊报文又分为两类:版本协商报文(Version Negotiation Packets)及公共重置报文(Public Reset Packets)。普通报文也分为两类:帧报文及FEC(Forward Error Correction)报文。
QUIC报文的大小需要满足路径MTU的大小以避免被分片。当前QUIC在IPV6下的最大报文长度为1350,IPV4下的最大报文长度为1370.
QUIC报文格式见《QUIC的那些事 | 包类型及格式》
新一代基于UDP的低延时网络传输层协议——QUIC详解