我使用以下代码在名称为C,S的两个设备上测试(客户端172.18.91.28为C,服务器172.18.91.41为S):
#!/usr/bin/python
import sys, socket, struct
def client():
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# work only with add new iptable rule in device S
sock.bind(("172.18.91.28", 9999))
sock.connect(("230.1.1.5",9999))
while True:
d = raw_input('input:')
sock.send(d)
def server():
sock = socket.socket(socket.AF_INET,socket.SOCK_DGRAM)
# work only with add new iptable rule in device S
sock.bind(("230.1.1.5", 9999))
sock.connect(("172.18.91.28", 9999))
# join multicast group
mreq = struct.pack("=4sl", socket.inet_aton("230.1.1.5"), socket.INADDR_ANY)
sock.setsockopt(socket.IPPROTO_IP, socket.IP_ADD_MEMBERSHIP, mreq)
# make sure to create a ESTABLISHED udp connection(in 'netstat -anup').
sock.send("xxxx")
while True:
data = sock.recv(1024)
print("receive: "+repr(data))
if(sys.argv[1] == 'client'):
client()
else:
server()
两个设备的iptables均为:
$ sudo iptables -nL
Chain INPUT (policy DROP)
target prot opt source destination
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0 state RELATED,ESTABLISHED
ACCEPT all -- 0.0.0.0/0 0.0.0.0/0
ACCEPT icmp -- 0.0.0.0/0 0.0.0.0/0
....
您会看到iptable接受所有已建立的软件包。
服务器运行时,netstat显示:
S ~ # netstat -anup
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
udp 0 0 172.18.92.41:9999 172.18.91.28:9999 ESTABLISHED 4689/python
您会看到C和S之间已建立的udp连接。
问题是服务器S无法接收客户端的软件包,而C和S之间已建立连接(tcpdump可以捕获软件包)。
所以为什么iptables会丢弃“ ESTABLISHED” udp INPUT多播包?(虽然已建立的udp INPUT NON-multicast包被相同的iptables接受)。
这与状态模块的实现有关吗?