记 QUIC 的折腾记录

jsq2627 · 4 天前 · 104 次点击

家里一直是路由器翻墙,以前一直是屏蔽 443 端口 UDP 流量,也就是禁用 QUIC ,这也是大多数人的做法。最近我尝试放行 QUIC 流量,想看看现在体验到底怎样了。

测试环境

首先,先保证自己到梯子的网络稳定。我是自建服务器,iperf3 UDP 打流,100Mbps 下 0 丢包,500Mbps 下 10% 以下丢包。TCP 打流,可以跑满千兆带宽,只触发少量重传。RTT 大约 20ms 。

UDP 大速率下的丢包还是比 TCP 严重很多。

服务器软件 sing-box ,路由器是 mihomo 。ss 协议,非 UDP over TCP 。

感受

在路由器上放行 QUIC 流量后,立马感受到 Google / YouTube / FSHEX 的 "冷访问" 明显丝滑很多。很明显能感受到 0-RTT 带来的好处。

观察到自己日常大多数 QUIC 流量属于 Google 系和套了 Cloudflare 的网站。Google 系的 QUIC 覆盖率很高,除了 Google 自家,很多用了 GCP 的网站、app 也都有很好的 QUIC 支持。Facebook 基本也做到了全站 QUIC 覆盖。iCloud 下的少数域名也支持 QUIC 。iCloud 照片图库的数据分散于 AWS/GCP/Azure 等多地数据中心,其中从 GCP 同步照片、视频时,也可以触发 QUIC 。

下载大文件时,QUIC 的极限速率比不上 TCP 。但是对于浏览网页看视频,也已经够用。0-RTT 体感很明显。YouTube 拖进度条,响应非常快。

问题

接下来开始说问题。

第一个问题,如果非自建梯子,而是用机场,那么 UDP 的链路质量可能会更差,即便机场是各种专线中转。原因可能有很多,比如机场国内所在机房的 UDP QoS (为了防 DDoS ,国内机房针对 UDP 会有各种奇怪策略),或者机场服务器 CPU 高负载。但是我觉得如果能做到 200-300Mbps 下低丢包,就够用。

第二个问题,Safari 和 Chrome 对 HTTP/3 的使用策略不一样。

Chrome 会看网站的 Alt-Svc header ,如果有 h3 ,那么会很积极地使用 HTTP/3 。大多数适配 HTTP/3 的网站都会带有 Alt-Svc ,因此在 Chrome 下不会遇到太多问题。

Safari ,以及苹果平台上所有基于 NSURLSession 的应用(包括 macOS/iOS 等),对 Alt-Svc 的使用不会很积极,而是对 DNS HTTPS RR 的使用更积极。 所以发现除了 Google / Cloudflare 之外的大多数网站,在 Safari 下并不能触发 QUIC ,因为大多数没有设置 HTTPS RR 。

第三个问题,各种 QUIC 实现对 NAT rebinding 的支持程度不一致。

QUIC 的一大特性是,使用双方协商的 Connection ID 来识别连接唯一性,而不是 TCP/UDP 的四元组。意味着当客户端一方的 IP 或端口变化后,只要 Connection ID 保持不变,双方还能继续使用之前建立的 connection 。这个特性对于处于 NAT 后的客户端很重要,因为在不发送心跳的情况下,NAT 对 UDP 的端口映射只会保持很短时间;客户端可能由于 NAT 要经常变化端口。

而翻墙时,至少要经过两层 NAT:路由器软件一层,服务器软件一层。查看代码实现,发现 mihomo 的 UDP NAT 保持时间是 60s 且不可配置,sing-box 默认是 300s ,可以配置。此外中间可能还会有其他 NAT ,比如运营商 NAT ,机场国内中转 NAT 。最终有效的 UDP NAT 保持时间可能非常小。

所以我们很依赖 QUIC 对 NAT rebinding 的支持,来保证对连接的复用。

事实上我发现只有 Google 对 NAT rebinding 做了完整的支持。占据 QUIC 流量半壁江上的 Cloudflare 并不支持

在使用 Chrome 时,这个问题并不凸显,因为 Chrome 对 QUIC 连接超时判断很迅速。用 Chrome 打开一个 HTTP/3 域名下图片(比如这个],等待 NAT 映射过期之后(等待时间要少于 QUIC 服务端配置的 idle timeout ,Cloudflare 是三分钟),重新刷新页面,Chrome 大概只用很短的几百 ms 就完成了超时判断,重新用新端口发起新 QUIC 连接。因为这几百 ms ,体感上对比平时的 0-RTT 就会感觉稍慢,不注意其实很难察觉。

在使用 Safari 时,这个问题是个灾难,同时影响 macOS 和 iOS 。Safari 对 QUIC 超时判断逻辑是固定等待 15 秒左右,NAT 过期后刷新网页,页面会卡 15 秒白屏,然后才会发起新连接。平时我在用 Safari 刷 FSHEX 时,等一段时间不操作后,经常卡住白屏十几秒,后续又非常流畅,就是这个问题。

结论

经过这几天一通折腾,我最终还是选择禁用 QUIC 。并且打消了我在任何自己参与研发的产品上启用 HTTP/3 或 QUIC 的想法。

举报· 104 次点击
登录 注册 站外分享
快来抢沙发
0 条回复  
返回顶部