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

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

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

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确认接口已启动并且已设置广播标志:

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 REPL中的一项简单测试表明接口是有效的。这是接收者:

>>> 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))

这是发件人:

>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
>>> s.connect(('192.168.241.2', 48469))
>>> s.send(b'abc')
3

适用于单播数据包。但是,广播数据包似乎已被静默丢弃。下面的发送方REPL可用于重现该问题:

>>> 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 Mint 18上运行这些测试。我想念什么?

linux broadcast broadcasting virtual-network virtual-network-interface
1个回答
1
投票

隧道很好。

问题是,除非套接字绑定到INADDR_ANY,否则Linux会丢弃所有传入的广播流量。如果接收方的REPL更新如下,则一切正常:

>>> 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)无关。

© www.soinside.com 2019 - 2024. All rights reserved.