Linux 中的 TCP MSS 必须至少为 88(include/net/tcp.h):
/* Minimal accepted MSS. It is (60+60+8) - (20+20). */
#define TCP_MIN_MSS 88U
我的问题是:他们从哪里想到“60 + 60 + 8”?为什么?我知道 20 + 20 来自 IP 标头 + TCP 标头。
编辑:仔细查看标题后,公式对我来说如下所示:
(MAX_IP_HDR + MAX_TCP_HDR + MIN_IP_FRAG) - (MIN_IP_HDR + MIN_TCP_HDR)
问题仍然存在:为什么?为什么 Linux 内核使用这个公式,从而禁止(强制流动)例如 20 字节的 TCP 段?想想这里的iperf。
EDIT2:这是我的用例。通过在套接字/连接上强制设置低 MSS,全部堆栈发送的数据包尺寸较小。我想在使用 iperf 进行数据包/秒测试时设置较低的 MSS。由于 MSS 的下限,我无法在线路上获取小于 128 字节的 IP 数据包(142 字节的以太网帧)!我希望按照 RFC 2544 获得尽可能接近 64 字节的以太网帧大小。理论上这应该是可能的:18 + 20 + 20 < 64。
答案1
需要一个实现来支持最大大小的 TCP 和 IP 标头,每个标头为 60 字节。
实现必须支持 576 字节数据报,即使使用最大标头,也意味着数据报中的数据超过 8 字节。要发送超过 8 字节数据的数据报,IP 分段必须将至少 8 字节数据放入至少一个表示数据报片段的数据包中。因此,实现必须支持数据包中至少 8 字节的数据。
综上所述,实现必须支持 60+60+8 字节数据包。
当我们发送属于 TCP 流的数据包时,它们具有 20 字节的 IP 标头(加上选项)和 20 字节的 TCP 标头(加上选项)。这至少为数据和选项留下 (60+60+8)-(20+20) 字节。因此,这是我们可以安全地假设实现的 TCP MSS 的最大值。
答案2
我不知道这个数字来自哪里,但我可以告诉你它超出了规范。 IP 网络支持的最小 MTU 为 576 字节,即 512 数据字节加上最多 64 字节的 IP + TCP 标头和 TCP 选项。选择该值是为了在典型情况下提供相当低的开销。
我对内核代码位的阅读表明您显示的值不是任意的。有一种较旧的做法是仅使用原始常量 64 代替TCP_MIN_MSS
。因此,我假设内核开发人员遇到了一些奇怪的 IP-over-Foo 网络,这使他们决定可以将价值提高到您所看到的程度。
然而,我不能说这种非标准网络类型是什么。