【发布时间】:2021-09-25 15:51:43
【问题描述】:
我在使用 AF_PACKET 套接字时遇到了一个奇怪的问题,我想知道这是否是因为我可能滥用了 trio 或其他原因。
我正在编写一个 TCP SYN 端口扫描器,目的是使其具有高性能。假设我要扫描 64K 端口;程序会将这个间隔分成八个 8K 间隔,并且对于每个间隔,生成一个 multiprocessing.Process,以 trio.run 作为参数。在这个过程中,由于使用了异步套接字,一切都是异步的。说到套接字,我正在使用BPF 进行自己的过滤 - 这是一个简单的过滤器,只允许源自目标并发往侦听端口的数据包通过。
但是,问题是我会多次recv() 看似随机的数据包,我不知道为什么会这样。我已经使用 Wireshark 检查了流量,但没有看到重复的数据包,所以我认为问题一定出在程序的某个地方。
我正在寻找有关为什么会发生这种情况的见解,以及有关如何克服该问题的建议。
我也不确定在 n multiprocessing.Process 运行 n trio 事件循环的这种设计是否被认为是可取的。
如果有人想看,我附上代码:
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()
谢谢。
【问题讨论】:
-
不幸的是,您提供的代码 sn-ps 非常不完整。人们可能会做出有根据的猜测可能是什么问题,但没有办法理解甚至重现你真正在做什么。
标签: python sockets bpf python-trio