概要

QUIC at 10,000 feet

QUIC FAQ for Geeks

目的是用 udp + quic 取代 tcp+tls+spdy 的组合

低连接时延

避免tcp + tls多次握手认证

首次通信 1-roundtrip handshake 认证,后续可以 0 roundtrip 复用

这个时延优化效果比较给力。但复用认证也需要弄一些安全措施加固。

拥塞控制

原始数据包 与 重传数据包 采用 独立的序列号,不复用。此时能够区分原始/重传ack,避免tcp拥塞反复重传。

ack还带上收包<->发出ack包的时间,提高roundtrip测量精度。

256 NACK range,相比于 TCP的SACK,对失序/丢包的容忍度更大。

nak

sack

反正是在udp上面嘛。。。

多路复用

spdy + tcp 能支持多个流,但是当tcp丢包时,就要傻等。

quic 基于 udp,某个流的udp丢包,其他流不受影响。

这个是继承udp的好处。

前向校验

开启FEC (forward error correction)选项,一组数据包即使有部分丢包,也可以通过FEC重组(不需重传)。

FEC选项由发送方决定是否开启。

这个选项明显消耗更多资源,我觉得有没有人愿意用很难说。除非是网络质量比较差的时候再开。。。

连接迁移

以client随机生成的64 bit连接ID进行标识,而不像传统的 srcip, srcport,dstip, dstport 四元组。

client换ip也可以复用之前的connection id,不用重新起连接。

这个还是N年的老问题,ip地址某种程度上存在 身份+寻址 复合作用,这里用连接ID硬拆开些。

数据包结构

QUIC wire layout spec

包格式比较简单,没啥好说的。

Connection ID 0, 8, 32, 64 length

Sequence Number 8, 16, 32, 48 length

data packet 用的是 type + payload 结构,根据type类型解析不同payload。

传输安全

QUIC Crypto

一般用 handshake + nonce 启动连接,用于防止源地址欺骗,重放攻击。

DNS协议是典型的无连接,所以上面两个问题自作自受(这个俺同意)。

QUIC 处理源地址欺骗

server 向 client 扔一个 source address token,相当于 authenticated-encryption block ,包含client源IP、server timestamp信息

client 回头带上这个token

client与server第一次初始连接、或者client切换ip时,server要生成新token。

token 生存时间控制(这个主要是防重放)

此外还有entropy bit机制检查数据包到达率(说白了除了丢包率高,就是伪装重放):server 发包时设置一个 entropy bit,client收到后回复entropies的hash值,标识真的有收到。

求极端加速时去掉token限制,当server发现某个srcip得不到应答的数据包比率升高时,加强token限制(我觉得不太靠谱,坏蛋太多。。。)

QUIC 处理重放

TLS的connection是client/server双方握手扔nouce,确保两边都是fresh

QUIC要省时延,0-round trip 只让client直接往server扔nouce id;同时又要防重放(同一个connection不要来两次):区分连接状态 + 要求时钟同步。

server 并不是检查 client nonce 是否 unique,而是检查 client nonce 在给定的”orbit” 内是否唯一。

(client nouce, orbit) <-> server

client 缓存 server的orbit值,如果connection被route到别的server,每当server检验到orbit值不符,会重启handshake。

nounce里加上时间戳信息,还可以自然die,或者时间不对版直接重新handshake(类似于cookie时限)

已连接过的client nouce登记到 strike-register,如果回头一个connection在strike-register里,就识别为重放。

正常connection:timestamp正确,orbit正确,没在strike-register出现过 => 允许连接,更新到register

握手

QUIC server 提供静态 server config:连接参数 + Diffie-Hellman 公钥

server config 设置有效期,且以 server 私钥认证。

connection key 通过 Diffie-Hellman 交换实现: client 先用server config提供的D-H加密扔过去,server回复一个临时生成的D-H key给client(此次connection就用这个临时的)

第9页有client-server连接示意图,比较清楚(以前没连过,就inchoate,否则直接hello,server检查非重放,则返回当前连接的secure encryption,即完成rekey)

后面是字段细节,懒得看了,真用到再来查。

设计详情

QUIC Design Document and Specification Rationale

主要是设计动机,解决的问题,为啥要这样那样等等的说明。

50来页,字多图少,就随便翻了下。

感想

我觉得这个在非强安全连接需求的应用场景下,肯定可以的,前提是ISP有节操到不乱丢udp包。

此外就是把在内核实现的一些tcp连接控制有选择或者微调的在quic上实现了,优化策略主要围绕降时延。

其他相关细节主要是用connection id替代tls+tcp传统四元组标识连接,nouce之类用 srcip + timestamp + server orbit 绕开每次双向握手。

还有就是server侧存register信息,与tls双向临时nouce相比,以server的处理资源换连接时间。

注意inchoate连接server不会直接回一大堆server config信息,而是在source address token验证之后才给全。避免伪造源地址放大攻击第三方。



blog comments powered by Disqus

Published

28 April 2015

Tags