Linux 中的最小 TCP MSS

Mir*_*zan 9 linux networking tcp linux-kernel

Linux 中的 TCP MSS 必须至少为 88(包括/net/tcp.h):

/* Minimal accepted MSS. It is (60+60+8) - (20+20). */
#define TCP_MIN_MSS             88U
Run Code Online (Sandbox Code Playgroud)

我的问题是:他们从哪里想出“60 + 60 + 8”,为什么?我知道 20 + 20 来自 IP 标头 + TCP 标头。

编辑:仔细查看标题后,公式看起来像这样:

(MAX_IP_HDR + MAX_TCP_HDR + MIN_IP_FRAG) - (MIN_IP_HDR + MIN_TCP_HDR)
Run Code Online (Sandbox Code Playgroud)

问题仍然存在:为什么?为什么 Linux 内核使用这个公式,从而禁止(强制流)TCP 段,比如 20 字节?想想这里的iperf。

EDIT2:这是我的用例。通过强制套接字/连接上的低 MSS,堆栈发送的所有数据包都将具有小尺寸。我想在使用 iperf 进行数据包/秒测试时设置低 MSS。由于 MSS 的下限,我无法在线路上获得小于 128 字节(142 字节的以太网帧)的 IP 数据包!根据 RFC 2544,我想尽可能接近 64 字节的以太网帧大小。理论上这应该是可能的:18 + 20 + 20 < 64。

Dav*_*rtz 5

需要一个实现来支持最大大小的 TCP 和 IP 标头,每个标头为 60 字节。

一个实现必须支持 576 字节的数据报,即使有最大报头也意味着数据报中有超过 8 个字节的数据。要发送包含超过 8 个字节的数据的数据报,IP 分段必须将至少 8 个字节的数据放入至少一个表示数据报片段的数据包中。因此,一个实现必须支持一个数据包中至少 8 个字节的数据。

综上所述,一个实现必须支持 60+60+8 字节的数据包。

当我们发送作为 TCP 流一部分的数据包时,它们有一个 20 字节的 IP 标头(加选项)和一个 20 字节的 TCP 标头(加选项)。这为数据和选项留下了最少 (60+60+8)-(20+20) 个字节。因此,这是我们可以安全地假设实现的 TCP MSS 的最大值。


War*_*ung 2

我不知道这个数字来自哪里,但我可以告诉你它超出了规范。IP 网络支持的最小 MTU 为 576 字节,即 512 数据字节加上最多 64 字节的 IP + TCP 标头和 TCP 选项。选择该值是为了在典型情况下提供相当低的开销。

我对内核代码位的阅读表明您显示的值不是任意的。有一种较旧的做法是仅使用原始常量 64 代替TCP_MIN_MSS。因此,我假设内核开发人员遇到了一些奇怪的 IP-over-Foo 网络,这使他们决定可以将价值提高到您所看到的程度。

然而,我不能说这种非标准网络类型是什么。