当前位置:   article > 正文

QUIC传输协议设计_quic视频分段传输

quic视频分段传输

原文

概要

我们提出QUIC,一种加密的多路复用且低延迟的传输协议,全面提升Https流量的传输性能,实现传输机制的快速部署和持续发展。QUIC在谷歌已经被全面的部署在数千台服务器上,涉及的客户端包括广泛使用的浏览器chrome以及一些视频流式应用TouTube.我们估计当今互联网的流量有7%使用了QUIC。本文描述了我们发展这种传输协议的动力、指导我们的设计原则、在互联网上进行的QUIC的性能表现的迭代试验、我们各种服务的性能改进以及我们全球部署的经验。我们还分享传输协议设计和我们从部署中学到的互联网生态的经验。

介绍

QUIC,一种用以提升HTTPS性能表现、实现快速部署和持续迭代的新的传输机制,QUIC代替最传统的HTTPS栈:HTTP/2、TLS、TCP。QUIC作为一种用户空间的传输,底层使用UDP协议。

在用户空间构建QUIC使得其作为应用的一部分可以在应用升级过程中进行迭代。

QUIC是加密的传输,数据包是需要认证的和加密的,防止修改,允许UDP包经过中间件。QUIC使用加密的握手协议,通过在大多数已知服务器证书的重复连接情况下以及在网络栈的多个层移出冗余的握手来减少握手延迟。

QUIC通过使用轻量级数据结构–流,消除了线头阻塞延迟,流在单个连接中被多路复用,因此丢失单个数据包只会阻塞包含该数据包中的数据的流。

QUIC与传统HTTPS协议栈

动机

  1. 协议僵化:中间件是互联网的一个组成部分,比如防火墙会拦截任何它任务不安全的内容,地址转换协议NATS会转写传输头,让这些中间件支持新协议很难实现。另外,有一些信息,比如TCP 的Header,可以被中间件修改。结论是:由于与中间件有关联,导致修改很难。
  2. 实现僵化:TCP是操作系统内核实现的,即使修改TCP,推动TCP协议栈改动需要升级操作系统,很难。
  3. 握手延迟:TCP、TSL的通用性很好的持续服务这互联网的发展,但随着HTTPS协议栈延时的增加,分层的开销也越来越明显。在发送任何应用程序数据之前,TCP通常会导致1RTT的延迟,TSL会增加2RTT的延迟,网络带宽的增加,但光速保持不变,互联网上大部分连接和web的大多数事务都是短连接,最受不必要的握手连接的影响。
  4. 队头阻塞延迟(Head-of-line Blocking delay)(HOL)为减少多路复用延迟和开销,HTTP1.1建议限制客户端对server的初始连接数。为了进一步减少事务延时,HTTP2多路复用多个对象,推荐用对一个server用一个TCP连接。

设计和实现

QUIC的目标是:可部署、安全、减少握手延迟、解决队头阻塞。QUIC将加密和握手结合来减少RTT,它在一个连接上多路复用多个请求/响应,为每个请求提供自己的流,这样就不会有响应被其他流阻塞。

它对数据包进行加密和身份验证以避免中间人篡改,并限制协议僵化。它使用唯一的数据包编号来避免重传歧义,并通过再ACKs中使用显式信号来进行精确的RTT测量,从而提高丢包恢复。

通过使用连接ID标识连接而不是ip:port,它允许连接夸ip地址更改迁移。提供流控制来限制慢速接收方缓冲区中的数据,并通过使用每个流的控制限制来确保单个流不会消耗接收方的所有缓冲区。

我们的协议实现提供了一个拥塞控制模块接口,用于实验各种控制器,我们的客户端和服务器在没有额外延迟的情况下协商协议。

连接建立

建立连接

QUIC通过加密和握手的合并来建立安全连接,成功建立连接后,客户端缓存服务器的信息(一系列的URI、hostName、port),下一个对同一主机的连接,客户端可以在0RTT下建立安全连接,数据可以随着握手信息直接发生给服务器。QUIC使用专用的可靠的加密流实现握手。

初始握手

最初,客户端没有服务器的任何信息,在握手之前,客户端发送一个早期的client hello (CHLO)给服务器,得到一个拒绝message,REJ消息包括:服务器的配置(服务器长期有效的DH公钥、服务器的证书链、服务器的签名、source-address token: 加密的身份认证的块,包含客户端的ip、服务器端的一个时间戳)。客户端在握手阶段发送这个token给服务器,阐述其ip地址的所有权。一旦客户端收到服务器的配置信息,它就验证证书链和签名,之后发送CHLO,包含客户端临时的D_H公钥。

