摘要

  • DNS 的 A 与 AAAA 记录只提供候选地址,不证明某个客户端此刻可以沿相应协议族完成连接。
  • RFC 6555 把 IPv6 优先变成有限的先发优势;RFC 8305 又把流程细化为异步 DNS、RFC 6724 排序、协议族交错和有节奏的并行尝试。
  • 最先完成建立的连接只赢得当前一次选择。自动后备保护了用户,也可能把长期坏掉的网络藏在一次几乎无感的切换之后。

记录没有错,推论错了

RFC 1671 在 1994 年已经指出双栈难题:DNS 可以同时返回两类地址,却不知道客户端到其中一类地址的路径上是否存在只会丢包的旧路由器,也不知道服务端此刻是否真的在对应地址上工作。

AAAA 记录可以完全真实,IPv6 路径也可以完全不可用。DNS 描述的是“可以尝试什么”,不是“这条 SYN 一定能到”。把候选误当成可达性证明,才是长等待的起点。

传统程序顺序遍历地址。IPv6 排在前面,就先等它重传若干次,再去试本来可用的 IPv4。结果很反常:只有 IPv4 的旧客户端立即打开页面,能力更完整的双栈客户端反而停顿数秒。对用户而言,最有效的修复似乎是关掉 IPv6。过渡技术于是用自己的失败体验训练人们拒绝过渡。

另建一个 ipv6 域名会割裂人们共享的名称;白名单也无法跟随每条路径的短暂故障。真正缺少的事实只能在客户端发起连接时获得。

先发不等于独占

RFC 6555 于 2012 年把 Happy Eyeballs 写成标准轨规范。它没有宣布 IPv4、IPv6 地位相同。主机的地址策略通常仍把 IPv6 放在第一位。变化在于:第一项没有及时完成时,另一协议族可以开始尝试,而前一项仍可继续。

这把“优先”从排他命令改成了先发优势。策略决定谁先接受检验,真实运行结果决定谁承载本次连接。

竞速并非免费。额外的 SYN 会占用服务器控制块、防火墙状态、NAT 端口与链路资源。因此规范要求控制节奏,并在一个尝试成功后放弃其他尝试。如果单纯让最快的一方永远获胜,双栈主机可能持续挤占共享 IPv4 与转换设备,拖延旧基础设施缩减;如果 IPv6 拥有无限等待权,用户又会替故障承担成本。Happy Eyeballs 在两者之间设了一条可测量的边界。

失败记忆也不能成为永久判决。RFC 6555 允许客户端暂时记住某协议族失败,但要定期重试偏好协议族,文中给出约十分钟的量级;连接到新网络时还应清空状态。咖啡店里坏掉的 IPv6,不得跟随笔记本回家。

第二版把解析也纳入竞速

2017 年的 RFC 8305 取代第一版,把已经运行多年的做法整理成四个阶段:异步发起 DNS 查询、排列目的地址、异步发起连接、保留一个成功连接并取消其他项。

AAAA 与 A 查询几乎同时发出,AAAA 在先,但程序不必等两份答案都回来。如果 A 先到,建议等待 50 毫秒,给稍晚的 AAAA 一次保住 IPv6 先手的机会;时间到后,已有 IPv4 地址即可进入尝试。这个解析延迟是经验性配置,不是互联网常数。

客户端先依据 RFC 6724 排序。可用源地址、作用域、标签与本地政策共同决定更合理的先后,但排序依旧不证明路径活着。

随后,算法把协议族交错排列。如果第一项是 IPv6,最好的 IPv4 候选通常移动到第二项。这样,一个家庭有五个 AAAA 地址时,不会因为 IPv6 整体故障而连续熬过五轮超时,才让第一个 A 地址登场。

连接尝试逐个启动,却允许重叠。RFC 8305 建议缺省间隔 250 毫秒;硬性规定下一项不得在 10 毫秒内启动,建议最小值 100 毫秒、最大值两秒。历史往返时间可以修正节奏,过去用过的地址也可稍获优先,但这些记忆必须局限于当前网络接口,并在网络切换时清除。

某个尝试完成传输层握手后,其他在途尝试应被取消,尚未开始的地址也不再使用。迟到的 DNS 回答仍可短暂进入缓存,却不再改写这一连接的结果。选择完成,但它的效力只属于这一刻、这一网络。

赢得握手,不等于赢得真相

Happy Eyeballs 主要处理初始连接失败。最先建立 TCP 的地址,不保证 TLS 证书有效、HTTP 服务一致,也不保证大报文可以穿过路径。RFC 8305 特别提醒,路径 MTU 问题可能在握手之后才出现,因而逃过竞速阶段。

获胜地址也不是身份。DNS 结果会变化,同一主机名的后续连接可能选中不同地址;身份需要由真正了解服务对象的安全层证明。

它最深的副作用是可观测性。IPv6 如果每天都失败,IPv4 却在 250 毫秒后接管,普通读者只会觉得页面略有停顿。客户端修复了体验,却没有修复网络,还拿走了最响亮的报警器。RFC 8305 因此要求运营者另行监测每个协议族。

Happy Eyeballs 的历史价值不是选出胜者,而是限制偏好的权力:政策可以决定第一次实验,不能拒绝承认运行代码给出的反证。

信息源与边界

闭集来源为 RFC 1671、RFC 6555、RFC 6724 与 RFC 8305。它们证明问题、算法、建议参数和局限,不提供当前软件覆盖率、全球协议族质量排名或适用于一切网络的固定延迟。