你把启动器加入排除列表,下载速度从慢变快,比赛却仍然落在远端服务器上。什么都没坏。启动器和游戏是两个进程,各自拥有一组套接字,排除其中一个并不能说明另一个。下载变快是因为下载本来就是启动器的流量;比赛是别人的连接,由你的规则从未见过的可执行文件打开。

一个安装器,多个进程

现代游戏软件像一个小星座。有负责登录的客户端,有拉取内容的更新器,有启动游戏的启动器,还有游戏可执行文件本身,它可能为反作弊或匹配覆盖层再生成一个进程。它们每一个都可能保持通往各自目标的连接。

排除规则通常只点名其中一个。点的是哪一个,完全取决于 VPN 客户端支持的标识符,而这正是用户很少检查的部分。有些客户端匹配可执行文件路径,有些匹配包或 bundle 标识符,还有些匹配两个无关二进制文件都可能使用的进程名。先读规则,再看进程列表,因为规则限制了你甚至能表达什么。

所以症状不是「分流隧道坏了」,而是「规则覆盖的进程并不是承载我在乎的流量的那个进程」,这句话狭窄得多,也好修得多。一旦这样说,问题就变小了。下一步也不再是猜。

找到拥有比赛连接的那个进程

启动游戏,进入一场比赛,然后看谁拥有套接字,而不是看屏幕上显示什么。在 Windows 上,进程列表加逐进程套接字查询,两条命令就能回答:

Get-Process | Where-Object { $_.ProcessName -match 'launcher|game|client' } | Select-Object Id,ProcessName,Path
Get-NetTCPConnection -State Established | Select-Object OwningProcess,RemoteAddress,RemotePort | Sort-Object OwningProcess

第二条命令打印的是进程 ID,不是名称,所以按 ID 把两份输出连接起来。你要找的那一行,其远程地址属于游戏服务,而拥有它的进程就是规则必须点名的可执行文件。

在 Linux 上,同一个问题需要按套接字类型各一条命令,而且两种都值得检查,因为比赛连接可能是 UDP,而其他一切都是 TCP:

ss -tunp state established | grep -i game
ss -tunp | awk 'NR==1 || /udp/'

如果游戏运行在容器或兼容层中,你找到的进程可能是 shim,而不是你安装的那个二进制文件。在这种情况下,重要的标识符是客户端看到的那个,可能是 shim 的路径,而无论怎么编辑原始文件都不会影响它。

匹配你的客户端支持的标识符

在添加任何东西之前,先读客户端关于排除规则的文档。三种常见模型行为不同,其中一种是陷阱。

IdentifierHow it behavesFailure mode
Executable pathMatches exactly the file at that pathBreaks when an update moves the binary
Process nameMatches any binary with that nameToo broad; catches unrelated software
Package or bundle idMatches a signed application groupMay include services you did not intend

路径规则最精确,也最脆弱。启动器更新一旦移动可执行文件,规则就会指向一个不再运行的文件,症状会在没有任何明显变化的情况下回来。包规则能扛住这一点,但它也可能悄悄覆盖你从没想过的辅助进程,这取决于辅助进程,可能方便,也可能令人警惕。

无论客户端支持什么,都不要为你找到的每个可执行文件都加条目。靠反复试错直到某次会话能用来拼出的列表无法审查,而且会悄悄积累无关软件的例外。点出你找到的那个进程,并写下它是做什么的。

在比赛上测,不要在下载上测

启动器的下载速度是最糟糕的测试,因为它练的正是已经被排除的那个进程。用之前失败的东西来测,并检查路径,而不是游戏自己的性能显示:

ip route get 203.0.113.55
Get-NetTCPConnection -State Established | Where-Object RemotePort -eq 27015

第一条命令需要比赛服务器解析出的地址,游戏的连接日志或客户端可以给你。如果路由显示的是物理接口,规则就在生效。第二条显示会话是否存在,从而把「已排除但服务器宕机」和「没有排除」分开。

测试时保持地区和接入网络不变。每次尝试都落在不同数据中心的比赛会产生不同地址,你最终会追一个移动目标,而不是验证规则。两次相同地址的运行,比十次不同地址更有价值。

下次更新后重新检查

任何基于路径的规则都有以补丁周期衡量的保质期。一个月后游戏不再遵守排除时,第一件要检查的事是可执行文件是否移动了,第二件是它旁边是否出现了新的辅助进程。

某个客户端记录的应用排除模型是描述这类规则的合理参考,尽管不同产品的细节不同。读你自己的文档,记录你使用的标识符,并写下日期。正是这份记录,让启动器下次发布更新时,谜题变成五分钟的修复。

如果客户端根本无法表达你需要的边界,经过批准的更宽策略,比一堆没有文档的例外更好。宽而清楚胜过窄而错误,尤其当所有人都以为生效的正是那个窄版本时。

相关文章