繁体   English   中英

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

[英]Retransmitting large packets with raw sockets

问题:在原始套接字上, 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 确认了这一点,如图所示,因此必须在较低级别进行一些重组,例如网络控制器本身。 收到的数据包

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

编辑:我刚刚用ethtool -k interf检查了机器,并在所有机器上都tcp-segmentation-offload: ontcp-segmentation-offload: on ,所以它似乎真的是 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-checksuming 和 tx-checksumming。 如果两者都启用,它要么工作,要么坏了。 RAW 套接字(如果启用)取决于您的内核版本和网卡类型。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM