QUIC

QUIC(Quick UDP Internet Connections,快速UDP互联网连接)是Google提出的一种基于UDP改进的通信协议,其目的是降低网络通信的延迟,提供更好的用户互动体验。

QUIC协议的主要目的,是为了整合TCP协议的可靠性和UDP协议的速度和效率。

QUIC的位置

QUIC底层通过UDP协议替代了TCP,上层只需要一层用于和远程服务器交互的HTTP/2 API。这是因为QUIC协议已经包含了多路复用和连接管理,HTTP API只需要完成HTTP协议的解析即可。

QUIC特性

避免前序包阻塞

SPDY和HTTP/2协议现在都支持将页面的多个数据(如图片、js等)通过一个数据链接进行传输。该特性能够加快页面组件的传输速度,但是对于TCP协议来说,这会遇到前序包阻塞的问题。这是由于TCP协议在处理包时是有严格顺序的,当其中一个数据包遇到问题,TCP连接需要等待这个包完成重传之后才能继续进行。因此,即使逻辑上一个TCP连接上并行的在进行多路数据传输,其他毫无关联的数据也会因此阻塞。

QUIC协议直接通过底层使用UDP协议天然的避免了该问题。由于UDP协议没有严格的顺序,当一个数据包遇到问题需要重传时,只会影响该数据包对应的资源,其他独立的资源(如其他css、js文件)不会受到影响。

减少数据包

QUIC协议在创建连接握手时,只需要1到2个数据包即可。

这在移动网络上,效果是很明显的,移动网络的延时通常在100ms+上。

向前纠错

QUIC协议有一个非常独特的特性,称为向前纠错(Forward Error Correction),每个数据包除了它本身的内容之外,还包括了部分其他数据包的数据,因此少量的丢包可以通过其他包的冗余数据直接组装而无需重传。

目前默认的冗余量是10%,既每发送10个数据包,其冗余数据就可以重新构建一个丢失的数据包。

向前纠错牺牲了每个数据包可以发送数据的上限,但是减少了因为丢包导致的数据重传,因为数据重传将会消耗更多的时间(包括确认数据包丢失、请求重传、等待新数据包等步骤的时间消耗)。

安全性

QUIC采用了两级密钥机制:初始密钥和会话密钥。初次连接时不加密,并协商初始密钥。初始密钥协商完毕后会马上再协商会话密钥,这样可以保证密钥的前向安全性,之后可以在通信的过程中就实现对密钥的更新。接收方意识到有新的密钥要更新时,会尝试用新旧两种密钥对数据进行解密,直到成功才会正式更新密钥,否则会一直保留旧密钥有效。

0-RTT握手过程

QUIC握手的过程是需要一次数据交互,0-RTT时延即可完成握手过程中的密钥协商,比TLS相比效率提高了5倍,且具有更高的安全性。

QUIC在握手过程中使用Diffie-Hellman算法协商初始密钥,初始密钥依赖于服务器存储的一组配置参数,该参数会周期性的更新。初始密钥协商成功后,服务器会提供一个临时随机数,双方根据这个数再生成会话密钥。

具体握手过程如下:

  1. 客户端判断本地是否已有服务器的全部配置参数,如果有则直接跳转到(5),否则继续
  2. 客户端向服务器发送inchoate client hello(CHLO)消息,请求服务器传输配置参数
  3. 服务器收到CHLO,回复rejection(REJ)消息,其中包含服务器的部分配置参数
  4. 客户端收到REJ,提取并存储服务器配置参数,跳回到(1)
  5. 客户端向服务器发送full client hello消息,开始正式握手,消息中包括客户端选择的公开数。此时客户端根据获取的服务器配置参数和自己选择的公开数,可以计算出初始密钥。
  6. 服务器收到full client hello,如果不同意连接就回复REJ,同(3);如果同意连接,根据客户端的公开数计算出初始密钥,回复server hello(SHLO)消息,SHLO用初始密钥加密,并且其中包含服务器选择的一个临时公开数。
  7. 客户端收到服务器的回复,如果是REJ则情况同(4);如果是SHLO,则尝试用初始密钥解密,提取出临时公开数
  8. 客户端和服务器根据临时公开数和初始密钥,各自基于SHA-256算法推导出会话密钥
  9. 双方更换为使用会话密钥通信,初始密钥此时已无用,QUIC握手过程完毕。

results matching ""

    No results matching ""