最后的握手/重复的握手

连接的所有键是来自DH参数。发送complete CHLO后,客户端拥有初始键值,因为客户端有自己的临时DH参数,可以通过服务器长期有效的DH参数计算共享的秘钥。自此,客户端可以发送数据。如果客户端想要实现0RTT延迟发送数据,必须在服务器应答前发送使用初始的key加密的信息。
如果握手成功,服务器返回server hello (SHLO),该消息是用初始秘钥加密的,且包含服务器的临时DH公钥,当双方有了临时参数对,可以计算前向安全的秘钥,在发送SHLO时,服务器立马切换到发送前向安全秘钥加密的数据包,在收到SHLO后,客户端切换成用前向加密秘钥加密数据包。
因此,QUIC的加密提供了两种级别的安全:初始客户端数据使用初始秘钥加密的,后续客户端数据和所有服务端数据是用前向秘钥加密的(处理SHLO)。初始秘钥提供保护类似于TSL使用sessionTicket进行session恢复。前向安全的keys是临时的,提供更强的保护。
客户端缓存服务器的配置信息和source-address token,当有请求来时,使用这些参数进行连接,发送complete CHLO,如图4,客户端发送初始秘钥加密的数据不需要等服务端数据返回。
最后,source-address token 或者服务器配置可能过期,或者服务器证书变了,导致握手失败,即使客户端发送了complete CHLO。这种情况下,服务器会放回REJ消息,就如同服务器收到了Inchoate CHLO。

版本协商

客户端和服务器版本协商在连接建立的期间,避免不必要的延迟。QUIC客户端在连接的第一个包中提出一个用于连接的版本,并使用建议的版本对握手的其余部分进行编码。如果服务器不使用客户端选择的版本,它将通过向客户端发送所有服务器支持版本来强制进行版本协商,从而导致建立连接之前的往返延迟。在服务端同意客户端的选择的情况下,该机制消除了RTT延迟,并且鼓励服务器要部署新版本,不要低于客户端版本。为防止降级攻击,在生成最后秘钥时,客户端初始请求版本和服务器支持的版本列表被嵌入客户端和服务器的key生成函数。

复用流

应用程序通常在一个数据流上复用数据单元,为了避免HOL阻塞,QUIC支持在一个连接上复用多个流,确保丢失一个UDP的包只会影响该数据包对应的流,其他流上的序列可以继续传输,并组装数据交个应用程序。
QUIC流是一个轻量级的抽象,它提供了一个可靠的双向字节流。流可用于在单个流上传输大小为2^64字节的任意应用程序消息,但它们足够轻,当发送一系列小消息时,可以合理地为每个消息使用一个新流。流由流id标识,为客户端启动的流静态分配奇数id,为服务器启动的流静态分配偶数id,以避免冲突。当结束尚未使用的流上的第一个字节时,流创建是隐式的,流关闭通过在最后一个流帧上设置一个“FIN”位来指示对等方。如果发送方或接收方确定流上的数据不再需要,则可以取消流,而不必关闭整个QUIC连接。尽管流是可靠的抽象,QUIC不会为已取消的流重新传输数据。
一个QUIC包由一个公共报头和一个或多个帧组成,如图5所示。QUIC流复用是通过将流数据封装在一个或多个流帧中来实现的,并且单个QUIC包可以携带来自多个流的流帧。
QUIC端点发送数据的速度总是有限的(见章节3.5和3.6)。端点必须决定如何在多个流之间分配可用带宽。在我们的实现中,QUIC仅仅依赖于HTTP/2流优先级[8]来调度写操作。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-E2wKxNCg-1601373028571)(1CCAAE7A49E6493884177512E7E38845)]

认证和加密

