TTL 为 0 的 IP 数据包不得离开主机。
但是,当我启动以 TTL 0 进行多播 UDP 数据包的应用程序时,我看到 TTL 0 的数据包离开主机几秒钟,并恢复 TTL 0 的正常行为。这很可能发生在应用程序重新启动和首次启动后。
我使用 tcpdump 确认了离开主机的 TTL 为 0 的数据包:
05:31:39.048304 IP (tos 0x0, id 14487, offset 0, flags [DF], proto UDP (17), length 1344)
192.168.1.200.46968 > 239.0.0.1.1234: UDP, length 1316
05:31:39.049594 IP (tos 0x0, id 14488, offset 0, flags [DF], proto UDP (17), length 1344)
192.168.1.200.46968 > 239.0.0.1.1234: UDP, length 1316
05:31:39.051601 IP (tos 0x0, id 14489, offset 0, flags [DF], proto UDP (17), length 1344)
192.168.1.200.46968 > 239.0.0.1.1234: UDP, length 1316
05:31:39.053584 IP (tos 0x0, id 14490, offset 0, flags [DF], proto UDP (17), length 1344)
192.168.1.200.46968 > 239.0.0.1.1234: UDP, length 1316
我们可以看到ttl
没有显示,这意味着 TTL 0,这从 tcpdump 手册页中可以确认:https://www.tcpdump.org/manpages/tcpdump.1.html(搜索ttl
,它明确指出:ttl 是生存时间;如果为零,则不会报告)。
没有任何iptables
规则可运行。
uname -a
:Linux mydevice 4.15.0-101-generic #102-Ubuntu SMP Mon May 11 10:07:26 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
lsb_release -a
:
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 18.04.4 LTS
Release: 18.04
Codename: bionic
什么原因造成这种现象?我该如何解决?
答案1
解决方案是加入多播组
setsockopt(sockFd, IPPROTO_IP, IP_ADD_MEMBERSHIP, reinterpret_cast<const char*>(&mcastJoinReq), sizeof(ip_mreq))
进行多播之前sendto()
。
我一直认为,当我只需要发送多播时,我不需要加入多播,即我永远不会打电话recvfrom()
来接收多播。但无论只发送还是只接收,我们都必须加入多播。