QUIC协议

什么是QUIC

QUIC(Quick UDP Internet Connections)是一种由Google开发的新型网络传输协议,旨在通过UDP提供与TCP类似的可靠传输服务,同时解决传统TCP协议的延迟和拥塞控制问题。QUIC整合了TLS加密、流量控制、连接管理等功能,优化了传输性能,尤其是在高延迟和不稳定网络环境中表现出色。

QUIC所处的网络层次如下图所示。

QUIC的核心概念

连接ID:QUIC使用连接ID来标识连接,从而使得在网络地址(如IP和端口)变化时能够保持连接状态。
数据包:QUIC的数据包结构与传统UDP包不同,包含连接ID、包号、加密信息等,确保数据包的安全和可靠传输。
流(Stream):QUIC中的流是数据传输的基本单位,每个流都有唯一的ID,可以独立传输,避免互相影响。
握手过程:QUIC将连接建立与TLS握手结合,使用1-RTT或0-RTT完成握手过程,极大地减少了连接延迟。

QUIC的数据包格式

QUIC的数据包分为Header和Data部分,其中Header是明文传输,包括Flags是标志位,Connection ID是连接ID,可用于连接迁移,QUIC Version是QUIC的版本号,Packet Number是包序号,用于保证可靠传输;Data部分是密文传输,是一些数据帧,有很多数据帧类型:Stream、ACK、Padding、Blocked等,其中Stream帧传输应用数据。

Stream

Frame Type: Bit7~Bit0

  1. Bit7:必须设置为1,表示Stream帧
  2. Bit6:如果设置为1,表示发送端在这个stream上已经结束发送数据,流将处于半关闭状态
  3. Bit5:如果设置为1,表示Stream头中包含Data Length字段
  4. Bit432:表示offset的长度。000表示0字节,001表示1字节,002表示2字节,以此类推
  5. Bit10:表示Stream ID的长度。00表示1字节,01表示2字节,10表示3字节,11表示4字节

建立连接

建立HTTPS连接

先分析一下HTTPS的握手过程,包括TCP握手和TLS(Transport Layer Security)握手,HTTPS连接耗时3个RTT。

QUIC基于TLS建立连接

QUIC实现了快速握手,并把握手过程分为两种情况,分别是1-RTT和0-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),QUIC支持在单个UDP连接中复用多个流,并保证UDP报文的丢失仅影响相应的流,而不会影响其他的流(stream)。
可以在QUIC流上构建任意大小的应用程序报文,最多支持2的64次方的字节。并且stream的实现是轻量级的,即使消息报文很小也可以为它们使用单独的流。每一个Stream都有stream ID唯一标识。这些流ID由客户端/服务器进行静态分配。客户端主动发起的流的ID永远是奇数,服务器发起的流的ID是偶数。这样可以避免冲突。当在一个未使用过的流上发送数据时,流会自动创建;当需要关闭时,就会在最后一帧数据上设置一个FIN的标志指示接收方关闭流。如果发送方或接收方确定不再需要流上的数据,则可以取消流,而无需断开整个 QUIC 连接。尽管流是可靠的抽象,但 QUIC 不会为已取消的流重新传输数据。

连接迁移

QUIC连接使用随机生成的64bit的cid唯一确定。cid允许客户机在网络之间漫游,而不受网络或传输层参数变化的影响。

cid使得客户端能够独立于网络地址转换(network address translation, NAT)之外。cid 在路由中起着重要作用,特别是用于连接标识的目的。此外,使用 cids 可以通过探测连接的新路径实现多路径。
在连接迁移期间,端点假设对等方愿意在其当前地址接受数据包。因此,端点可以迁移到新的 IP 地址,而无需首先验证对等方的 IP 地址。新的路由路径可能不支持端点的当前发送速率。在这种情况下,端点需要重新构建它的拥塞控制器。另一方面,从一个新的对等地址接收非探测包 ,确认对等地址已迁移到新的 IP 地址。

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