为什么开启路由器 VPN 之后投屏不再工作
发现过程走的是链路本地组播,而电视自己拉取媒体。策略里的默认路由可能截获局域网请求,把它送进隧道。
投屏在开启路由器 VPN 之前是正常的,开启之后立刻失败,而手机上的普通浏览仍然可用。这两件事并不矛盾,因为投屏不是一条连接。手机在局域网内发现并控制接收端,随后由接收端用自己的连接去拉取媒体。
两条以不同方式失败的路径
控制路径是本地的。手机向局域网查询来发现接收端,然后向学到的地址建立控制连接。如果接收端始终不出现在列表里,说明在请求任何媒体之前,发现这一环就已经失败。
媒体路径不一定在本地。很多接收端会自己拉取码流,用它自己的连接和自己的凭据,所以手机的路由说明不了接收端的路由。看起来只用一个出口的手机,并不能说明电视的流量去了哪里。
正是这种分离让故障显得奇怪。隧道改变了手机的路由表,却没有改变电视的,所以出现在这对设备某一侧的症状,必须在该侧去追查。查错设备,通常是修了却看不到效果的常见原因。
为什么先坏的是发现
发现通常走链路本地组播。mDNS 发送到 224.0.0.251 的 UDP 端口 5353,SSDP 发送到 239.255.255.250 的 UDP 端口 1900。两者按设计都只限在单条链路内,所以路由器不会在没有中继或代理的情况下把它们转发到别的网段。被路由的 VPN 不会扩展组播组,策略路由也无法让一个从未离开链路的组出现在另一条链路上。
所以第一次失败与加密无关。手机的组播离开了发出它的那个接口,接收端在永远看不到它的网段里,设备列表于是返回空。空列表并不能证明电视失去了互联网访问。
完全不涉及 VPN 时,隔离也会造成同样的症状。访客网络和接入点的客户端隔离会刻意阻止设备互相通信,而在被隔离的网段上再开路由器 VPN 对此毫无改变。先检查隔离设置,再检查隧道。这是更便宜的答案,也更常见。
网段布局是另一半。第二台路由器、处在另一种模式的 mesh 节点,或者另一层 NAT 后面的有线网段,都会把接收端放在手机发现流量到不了的地方。
为什么默认策略会吞掉一个本地请求
把全部流量送进隧道的路由器,会在隧道接口上装一条默认路由。如果 LAN 前缀没有从这条策略中排除,那么发往两米外设备的报文现在会命中默认路由,路由器便把控制请求送进隧道,而不是送到交换机。
| Stage | What carries it | How a router VPN interferes |
|---|---|---|
| Discovery | Link-local multicast on a single segment | Not extended across segments, and not repaired by a route |
| Control connection | Unicast to the receiver address on the LAN | A policy default can capture the LAN destination and tunnel it |
| Media fetch | The receiver's own connection | Unaffected by the phone's route, but affected by the TV's own policy |
| Account authorization | Tokens held by the application | Can fail for reasons unrelated to any route |
规则顺序决定结果。策略路由按优先级评估规则,所以本地前缀的例外必须排在选择隧道表的那条规则之前。把例外加在隧道规则之后没有任何效果,这就是为什么看起来正确的配置仍然会把局域网流量送到远端出口。
修复范围很窄:放行投屏流程需要的那些特定本地目标,其余隔离保持不动。第一步就把客户端隔离删掉,症状是好了,但丢掉了网络原本设计上应有的控制。
在手机上快速看一眼,就能确定是哪一种失败。如果去接收端的路由指向隧道,问题在策略。如果指向局域网而发现仍然失败,问题在组播或隔离,改路由不会有帮助。
ip route get 192.168.1.50
ip rule show
avahi-browse -rt _googlecast._tcp测发生变化的那一环,而不是换国家
记录下来的观察胜过反复试验。记下接收端是否出现在设备列表里、控制请求是否到达它、选中码流后是否开始播放。每个答案都会把一环从嫌疑中排除。
然后直接测试每一环,而不是切换出口地区。换 VPN 国家测的是媒体路径,对发现和控制这两环毫无触及,所以它可能碰巧显得有用,却什么都没教会你。
在接收端一侧,检查它自己的路由和它自己的账号状态。电视通过和手机不同的出口拉取媒体是正常设计,那里的故障是关于接收端网络策略的问题,而不是手机隧道的问题。
把结果写成一句话:哪一环坏了,是什么改变了它。这句话比一周换国家更值钱,而且能扛过下一次固件更新。
投屏是检验隧道通用规则的好例子。当一条隧道被加进网络时,第一个问题是哪些目标本来就不该进入它;第二个问题是,其中哪些仍然被策略悄悄接受了。