众所周知 IPTV 因为是一个独立网络,会给家里网络布线带来一些不便。例如很多人家里弱电箱到客厅只有一根网线,如果想要光猫放弱电箱,IPTV 、路由器、游戏机等放客厅,那么就会有麻烦。一般常用方式要不是把一根 8 芯网线分成两根 4 芯降速到 100M 跑,要不是用带有 VLAN 管理的交换机实现单线复用。
这里我提供另一个思路,即把 IPTV 网和宽带网同时接入到主路由器上,然后用静态路由来分流。这个方案好处是不再依赖 VLAN ,因为很多家用路由器不支持 VLAN 管理; IPTV 盒子随意接到家里任何一个网口上都可以使用。
其实思路很简单,但是有一些坑,特别是涉及组播相关。下面以我所在地 海南电信 为例。
我的网络拓扑很简单:
光猫 <--> 主路由器 <--> AP
其中主路由器是 x86 软路由,安装了原版 openwrt 。AP 是市面上常见的家用 mesh 路由器,我的是华硕系列。光猫桥接模式,主路由拨号上网。
通过前期的抓包分析,我已经知道:
- 我的 IPTV DHCP 无需认证,可以直接获得 10.254.0.0/19 下的地址,默认网关是 10.254.0.1
- IPTV DHCP 下发的 DNS 和宽带网是一样的地址,DNS 是一个普通省内公网 IP 。经过测试在 IPTV 网络下,DNS 并无任何特殊解析行为。
- IPTV 盒子访问的所有 IPTV 网内资源都处于 10.39.0.0/16 和 10.255.0.0/16 这两个网段下
- IPTV 盒子也偶尔会访问一小部分公网资源,经过测试这部分公网资源在普通宽带网下面也可以正常访问,并不专属于 IPTV 网
- IPTV 盒子的直播都是走的 IGMP 组播。这些组播源我已经都抓出来整理好了,分享在了这里
- IPTV 盒子每次切换频道时都是秒切,几乎无等待,体验丝滑。而众所周知如果使用 IGMP 组播的话,因为要等待 I 帧到达,换台没有这么快速。分析发现使用了名为 Fast Channel Change (FCC) 的技术,在每次换台时,盒子会先向 FCC 服务器请求单播流,这个单播流因为是以 I 帧开头,所以立即可以解码播放。等 FCC 服务器认为时机合适的时候,会告知盒子无缝切换到组播流上继续解码。
有了上面这些抓包分析之后,配置方法就明确了:
- 从光猫连两根网线到主路由,一根属于宽带,一根属于 IPTV (连接光猫 iTV 口)。理论上这里也可以通过 VLAN 简化成一根网线,但是我没有光猫超级密码,不想折腾了。
- 在主路由配置两个 WAN ,WAN1 属于宽带,通过 PPPoE 拨号获取 IP 。WAN2 属于 IPTV ,通过 DHCP 获取 IP 。WAN1/WAN2 同属于同一个防火墙 zone 下面。把 WAN2 的默认网关和自动获取 DNS 选项关闭。
- 在主路由上配置两条静态路由:10.39.0.0/16 via 10.254.0.1 dev wan2 和 10.255.0.0/16 via 10.254.0.1 dev wan2
- 此时把 IPTV 盒子通过网线接到主路由或者任意 AP 下面,发现已经可以通过开机认证并且显示主界面了。只是不能播放直播频道。
- 这是因为我们还没有解决 IGMP 组播转发问题。对于 openwrt ,需要安装 omcproxy 和 luci-app-omcproxy 。omcproxy 的上行链路设置为 wan2 ,下行链路设置为 lan 。
- 此时 IPTV 盒子已经可以播放直播频道。任意电脑连接网线接入家庭局域网后,也可以用本地播放器直接播放上面我整理好的 RTP 组播地址。
- 但是发现 IPTV 盒子切换频道非常慢,每次换台需要等待 3-5 秒。如果 IPTV 盒子直接接入光猫,可以秒换台,很丝滑。看来 FCC 机制没有生效。
- 在主路由添加一条端口转发规则:将从 wan2 入站的 UDP 20000-21000 端口转发到 IPTV 盒子上。
- IPTV 盒子切换频道重新变得丝滑起来,秒切无卡顿。原因是当 FCC 服务器返回单播流时,是用一个新端口直接给盒子的 20000-21000 的某个随机端口打流,因此必须开启端口转发来放行
关于 FCC 的这部分我找了很多资料,过去应该很少有人提到过它。我折腾了很久,反复抓包对比才发现它的工作方式类似 FTP 主动模式,需要在防火墙上开端口映射才行。希望大家点个赞。
目前还有一个遗留问题,是 DHCP 获取的地址,1-2 天后会失效且不会自动重新获取。猜测有某种保活机制,但是我还没有逆向出来。现在我的应对办法是在路由器上通过脚本定期重启 wan2 interface 和 omcproxy 。