除了一些早期握手包和重置包之外,QUIC包是完全认证的,而且大部分是加密的。图5说明了QUIC数据包的结构。QUIC包头不在加密范围内,需要路由或解密包:标志,连接ID,版本号,多样化的Nonce,和包号码。标记对连接id字段和包号字段长度进行编码,且需要对后续字段可见。连接id用于路由和识别目的。负载平衡器使用它将连接的流量定向到正确的服务器,服务器使用它定位连接状态。收发双方使用包好作为每个包的nonce,用于对包认证和解密。包号不加密,用以支持包解密的无序接收。
有些信息在握手包中不加密,比如版本协商包,包含在最终连接键的生成中。对这些握手包的网络内篡改会导致最终的连接密钥在对等点上不同,导致连接最终失败,而任何一个对等点都无法成功解密任何应用程序数据。重置包有一个没有连接状态的服务器发送,在路由改变和服务器重启时可能发生。最终导致服务器没有连接秘钥,所以重置包未进行认证和加密。

丢失重传

TCP序列号促进了可靠性,并表示字节在接收方被交付的顺序。这种合并导致了“重传歧义”问题,因为重传的TCP段与原始数据包具有相同的序列号[39,64]。TCP ACK的接收者不能确定ACK是为原始传输还是为重传而发送的,重传段的丢失通常通过昂贵的超时来检测。每个QUIC包携带一个新的包号,包括携带重传数据的包号。这种设计避免了需要一个单独的机制来区分一个重传的ACK和一个原始传输的ACK,从而避免了TCP的重传歧义问题。流帧中的流偏移量用于发送顺序,分离TCP合并的两个函数。数据包编号表示一个显式的时间顺序,这使得比TCP更简单和更准确的丢失检测。
QUIC编码一个包和其确认包的延迟。结合单调递增的包顺序,可以精确的估计网络RTT,这有助于检测丢包。准确的RTT估计可以帮助延迟感知拥塞控制,如BBR和PCC[16].QUIC的应答支持多达256个ACK块,使QUIC比使用SACK[46]的TCP更能适应重新排序和丢失。因此,QUIC可以在重新排序或丢失的情况下保留更多的字节。QUIC和TCP之间的这些差异允许我们构建更简单和更有效的QUIC机制。

流控

当应用程序从QUIC的接收缓冲区缓慢读取数据时,流控制会限制接收方必须维护的缓冲区大小。缓慢耗尽的流可能会消耗整个连接的接收缓冲区,从而阻塞发送方在其他流上发送的数据。QUIC通过限制单个流可以消耗的缓冲区,改善了这种流之间潜在的线头阻塞。因此QUIC采用了连接级流控,限制了发送方跨所有流在接收方使用的聚合缓冲区,以及流级别的流控,限制发送方可以在任何给定流上消耗的缓冲区大小。
与HTTP/2类似,QUIC使用基于信用的流控,QUIC接收器在每个流中声明它愿意接收数据的绝对字节偏移量,当数据在特定流上发送、接收和交付时,接收方会定时发送窗口帧,增加该流所公布的偏移限制,从而运行双方发送更多的数据。连接级别流控的工作方式与流级别控制相同,但交付的字节和接收到的最高偏移量是跨所有流聚合的。我们的实现使用了一个比流级窗口大得多的连接级窗口,以允许多个并发流进行处理。我们的实现还使用流控制窗口自动调优,类似于常见的TCP实现(详细信息请参阅[1])。

拥塞控制

QUIC协议没有拥塞控制算法,我们实现了一个可插拔的接口来进行试验。在我们的部署中,TCP和QUIC都使用Cubic[26]作为拥塞控制器

NAT重新绑定和连接迁移

QUIC的连接有一个64位的连接id表示。QUIC的连接id是链接在客户端ip或端口改变后仍能存活,这种变化可能是有NAT超时和重新绑定引起的(UDP比TCP更易发生),或者客户端更改了一个ip。
虽然QUIC端点通过使用连接ID来识别连接,简单地省略了NAT重新绑定的问题,但客户端发起的连接迁移仍在进行中,目前部署有限。

QUIC Discovery for HTTPS

客户端不知道给定的服务器是否支持QUIC,所以发生HTTP请求,它通过TSL、TCP发送,当服务器支持QUIC,则返回一个包含Alt-Svc头的Response,此标头告诉客户端可以使用QUIC连接。在随后对用一源的Http请求中,竞争发送QUIC和TLS/TCP连接,但后者最多延迟300ms,无论哪个连接先建立成功,最终都会被用于该请求。如果QUIC被阻挡在路径上,或QUIC握手包大于路径的MTU,则QUIC握手失败,客户端使用TLS/TCP连接。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/626345
推荐阅读
相关标签
  

闽ICP备14008679号