以下内容转载自: https://github.com/y123456yz/reading-and-annotate-quic
client和server协商过程:
1. 客户端发送CHLO到服务端
2. 服务端回送的REJ信息给客户端,同时携带上原地址标识信息和服务端证书信息
3. 客户端再次发送CHLO到服务端
拥塞控制:
QUIC参考TCP的CUBIC拥塞控制算法,并在试探尝试其他拥塞控制算法
试探尝试新的拥塞控制算法:例如每个数据包的转发(包括原始数据包和重传包)都携带一个新的sequece序列化,这样可以避免TCP的重传模糊问题
QUIC-ACK会携带上接收数据包的时间以及发送ack的时间,这样有利于计算往返时延
QUIC-ACK相比TCP的SACK,跟容易实现包的重组,当有包丢失或者
FEC
通过FEC可以从一组FEC报文组中恢复网络传输中丢失的数据包,具体优化方案由发送端决定
连接复用
QUIC连接通过一个64位的连接标识符标识,该标识符由客户端产生。
QUIC的连接建立将版本协商与加密和传输握手交织在一起以减少连接建立延迟。我们将在下面首先描述版本协商。
连接建立延迟
灵活的拥塞控制
多路复用而不存在队首阻塞
认证和加密的首部和载荷
流和连接的流量控制
连接迁移
QUIC采用了两级密钥机制:初始密钥和会话密钥。初次连接时不加密,并协商初始密钥。初始密钥协商完毕后会
马上再协商会话密钥,这样可以保证密钥的前向安全性,之后可以在通信的过程中就实现对密钥的更新。接收方意
识到有新的密钥要更新时,会尝试用新旧两种密钥对数据进行解密,直到成功才会正式更新密钥,否则会一直保留
旧密钥有效。
QUIC在握手过程中使用Diffie-Hellman算法协商初始密钥,初始密钥依赖于服务器存储的一组配置参数,该参数
会周期性的更新。初始密钥协商成功后,服务器会提供一个临时随机数,双方根据这个数再生成会话密钥。
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握手过程完毕。之后会话密钥更新的流程与以上过程类似,只是数据包中的某些字段略有不同。
QUIC包含三种报文包类型:
协商Package、公用复位package、普通帧信息Package
Version Negotiation Packets and Public Reset Packets, and regular packets containing frames.
如果客户端的版本不被服务器接受,则将导致1-RTT的延迟。服务器将发送一个版本协商包给客户端。这个包将设置版本标记,并将包含服务器支持的版本的集合。
当客户端从服务器收到一个版本协商包,它将选择一个可接受的协议版本并使用这个版本重发所有包。
为了避免流ID冲突,流 ID 必须是偶数,如果流是由服务器初始化的话,如果流由客户端初始化则必须为奇数。
0不是一个有效的流 ID。流 1 被保留用来加密握手,它应该是第一个客户端初始化的流。当基于QUIC使用HTTP/2时,
流 3 被保留来为其它流传输压缩的首部,以确保首部的处理和传送可靠且有序。
各种帧格式参考:QUICWireLayoutSpecification.pdf
官方参考地址:https://www.chromium.org/quic
转载自: https://github.com/y123456yz/reading-and-annotate-quic