![CentOS 7上应用程序无法接收组播数据包](https://linux22.com/image/91393/CentOS%207%E4%B8%8A%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E6%97%A0%E6%B3%95%E6%8E%A5%E6%94%B6%E7%BB%84%E6%92%AD%E6%95%B0%E6%8D%AE%E5%8C%85.png)
我有一台 CentOS 7.2 机器,它是 VMware 来宾。我正在订阅一个多播组并看到我期望的所有多播,但我的应用程序没有看到流的内容。 strace 显示它正在等待 select() 系统调用。我忘记了什么?
这是我所做的:
- 在远程主机上启动多播发送器。
- 在 VMware 主机上构建 CentOS 7.2 来宾。
- 我停止并禁用防火墙,并
yum erase filewalld
在来宾上。iptables -L
显示:
-
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
- 我跑:
socat UDP4-RECVFROM:65000,ip-add-membership=239.31.82.10:10.0.54.210,fork STDOUT
- 我没有看到该命令的输出。
netstat -gn
表明它已订阅多播组。- selinux 被禁用,在
/etc/selinux/config
我看到:SELINUX=disabled
。是的,自该设置以来我已经重新启动。我还看到:SELinux status: disabled
从sestatus
tcpdump -n -nn -i eth0 host 239.31.82.10
显示从该 IP 到达接口、发往 UDP 端口 65000 的数据包。- 订阅同一多播组的另一台主机可以看到数据。
- 我构建了另一个 VM guest,这次使用 CentOS 6.4,并且运行良好。我看到多播发送器的常规输出。
- 我再次使用 CentOS 7.2 构建另一个 VM guest,并且运行良好。不过,这次我使用的是最小安装。
我的问题看起来就像防火墙阻止了数据包一样,但如图所示,没有启用防火墙。
我的非工作主机和工作主机之间的一个显着区别是,非工作主机上配置了两个接口。但同样,我将其显示为订阅了多播组,并且显示了到达接口的数据包。另外,我已经关闭了第二个界面,但这没有帮助。
谢谢。
答案1
哎哟!名言,
我的非工作主机和我的工作主机之间的一个显着区别是......
...因为那里躺着龙!
哎哟!著名的假设,
...但...
……因为这就是一切混乱的根源!
问题在于Linux 的网络反向路径过滤。问题是数据包进入一个接口,路由表发现发送主机的发件人地址应该通过另一个接口(默认路由器位于该接口上)传入/传出。因此,内核正在丢弃数据包,而不是将它们发送到我的应用程序。
发送 IGMP 报告是因为我告诉 socat 我应该使用哪个接口。路由器和交换机尽职尽责地设置多播,使其准确地到达我告诉它去的地方。最终,是内核不高兴了。
廉价而廉价的修复方法是使用 sysctl 更改为net.ipv4.conf.all.rp_filter
,但如果您不小心,可能会导致不可预见的后果(数据包乱序、接收到您不想要的数据包、数据包进入错误的接口)。最好确保路由表反映您正在尝试执行的操作的实际情况。因此,另一个修复方法是设置一个源或网络路由,专门用于该特定 iface 上的多播发送者 IP(即,或者您拥有的)。1
0
/etc/sysconfig/network-scripts/route-iface
eth1