【问题标题】:Getting duplicate packets from AF_PACKET socket从 AF_PACKET 套接字获取重复数据包
【发布时间】: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


【解决方案1】:

AF_PACKET 定义一个原始套接字。在这种情况下,传入的数据包被复制到同一接口上的所有原始套接字 - 因为没有明确的标识符传入的数据包属于哪个套接字。由于您使用了多个原始套接字,因此您会在这些套接字上获得重复的数据包。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-11-22
    • 2021-02-07
    • 1970-01-01
    • 2014-12-08
    • 2011-06-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多