我在使用AF_PACKET
套接字时遇到了一个奇怪的问题,我想知道这是否是由于可能trio
代表我的滥用行为,还是其他原因。
我正在编写一个 TCP SYN 端口扫描器,目标是使其具有高性能。假设我要扫描 64K 端口;程序将把这个间隔分成 8 个 8K 的间隔,并且对于每个间隔,产生一个multiprocessing.Process
,trio.run
作为参数。在这个过程中,由于使用了异步套接字,一切都是异步的。说到套接字,我正在做我自己的过滤BPF
——它是一个简单的过滤器,只允许来自目标并发往侦听端口的数据包通过。
然而,问题是我recv()
似乎不止一次地随机数据包,我不知道为什么会这样。我已经使用 Wireshark 检查了流量,但没有看到重复的数据包,所以我认为问题一定出在程序的某个地方。
我正在寻找有关为什么会发生这种情况的见解,以及有关如何克服该问题的建议。
我也不确定这种 nmultiprocessing.Process
运行 ntrio
事件循环的设计是否被认为是可取的。
如果有人想看,我附上代码:
import multiprocessing as mp
import trio
from trio import socket
async def jumboworker(target, interval):
start, end = interval
ipv4_packet = build_ipv4_packet(target)
send_sock, recv_sock = create_sock_pair(target)
await recv_sock.bind(('enp5s0', 0x0800))
for port in range(start, end):
await microworker(send_sock, recv_sock, target, ipv4_packet, port)
async def microworker(send_sock, recv_sock, target, ipv4_packet, port):
tcp_packet = build_tcp_packet(target, port)
for _ in range(3):
await send_sock.sendto(ipv4_packet + tcp_packet, (target, port))
data, addr = await recv_sock.recvfrom(1024)
src, dest, flags = unpack(data)
if flags == 18:
print('port %d: open' % src)
break
elif flags == 20:
print('port %d: closed' % src)
break
else:
break
async def main(target: str, ports: t.Union[t.Tuple, t.List]) -> None:
async with trio.open_nursery() as nursery:
if isinstance(ports, tuple):
nursery.start_soon(jumboworker, target, ports)
if __name__ == '__main__':
# Parse args and separate individual ports from
# intervals; slice big intervals to 8K
for interval in intervals:
mp.Process(target=trio.run, args=(main, target, i)).start()
if ports:
mp.Process(target=trio.run, args=(main, target, ports)).start()
谢谢。