我正在 Linux 上使用异步 I/O 和轮询实现邻居请求。我的主机有多个接口(没有默认路由)。由于套接字 API 和 libnetlink 都没有提供根据请求执行邻居发现的方法,因此我自己实现了它。
我的下一跳 IPv6 地址集来自本地路由表(大约 100 个下一跳)。邻居缓存一次只能缓存大约 30 到 80 个,我不能依赖下一跳的硬件地址在那里可用。
问题: 当以异步 I/O 允许的速度发送请求时,我只收到一个响应或没有收到响应。
细节: 对于每个接口,我创建一个套接字(
socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6)
),执行一系列配置(FD_CLOEXEC
,非阻塞,ICMP6_FILTER
,SO_DONTROUTE
,IPV6_MULTICAST_HOPS
,IPV6_UNICAST_HOPS
,IPV6_RECVHOPLIMIT
) 并将其绑定到接口的地址。
以一种典型的方式,我正在运行一个轮询循环,并在我可以写入和读取数据包时发出请求。这是奇怪的行为:
在所有情况下,我的程序收到的广告都不是对我的请求的响应。因此,我相信接收通常适用于所有三种情况。
为了确保这不是损坏状态并验证数据包是否实际发送出去,我用 Wireshark 记录了请求。请求通告的数据包与不请求通告的数据包相同。 (我提取了两个数据包的字节并通过
diff
运行它们。)一个捕获有回复而另一个没有。
(我查看了
ndisc6
的源代码,它也使用了poll
,但一次只发出一个请求。)
编辑:添加了关于查询集的信息。请参阅下面的评论。