对另一位玩家的隧道地址执行 ping,与看到他托管的游戏,是两项不同的成果。大厅列表通常依赖于为单一局域网编写的发现交换,而游戏会话只是到某个地址和端口的普通连接。把空列表当作路由故障,会让你走向可能并不需要的网桥,因此在改动任何东西之前,先把这两个问题分开。

把加入会话与发现会话分开

加入失败指向路由、防火墙规则和正在监听的服务。列表为空却加入成功,则指向发现过程,或指向公告所携带的地址。这两种结果通向完全不同的工作,只有刻意尝试第一种,才能把它们区分开。

在触碰 VPN 配置之前,先把结果写下来。这是整个排查中最便宜的测试,它能排除一半的设计空间。也记下你使用的地址,因为它会成为之后每次测试的参照点。笔记里没有这一行,下一次比较就只是猜测。

在触碰隧道之前先测试直接加入

如果游戏提供直连选项,就使用主机的隧道地址和文档中给出的游戏端口,并保留游戏自身的身份验证和主机防火墙规则不动。加入成功会把问题收窄到发现环节。加入失败仍需要单独排查,任何中继都修不好它。

不要假设发现端口和会话端口是同一个数字。游戏通常在一个 UDP 端口上公告,在另一个端口上接受玩家,而为错误端口搭建的中继只会给出仍然为空的列表。

还要检查托管进程选择了哪块网卡。绑定到家庭 LAN 地址的进程会宣告那个地址,即使公告送达,远端玩家也无法路由到它。列表可能被填满,而加入仍可能仅因这一点失败。

理解广播在哪里停止

经过路由的 TUN 隧道在对等端之间传输 IP 包,并不会在每个对等端的网络上重现本地广播。受限广播地址255.255.255.255留在发出它的接口内部,而子网定向广播是另一种情况,并不是允许路由器用公告淹没网络的通用许可。

这是设计本身的属性,不是用某个选项就能补上的缺陷。OpenVPN的client-to-client设置管理隧道内部的对等端流量,并不是发现中继,尽管许多帖子恰恰为此推荐它。中继是独立组件,有自己的配置和自己的失效方式。以为现有选项已经覆盖了它,是这项排查卡住最常见的原因。

多播发现面临同样的问题,只是地址类别不同;它需要多播路由或中继,而不是广播例外。

当中继确有必要时,把它做窄

如果自动发现是硬性要求,先确认实际的交换:广播还是多播、目的地址、UDP 端口、发送它的接口,以及回复中的地址。中继若适配协议并限定在这五个事实上,范围远比扩展整个以太网段窄。

原样转发数据包仍可能不够。如果载荷让接收方去连接一个它到不了的地址,中继送回的只是无用答案,所以应当先尝试游戏自身的界面或宣告地址设置,再考虑搭任何中继。

把中继限定在真正需要的接口和对等端上,并定义回复如何找到请求方。重复无关的广播会暴露其他本地服务,并制造出日后难以调试的环路。

只有当设计确实需要以太网时才用网桥

以太网帧在 TAP 内部传输,因此 TAP 隧道可以属于有意桥接的广播域。仅仅把dev tun换成dev tap并不会建起那座网桥,不会让服务器配置变得兼容,也不会让应用去选择新接口。OpenVPN 的桥接指南讲的是更宏观的部署,而不是治一个空大厅的灵药。

桥接还会抹平地址规划,因此这个决定值得有一个超越不耐烦的理由。两个原本分开的网络变成一个,两侧的每项服务都开始看到对侧的广播。这个后果应当在任何人启用之前写进变更记录。没有规定说游戏客户端必须待在 192.168 网段;选一个不重叠的方案,并检查具体游戏的限制,而不是因为某个论坛帖子这么做就重新给隧道编址。

最后把两个结果分开看:主机能否加入,以及发现回复所宣告的目的地是否是另一位玩家真的能用的。在未确认前者的前提下修后者,正是人们最终为一个从来与广播无关的问题维护网桥的原因。

相关文章