Skip to main content

基于 QUIC 的代理协议

· 6 min read
UIF Official

QUIC 简介

QUIC 是基于 UDP 的传输层协议,减少了建立链接所需的 RTT,解决了多路复用所带来的问题。基于 QUIC 的 HTTP 已经被标准委员会接收成为 HTTP3

在可预见的未来,HTTP3 将会被广泛使用。目前,谷歌全系产品已支持 QUIC。

多路复用所带来的问题

HTTP2是基于 TCP 复用的,虽然可以减少建立链接的延迟,但是传输效率不高,主要的原因是队头阻塞,也就是 A 必须要先于 B,如果即使 B 先到达了目标网络,A 丢失了需要重传,B 也必须要等待 A,即使 B 已经成功被接收了。

队头阻塞 不单单是 TCP 的原因,也有 TLS 的原因。因为 TLS 也有保证正确接收顺序的功能。所以,想要彻底解决这个问题,QUIC 必须要结合 TLS。

基于 UDP 的 QUIC

基于 UDP 是必然的选择,因为我们不可能网络层重新设计一个传输层协议,这样做的成本是巨大的;参考 IPv6,不兼用带来的成本使得设备产商和使用不积极推广更加先进的协议。

可能有人会疑虑:

UDP 会被运营商 QOS,俗称限速。这样会导致 QUIC 的带宽性能不佳。

我们认为 UDP 传输质量不佳,大概率是因为运营商对 UDP NAT 支持不佳导致的。使用 UDP 并不能突破运营商对网络带宽的限制。

参考这篇文章 #776,其中提到:

这种现象很明显,比如你刚开始测试 kcptun 开启的一段时间,速度是挺快,但是挂久了,就变得非常慢,这时候,只需要释放掉隧道,重新发起新隧道即可

因为 NAT 的原因,QUIC 也有心跳包的设计,用于维护 UDP session,保持路由器能够正确地转发。但是有些路由器可能图省事,一定时间后无论是否活跃都会直接关闭;这样一来,即节省了带宽内存,又不违反 UDP 协议。

一旦随着 HTTP3 的广泛应用,在激烈的竞争环境下,所谓有 QOS 的运营商会被消费者淘汰。

QUIC 的多路复用

QUIC 在用户层 管理链接(Connection) 和实现拥塞控制。并且使用 Connection ID 来标记每一条链接,不再使用传统的 IP 四元组,也就是说 QUIC 的链接是 IP 无关的。

无论客户端走到哪里,只要有 Connection ID,就可以被服务端识别到。在移动的网络环境中,这样做有巨大好处,例如乘坐汽车、高铁等交通工具时,即使不断更换网络(IP),也无需重新与服务器建立链接后再传输数据。

与 TLS 安全协议高度集成

QUIC 是强制使用 TLS 的。

上文提到,TLS 也有队头阻塞的问题。为了解决这个问题,QUIC 修改了 TLS 协议,仅使用由 TLS 协商出的秘钥,由 QUIC 来保证传输顺序正确,也就是 TLS 仅在握手阶段被使用到。

代理协议

像 HTTP 和 Sock5 等基于传输层的代理协议,根据网络协议的制定原则,他们是不会规定传输的具体内容的,也就是说可以根据用户的意愿自由替换使用传输层。

一个较早实现基于 QUIC 的代理工具有 v2ray,他可搭配各种传输层+代理层的组合。

UDP 的传输

需要传输 UDP 数据的场景,一般都是 VPN 所需要的。他们会截获操作系统的所有流量(包括 DNS),然后传输到代理服务器。

在此之前,我们一般把 UDP 数据放在传输层中,也就是 UDP over TCP。 在 QUIC 中也是可以大同小异,UDP over QUIC。

但是有一个问题,假如这个 UDP 是 QUIC,即 QUIC over QUIC,传输层再加上一个传输层,这又会造成本来我们要解决的 队头阻塞。因此,在代理社区中,一般建议用户禁用 443 UDP 端口,来规避这个问题。

终极解决方案

QUIC 还设计了 UDP 传输模式,也就是说使用该模式传输的数据,将与正常 UDP 传输数据无异(加密除外)。从理论上来说,UDP over UDP 就是终极解决方案。

比如说 TUIC 就是基于 QUIC 的代理协议。拥有 QUIC 的优点:超低的延迟、完全的多路复用、UDP 代理(目前已被删库,请使用 Hysteria2 代替)。


UIF 支持使用 Hysteria2,欢迎大家使用。