Link-scope IPv6多播数据包在MacBook Pro上突然无法路由?

4

这是一个有点晦涩的问题,但我困惑了,我想也许有人能更了解这个问题。

我的同事在他的MacBook Pro上成功运行了使用IPv6多播的内部应用程序数月,但今天Mac决定停止路由多播数据包。特别是,该程序打印以下错误:

SendDataUDP(ff02::bead:cede:deed:feed@4) failed on Network interface [Name=[en0] Description=[] IP=[fe80::222:41ff:fe21:dfd4@4] Netmask=[ffff:ffff:ffff:ffff::] Broadcast=[::]] (errno=65/No route to host).

... 这相当清楚地描述了出了什么问题,它尝试将UDP数据包发送到所示的IP地址,并且send()失败,errno=EHOSTUNREACH。

我不明白的是,什么可能导致IPv6链路范围的多播地址“不可达”?如果我对链路范围多播的理解正确,则数据包只需要通过本地以太网端口(在这种情况下为en0),而该机器正在正常工作。

我是否漏掉了一些多播方面的内容,还是他的机器出现了故障?他说他没有改变任何东西,它只是神秘地停止工作了。


嗯,你能发一份最小的代码示例吗?我会在我的Mac上测试它,看看我能否在这里重现/调试它。 - Cody Casterline
2个回答

3

为了测试 en0 是否仍然能够传输本地链接的多播请求,请尝试执行以下操作:

ping6 ff02::1%en0

这会联系所有主机,因此您应该会收到足够多的响应(为了好玩,可以尝试添加-w参数)。


1
有趣的是,那没起作用,我不得不使用“-I”选项来指定以太网地址以ping6。jdks-mbp:〜jeffk $ ping6 ff02 :: 1%en0ping6:UDP连接:无法到达主机jdks-mbp:〜jeffk $ ping6 -I en0 ff02 :: 1PING6(56 = 40 + 8 + 8字节)fe80 :: 21f:f3ff:fed8:3680%en0 - > ff02 :: 1 来自fe80 :: 21f:f3ff:fed8:3680%en0的16个字节,icmp_seq = 0 hlim = 64 time = 0.131 ms - jdkoftinoff

2
可能有助于查看内核源代码。(特别是出口IPv6数据包出口路径,ip6_output.c)当您在那里时,您还可以查看引导到它的套接字调用等。
对于组播,假设您已经到达ip6_output(),似乎唯一可能出现此错误的方法是未指定要发送的接口。(这很奇怪,因为您的错误消息明确提到了接口)
这台 MacBook 上的无线接口是否已启用,而以前没有启用,现在“链路本地”组播的概念是否不明确?使用套接字时是否明确指定了接口?地址末尾的@4看起来很奇怪。(那是一个接口索引吗?)通常使用%表示接口范围ID,但正如前面的答案及其评论中所述,它并不被普遍支持。

3
我们终于找到了这里的问题……至少在MacOS/X下,仅仅将接口索引放入sendto()调用的目标地址中是不够的。操作系统可以而且有时会选择自己使用的接口索引,忽略提供的那个索引并导致问题。解决方法是根据需要在套接字上调用setsockopt(fd, IPPROTO_IPV6, IPV6_MULTICAST_IF, &myIdx, sizeof(myIdx)),而不是(或者除了)在sendto()地址参数中指定接口索引。我不确定这是一个错误还是一个“特性”…… - Jeremy Friesner
@JeremyFriesner 你好,这是来自2022年的问候。这个问题似乎依然存在,而在Rust中我没有一种简单的方法来设置setsockopt(…)。如果您曾经回答过错误与功能问题的问题,我会很感兴趣。 - Cody Casterline
@CodyCasterline 我没有更多信息;苹果公司的行事方式很神秘。虽然如此,肯定有一种方法可以从 Rust 中调用 setsockopt(),否则他们不会定义常量。https://docs.piston.rs/gfx_text/libc/constant.IPV6_MULTICAST_IF.html - Jeremy Friesner
我找到了一种方法,只是还没有测试过: https://docs.rs/socket2/0.4.4/socket2/struct.Socket.html#method.set_multicast_if_v6 - Cody Casterline
哈哈!好的,我认为设置multicast_if可能已经在一般情况下修复了我的问题,但这里有一个有趣的类似问题。我正在编写一个实用程序,在计算机的每个网络上进行快速的多播广播/监听。我有一些en5接口,它仍然返回“无法路由到主机”的错误......那是因为它是连接到MacBook触控栏的桥接接口。我猜我只需要为那个接口写一个异常处理。‍♂️ https://stackoverflow.com/questions/50520202/macos-en5-network-cant-be-turned-off - Cody Casterline

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接