首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >广播数据包不会通过Linux隧道传播

广播数据包不会通过Linux隧道传播
EN

Stack Overflow用户
提问于 2019-09-24 12:45:57
回答 1查看 376关注 0票数 1

我正在开发一个依赖子网广播的网络应用程序。我决定使用虚拟以太网接口(veth)在本地计算机上设置一个用于测试和开发目的的受控环境。设置非常简单:

代码语言:javascript
运行
复制
ip link add veth0 type veth peer name veth1
ifconfig veth0 192.168.241.1 netmask 255.255.255.0 up
ifconfig veth1 192.168.241.2 netmask 255.255.255.0 up

ip link确认接口已打开,并设置了广播标志:

代码语言:javascript
运行
复制
8: veth1@veth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 46:29:76:81:27:af brd ff:ff:ff:ff:ff:ff
9: veth0@veth1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP mode DEFAULT group default qlen 1000
    link/ether 3a:ad:f9:cb:28:a8 brd ff:ff:ff:ff:ff:ff

Python中的一个简单测试表明接口是功能性的。这是接受者:

代码语言:javascript
运行
复制
>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.bind(('192.168.241.2', 48469))
>>> s.recvfrom(1000)
(b'abc', ('192.168.241.1', 45560))

这是发送者:

代码语言:javascript
运行
复制
>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.connect(('192.168.241.2', 48469))
>>> s.send(b'abc')
3

适用于单播数据包。然而,广播数据包似乎被静默丢弃。可以使用下列发件人端REPL来再现问题:

代码语言:javascript
运行
复制
>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)
>>> s.connect(('192.168.241.255', 48469))
>>> s.send(b'abc')
3
>>> s  # For diagnostic purposes
<socket.socket fd=3, family=AddressFamily.AF_INET, type=SocketKind.SOCK_DGRAM, proto=0, laddr=('192.168.241.1', 48065), raddr=('192.168.241.255', 48469)>

套接字配置成功,但发出的广播数据包从未到达隧道的另一端。这不是我所期望的行为,特别是考虑到接口标志表示接口支持广播。我使用股票内核在Linux 18上运行这些测试。我遗漏了什么?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-09-26 13:59:32

隧道很好。

问题是,除非套接字绑定到INADDR_ANY,否则Linux会丢弃所有传入的广播通信量。如果接收方REPL按以下方式更新,则所有操作都正常:

代码语言:javascript
运行
复制
>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.bind(('', 48469))  # Bind to INADDR_ANY to accept broadcast packets
>>> s.recvfrom(1000)
(b'abc', ('192.168.241.1', 45560))

在Windows上,行为是不同的(不管隧道如何):将套接字绑定到特定的接口不会拒绝广播流量。

Man 7 IP说,为了接收广播数据报,应该设置SO_BROADCAST;但是,我在接收端所观察到的行为似乎与描述不符:

只有在设置了

套接字标志时,才能发送或接收用于广播地址的SO_BROADCAST数据报。

广播数据报始终可以用INADDR_ANY接收;如果套接字绑定到特定的接口,则永远不会接收。无论s.setsockopt(socket.SOL_SOCKET, socket.SO_BROADCAST, 1)如何,这两条语句都保持不变。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/58080648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档