事情的起因是家里的安卓设备经常刷带有图片流的 APP 卡顿,怀疑是家里配置的 IPv6 的问题,于是花了一天时间利用现成的工具研究一下,但是似乎还是没有定位出结果,整理发出来请大家帮忙分析一下。
反复开关安卓设备的 wifi 开关,然后刷 ipv6 的网页资源 testipv6.cn ,会偶发提示没有接入 IPv6 的现象,然而此时安卓设备 wifi 详情页面是有全球唯一 IPv6 地址的。
ER-X (拨号,IPv6-PD 下发,SLAAC 配置方式)
|
|
TP-Link WDR7650 ( AP 模式,有线连接 ER-X ,为下面设备提供无线接入)
《 》
《 》
Android (Honor) Mac
在 ER-X 路由器处抓包发现,安卓设备以全球唯一 IPv6 地址向目标服务器发送了 TCP 请求,但是回程数据包经由路由器转发时,被路由器直接丢弃,并向目标服务器返回目标不可达 ICMPv6 报文。
进一步分析发现,路由器在转发 IPv6 报文给安卓设备前,需要先通过 Neighbor Discovery Protocol 获得设备的 MAC 地址。但是,路由器反复以多播方式发送 Neighbor Solicitation ( NS ),但是安卓节点却迟迟不回应 Neighbor Advertisement ( NA )报告自己的 MAC 地址,导致路由器以为目的节点不可达,从而导致路由器直接丢包。这也解释了加载图片卡的原因:安卓设备收不到 ipv6 数据包,从而超时,然后使用 ipv4 。
苹果设备支持较好,每次路由器的 NS 报文,均有设备端的 NA 报文回复。
安卓设备端丢弃或者不回应 NS 报文。 Google 发现参考来源[1],[2],有类似的安卓设备不回应 Neighbor Solicitation 的情况:
The problem was the WiFi driver. Samsung for some reason thought it should block ICMPv6/NDP in standby to safe battery.
无线 AP 对于有线以太网的组播报文转到无线空口时可能丢弃。 Google 发现,无线网卡的驱动对于多播报文的处理可能不尽相同,可能处于安全或者性能考虑丢弃多播报文。
抓包发现,这台无线路由器疑似使用了多播转单播技术,如下图所示:
Many vendors of wireless APs support multicast-to-unicast conversion, which sends a unicast copy the frame to each intended receiver, using IGMP snooping to determine those stations. This means that the frame can be sent at the receiving station’s best data rate, which should almost always be above the minimum. Several unicast transmissions at 54Mbps would still use less channel time than the same multicast transmission at 1Mbps. In addition, stations which aren’t the intended receivers don’t need to wake up to listen to the frame, reducing their battery consumption.
无线路由器可能使用了 IGMP snooping 技术,而这可能导致不转发 IPv6 的组播报文。安卓设备在退出再加入无线网络时,路由器向安卓设备发起了 IGMP Query 查询,但是安卓设备并没有回应,也没有主动报告过。这说明,无线路由器获得网络中的所有节点不是通过多播来进行查询的。因为网络中的节点肯定不是全部都支持多播,且本身接入无线网络就已经报告了自己的 MAC ,无需多此一举。但是,这里仍然存在 bug 的可能,就是由于节点没有报告自己的状态,snooping 可能阻止报文向此节点的传播。
与参考来源[4]类似的情况,我们在出现问题后,让安卓设备 ping 路由器 WAN 口地址,过一段时间后安卓设备就有 IPv6 网络访问了,发现也即是安卓设备发出了 NA 报文回应路由器的 NS 报文。
安卓不回应路由器的 NS 报文,直到第 28 个 ping 报文发出,才回应路由器的 NS:
由于安卓设备没有 Root ,不能直接在上面抓包,只能将问题缩小到安卓设备和无线 AP 上了。由于没有一个比较好的方法继续分析和解决,就暂时关闭 IPv6 了,为了给家里人用得更加稳定(家里安卓设备居多)。大家如果感兴趣可以一起交流,帮忙楼主分析一下。
[^1]. https://forums.he.net/index.php?topic=4069.0
[^2]. https://forums.he.net/index.php?topic=2268.0
[^3]. https://wirelesslywired.com/2019/05/02/multicast-over-wireless/
[^4]. https://l2dy.sourceforge.io/2021/05/11/openwrt-ipv6-relay.html
这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。
V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。
V2EX is a community of developers, designers and creative people.