簡體   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