如何在Go中为TCP数据包设置"do not fragment"标志位?

zzy*_*zzy 5 sockets tcp go

我打算在Go中设置"do not fragment"标志位,与它在C中的帖子相同.我检查了常量列表但是我没有找到这个选项.那么Go中的相应选项是什么?

提前致谢!

cni*_*tar 5

如何在Go中为TCP数据包设置"do not fragment"标志位?

首先你应该知道TCP真的不喜欢IP片段.大多数(如果不是全部)主要实现通过使用路径MTU发现来避免TCP段的碎片化.

TL; DR是包含TCP段的典型IP包具有DF位集.你可以(并且应该)试试这个.在这里,我在我的机器和stackoverflow.com之间嗅探几秒钟的流量:

% tshark -w /tmp/tcp.pcap tcp and host stackoverflow.com
<wait a few seconds>
% tshark -r /tmp/tcp.pcap -T fields -e ip.flags | sort | uniq -c
    186 0x00000002
Run Code Online (Sandbox Code Playgroud)

0x02表示DF位置1.我在其他捕获中承认我在没有DF位的IP​​数据包中偶尔看到TCP段; 我怀疑rfc1191对此有一个解释.


现在回到你的问题,我认为没有可移植的方法来设置DF位,这是一个更普遍的问题(甚至没有POSIX可移植方式).在golang.org/x/sys下,您可以在相关包中找到一个逃生舱.

例如,在Unix支持IP_DONTFRAG诸如FreeBSD的人们可以使用unix.SetsockoptInt,挖有关的恒定值.

在Linux上没有IP_DONTFRAG,正如您从链接的问题中发现的那样.解决方法似乎是使用IP_MTU_DISCOVER恰好在unix包中作为常量使用.您可以使用相同unix.SetsockoptInt的设置.