Chromecast 与 DLNA 的发现从不穿过被路由的 VPN
投屏与 DLNA 浏览需要在本网段做组交换,而路由隧道从不承载它。请先查公告,再查隧道。
投屏按钮什么都不列,VLC 的 DLNA 一直是空的,而另一端那台机器对 ping 照常应答。这个组合不是带宽问题,也不是防火墙之谜。这些协议的发现就是本网段上的组交换,而 路由隧道并不承载组地址流量。你要发起的会话根本没有被通告出去。
连通性没有问题。缺的是发现。
误区:隧道需要某个设置,或者更多带宽
常见的建议是启用对等流量、提高 MTU,或者更换隧道设备类型。它们都不会增加广播域。组播由交换机和本地网络栈投递,而点对点 TUN 接口根本没有可泛洪的组地址。
改设置只会让故障更响。它没法让协议从未发出的公告凭空出现。
发现交换究竟是什么
三个模式几乎覆盖你遇到的全部情况。mDNS 发往 224.0.0.251 的 UDP 5353,SSDP 发往 239.255.255.250 的 UDP 1900,更早的 SMB 浏览列表则发往子网广播地址。它们都发往一个组而不是一台主机,并且都期待同一网段上的监听者。位于路由隧道另一端的接收者不在那个网段,所以什么也到不了。
即便是被中继的公告也带着负载:通常是发送方的 LAN 地址和端口,远端观看者必须能够到达那里。
改隧道之前先读抓包
在应用扫描时,在隧道接口上抓包。空抓包意味着公告从未越过边界,再多的隧道调优也改变不了。应用仍然什么都不显示、但确实出现报文,通常说明所公布的地址从观看者一侧不可达,这是披着发现外衣的路由问题。
两分钟的抓包胜过一小时的端口猜测:tcpdump -ni tun0 udp port 5353 or udp port 1900。
三个办法,最便宜的先来
让客户端直接指向服务地址。对 DLNA、SMB 和普通媒体服务器来说,这完全跳过发现,并证明负载通路可用,因此它既是最好的第一项测试,也是可用的变通办法。Chromecast 是例外,因为接收端期望被找到,而不是被指到。
在网关上中继该协议。mDNS 反射器在隧道与 LAN 之间重复公告,Avahi 提供了一个接收明确接口列表的反射器段。把中继范围收窄,并确认所公布的地址从两侧都可达,否则应答仍然指向观看者无法路由的子网。
用桥接而不是路由。让服务器把 tap 设备桥接到 LAN 的 TAP 网段,会把两端放进同一个广播域,于是公告原样通过。这也是最贵的选项,因为一个子网意味着一个故障域,而 LAN 上每个组播服务现在都能到达每个对等端。
什么帮不上忙,无论被建议多少次
在没有桥接的情况下,把 dev tun 换成 dev tap 只会留下仍然被路由的 TAP 设备,行为不会改变。client-to-client 允许对等单播,但不会泛洪广播。把发现端口转发到单台主机并不会投递组地址流量。绑定在单个地址上的媒体服务器会继续在该地址上应答,直到它自己的配置列出 VPN 接口为止。
先测一个直接单播请求,再测一个被公告的请求。如果第一个能用、第二个不能,说明隧道是健康的,发现才是全部问题。