• 新一代互联网传输协议QUIC


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

        QUIC的主要特点包括:具有SPDY(SPDY是谷歌研制的提升HTTP速度的协议,是HTTP/2.0的基础)所有的优点;0-RTT连接;减少丢包;前向纠错,减少重传时延;自适应拥塞控制, 减少重新连接;相当于TLS加密。

    1.重传与恢复

         与TCP类似,QUIC每发送一个包后,都会等待回复一个确认包。当丢包率超过协议的纠错门限时,会显式或隐式地进行重传

        对于某些重要的数据包,如初始密钥协商时的数据包,在建立连接时非常重要,如果这类包丢失会阻塞整体数据流。QUIC对于这一类数据包在确认发生丢失前就会尝试重传,通常是等待较短的时间(如20ms)没收到确认后就马上再次发送。这样在网络中会有若干个相同的包同时传输,只要有一个能成功抵达就完成了连接,这样降低了丢包率。接收方对于关键数据包的多次发送和普通数据包的超时重传,都采用相同的重复包处理机制

         QUIC在拥塞避免算法的基础上还加入了心跳包,用于减少丢包率

         QUIC使用了FEC(前向纠错码)来恢复数据,FEC采用简单异或的方式。每次发送一组数据,包括若干个数据包后,并对这些数据包依次作异或运算,最后的结果作为一个FEC包再发送出去。接收方收到一组数据后,根据数据包和FEC包即可以进行校验和纠错。

        2.安全性

        QUIC对每个散装的UDP包都进行了加密和认证的保护,并且避免使用前向依赖的处理方法(如CBC模式),这样每个UDP包可以独立地根据IV进行加密或认证处理。

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

        3. 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协议原理
    1,0RTT 建连

     先声明一点,如果一对使用QUIC进行加密通信的双方此前从来没有通信过,0RTT是不可能的。

    所以第一次C和S建连还是会走正常的tls握手流程,但过了一会儿或者一段时间后,C又想和S通信,此时C已经有了刚刚和S协商出来的密钥(可能是存在内存or外存)。C就会利用刚刚的密钥K1来和S加密首次数据,在第二个RTT期间,S会和C协商出新的密钥K2,作为接下来的通信密钥。

    2,没有歧义的重传
    TCP 重传的 包 的 sequence number 和原始的 包 的 Sequence Number 是保持不变的,也正是由于这个特性,引入了 Tcp 重传的歧义问题。

     超时事件 RTO 发生后,客户端发起重传,然后接收到了 Ack 数据。由于Sequence Number一样,这个 Ack 到底是原始请求的响应还是重传请求的响应呢?这就间接导致了RTT计算的歧义。

    Quic 使用 Packet Number 代替了 TCP 的 sequence number,并且每个 Packet Number 都严格递增,也就是说就算 Packet N 丢失了,重传的 Packet N 的 Packet Number 已经不是 N,而是一个比 N 大的值,这就解决了RTT计算的歧义问题。

    3,保证包的顺序
    QUIC 引入了一个叫 Stream Offset 的概念。

    假设 Packet N 丢失了,发起重传,重传的 Packet Number 是 N+2,但是它的 Stream 的 Offset 依然是 x,这样就算 Packet N + 2 是后到的,依然可以将 Stream x 和 Stream x+y 按照顺序组织起来。

    4,解决ack delay

    TCP 的 RTT 计算:

    Quic的RTT计算:


    5,队头阻塞
    拿http2举例,

    http2 在一个 TCP 连接上同时发送 4 个 请求。其中 请求1 已经正确到达,并被应用层读取。但是 请求2 的第三个 tcp包丢失了,为了保证数据的顺序,需要发送端重传第 3 个包才能通知应用层读取接下去的数据,虽然这个时候 请求3 和 请求4 的全部数据已经到达了接收端,但都被阻塞住了。

    Quic基于UDP,各个请求之间相互独立,比如 请求2 丢了一个 Pakcet,不会影响 请求3 和 请求4,不存在 TCP 队头阻塞。

    四,Quic和http3
    QUIC 协议最初是由Google发起的项目,后面慢慢成为了 HTTP/2-encrypted-over-UDP 协议。
    当 IETF 开始进行协议标准化工作时,协议被分为两层:传输部分和 HTTP 部分。这个想法的初衷是考虑到该传输协议也可用于传输其他数据,而不仅仅用于 HTTP 协议。
    社区中大家使用 iQUIC 和 gQUIC 这样的非正式名称来引用这些不同版本的协议,以便将IETF 和 Google提出的QUIC 协议分开。
    通过 iQUIC 发送 HTTP 请求的协议被称为HTTP-over-QUIC,即HTTP3。

    例子:
    https://www.cnblogs.com/jb2011/p/8458549.html

    参考资料
    下一代通信协议:Quic
    https://knownsec-fed.com/2018-01-19-xia-yi-dai-tong-xin-xie-yi-quic/
    QUIC协议是如何做到0RTT加密传输的
    https://blog.csdn.net/dog250/article/details/80935534
    Web服务器快速启用QUIC协议
    https://my.oschina.net/u/347901/blog/1647385
    QUIC协议原理分析
    https://zhuanlan.zhihu.com/p/32553477
    QUIC在腾讯的实践及性能优化
    https://zhuanlan.zhihu.com/p/32560981
    七牛云 QUIC 推流方案如何实现直播 0 卡顿
    https://zhuanlan.zhihu.com/p/33698793
    当我们在讨论http队头阻塞时,我们在讨论什么?
    https://liudanking.com/arch/what-is-head-of-line-blocking-http2-quic/
    QUIC官方文档
    https://www.chromium.org/quic
    QUIC协议规范

    https://www.wolfcstech.com/2017/01/13/QUIC%E5%8D%8F%E8%AE%AE%E8%A7%84%E8%8C%83/

  • 相关阅读:
    Repeater 双向排序
    将具有固定格式的text 类型中的数据分离出来的一种方法
    ASP.NET 快速构建应用程序页面主框架
    2分分页处理存储过程通用存储过程
    C#3.0之匿名类型
    常用的js收集
    用CSS实现DataGird滚动而表头不动
    Lucene.Net 创建索引和检索
    Lucene.net 实现全文搜索
    SQL 中操作日期的几个函数
  • 原文地址:https://www.cnblogs.com/klb561/p/11871549.html
Copyright © 2020-2023  润新知