你的分流隧道排除的是启动器,不是游戏
启动器会为比赛启动另一个可执行文件,而那个进程拥有自己的套接字。找到真正的进程,匹配正确的标识符,然后再测试。
你把启动器加入排除列表,下载速度从慢变快,比赛却仍然落在远端服务器上。什么都没坏。启动器和游戏是两个进程,各自拥有一组套接字,排除其中一个并不能说明另一个。下载变快是因为下载本来就是启动器的流量;比赛是别人的连接,由你的规则从未见过的可执行文件打开。
一个安装器,多个进程
现代游戏软件像一个小星座。有负责登录的客户端,有拉取内容的更新器,有启动游戏的启动器,还有游戏可执行文件本身,它可能为反作弊或匹配覆盖层再生成一个进程。它们每一个都可能保持通往各自目标的连接。
排除规则通常只点名其中一个。点的是哪一个,完全取决于 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 的路径,而无论怎么编辑原始文件都不会影响它。
匹配你的客户端支持的标识符
在添加任何东西之前,先读客户端关于排除规则的文档。三种常见模型行为不同,其中一种是陷阱。
| Identifier | How it behaves | Failure mode |
|---|---|---|
| Executable path | Matches exactly the file at that path | Breaks when an update moves the binary |
| Process name | Matches any binary with that name | Too broad; catches unrelated software |
| Package or bundle id | Matches a signed application group | May include services you did not intend |
路径规则最精确,也最脆弱。启动器更新一旦移动可执行文件,规则就会指向一个不再运行的文件,症状会在没有任何明显变化的情况下回来。包规则能扛住这一点,但它也可能悄悄覆盖你从没想过的辅助进程,这取决于辅助进程,可能方便,也可能令人警惕。
无论客户端支持什么,都不要为你找到的每个可执行文件都加条目。靠反复试错直到某次会话能用来拼出的列表无法审查,而且会悄悄积累无关软件的例外。点出你找到的那个进程,并写下它是做什么的。
在比赛上测,不要在下载上测
启动器的下载速度是最糟糕的测试,因为它练的正是已经被排除的那个进程。用之前失败的东西来测,并检查路径,而不是游戏自己的性能显示:
ip route get 203.0.113.55
Get-NetTCPConnection -State Established | Where-Object RemotePort -eq 27015
第一条命令需要比赛服务器解析出的地址,游戏的连接日志或客户端可以给你。如果路由显示的是物理接口,规则就在生效。第二条显示会话是否存在,从而把「已排除但服务器宕机」和「没有排除」分开。
测试时保持地区和接入网络不变。每次尝试都落在不同数据中心的比赛会产生不同地址,你最终会追一个移动目标,而不是验证规则。两次相同地址的运行,比十次不同地址更有价值。
下次更新后重新检查
任何基于路径的规则都有以补丁周期衡量的保质期。一个月后游戏不再遵守排除时,第一件要检查的事是可执行文件是否移动了,第二件是它旁边是否出现了新的辅助进程。
某个客户端记录的应用排除模型是描述这类规则的合理参考,尽管不同产品的细节不同。读你自己的文档,记录你使用的标识符,并写下日期。正是这份记录,让启动器下次发布更新时,谜题变成五分钟的修复。
如果客户端根本无法表达你需要的边界,经过批准的更宽策略,比一堆没有文档的例外更好。宽而清楚胜过窄而错误,尤其当所有人都以为生效的正是那个窄版本时。