Linux 上带有邻居请求的异步 I/O

问题描述 投票:0回答:0

我正在 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
) 并将其绑定到接口的地址。

以一种典型的方式,我正在运行一个轮询循环,并在我可以写入和读取数据包时发出请求。这是奇怪的行为:

  1. 如果我用 single 邻居地址运行代码,一切都按预期工作。
  2. 如果我使用 多个 邻居地址运行代码并在发送新请求之前等待匹配的广告,则代码有效。
  3. 但是,如果我在没有等待相应广告的情况下发送多个请求,我会收到一个或(大部分)没有匹配我的请求的广告。

在所有情况下,我的程序收到的广告都不是对我的请求的响应。因此,我相信接收通常适用于所有三种情况。

为了确保这不是损坏状态并验证数据包是否实际发送出去,我用 Wireshark 记录了请求。请求通告的数据包与不请求通告的数据包相同。 (我提取了两个数据包的字节并通过

diff
运行它们。)一个捕获有回复而另一个没有。

(我查看了

ndisc6
的源代码,它也使用了
poll
,但一次只发出一个请求。)

编辑:添加了关于查询集的信息。请参阅下面的评论。

networking network-programming ipv6 icmpv6
© www.soinside.com 2019 - 2024. All rights reserved.