大多数 VPN 协议默认用 UDP 承载隧道,这不是习惯,而是一个有工程依据的选择:让隧道内层的 TCP 自己处理丢包和拥塞,外层只负责尽力而为地转发。如果外层也用 TCP,两层的可靠性机制就会互相干扰。

TCP over TCP 的三个问题
重传为什么会叠加
内层 TCP 发往远端的数据在外层链路上丢包,外层 TCP 会先重传。重传需要时间,内层 TCP 在没收到确认时认为自己超时了,也开始重传。于是同一份数据被两层分别重传,流量被放大,进一步加重拥塞。
队头阻塞会带来什么影响
外层 TCP 是一条有序的字节流。一个包丢失后,后面所有已到达的数据都要等它重传成功才能交给上层,整条隧道里的所有内层连接都会被一起拖慢。UDP 外层不会这样,丢一个包只影响它所属的那一条内层连接。
两层拥塞控制为什么会互相干扰
两层都在根据丢包和延迟调节发送速率,各自的估计都会被对方的调节扭曲。表现为吞吐在某个值附近剧烈波动,延迟抽动明显。

UDP 与 TCP 隧道的对照
| 维度 | UDP 隧道 | TCP 隧道 |
|---|---|---|
| 丢包处理 | 交给内层协议处理 | 外层也会重传 |
| 队头阻塞 | 不存在 | 所有内层连接一起受影响 |
| 穿越只放行 TCP 的网络 | 可能被拦 | 通常可以通过 |
| NAT 映射保持 | 需要周期性保活 | 由 TCP 连接状态保持 |
| 高丢包链路表现 | 相对平稳 | 延迟和吞吐波动大 |
什么时候仍然需要 TCP
部分企业和校园网络只放行 TCP 80 和 443,UDP 直接丢弃。这时 TCP 隧道是唯一能用的方式。应当把它当作回退选项,而不是默认配置。
必须用 TCP 时怎么降低影响
几个实用的做法:用客户端的自动回退功能,只在 UDP 连不通时才切到 TCP;把隧道 MTU 和 MSS 设得保守一些(OpenVPN 的 mssfix 默认是 1450),避免内层包被外层再分段;把服务端放在离客户端更近的位置,缩短外层 RTT,让两层重传的等待时间尽量短。
为什么内层是 UDP 时问题小得多
内层是 UDP 或 QUIC 时,内层自己不重传或重传策略不同,重传叠加的不利影响不改变防火墙环境下整体延迟的特性,但队头阻塞仍然存在。这也是基于 QUIC 的隧道方案值得关注的原因。




