gpt4 book ai didi

c - 使用原始套接字重新传输大数据包

转载 作者:太空狗 更新时间:2023-10-29 11:12:25 24 4
gpt4 key购买 nike

问题:在原始套接字上,recvfrom 可以捕获比 sendto 可以发送的字节更多的字节,阻止我重新传输大于 MTU 的数据包。

背景:我正在编写一个应用程序来捕获和重新传输数据包。基本上主机 A 将数据发送到 X,记录它们并将它们转发给 B,所有 Linux 机器。我正在使用原始套接字,因此我可以捕获所有数据,它是使用 socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)) 创建的。

然后是等待和读取传入数据包的代码:

const int buffer_size = 2048;
uint8_t* buffer = new uint8_t[buffer_size];
sockaddr_ll addr = {0};
socklen_t addr_len = sizeof(addr);
int received_bytes = recvfrom(_raw_socket, buffer, buffer_size, 0, (struct sockaddr*)&addr, &addr_len);

接下来是数据包处理,循环结束,再次发送数据包:

struct sockaddr_ll addr;
memset(&addr, 0, sizeof(struct sockaddr_ll));
addr.sll_family = htons(AF_PACKET);
addr.sll_protocol = eth_hdr->type;
addr.sll_ifindex = interface().id();
addr.sll_halen = HardwareAddress::byte_size;
memcpy(&(addr.sll_addr), eth_hdr->dest_mac, HardwareAddress::byte_size);

// Try to send packet
if(sendto(raw_socket(), data, length, 0, (struct sockaddr*)&addr, sizeof(addr)) < 0)

问题是我不希望收到大于以太网 MTU(1500 字节)的数据包,而且我不应该这样做,因为我使用的是单独处理每个数据包的原始套接字。但有时我确实会收到大于 MTU 的数据包。我认为这可能是我的代码中的错误,但 Wireshark 证实了这一点,如图所示,因此必须在较低级别(如网络 Controller 本身)进行一些重组。 Received packet

好吧,那么我不认为有一种方法可以只为一个应用程序禁用它,而且我无法更改主机配置,所以我可能会增加缓冲区大小。但问题是,当我用任何大于 MTU 大小(实际上是 1514B,因为 eth header )调用 sendto 时,我得到 80: Message too long errno。这就是上面提到的问题——我无法发送我收到的同一个数据包。这可能是什么解决方案?我需要多大的缓冲区才能始终捕获整个数据包?

编辑:我刚刚使用 ethtool -k interf 检查了机器并在所有他们,所以看起来它真的是NIC重新组装碎片。但我想知道为什么 sendto 的行为与 recvfrom 不同。如果数据包可以自动重组,为什么不分片?

旁注:应用程序需要发送这些数据包。使用 iptables 等设置转发将不起作用。

最佳答案

您的网卡可能启用了分段卸载,这意味着硬件可以在 TCP 分段到达操作系统或您的代码之前重新组装它们。

您可以通过运行 ethtool -k 检查是否是这种情况。虽然透明地捕获 TCP 流量并以如此低的级别重新传输它通常比它值得的麻烦更多(通常最好在应用程序层执行此操作,终止 TCP 连接并为您的主机建立一个新的 TCP 连接B),如果你的网卡已经把数据包弄乱了,你就不能捕获并重新发送数据包。你需要:

  • 关闭通用分段卸载
  • 关闭通用接收卸载
  • 关闭 tcp-segmentation-offload
  • 如果您还要处理 UDP,请关闭 udp-fragmentation-offload
  • 如果您的数据包是 VLAN 封装的,请关闭 rx-vlan-offload/tx-vlan-offload
  • 可能会关闭 rx-checksumming 和 tx-checksumming。如果两者都有效,它要么有效已启用,或者它已损坏。 RAW 套接字(如果启用),具体取决于您的内核版本和网卡类型。

这些可以使用 ethtool -K 命令打开/关闭,确切的语法在 ethtool 手册页中有描述。

关于c - 使用原始套接字重新传输大数据包,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43051899/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com