Windows 7 不从 DHCP 服务器请求 MTU;它在想什么?

Ian*_*oyd 8 networking windows-7 ethernet ip mtu

我的计算机的以太网适配器使用 1,500 字节的以太网帧。通常这意味着我的本地连接的MTU 是1500字节。

但是我的 (IPv4) 连接到 Internet 有一些开销。这意味着与 Internet 通信时我的实际 MTU 是1492. 这导致了错误配置的接口 MTU 存在的所有常规问题。

路由器可以解决它

显然,我可以使用netsh,并使用自定义 MTU 覆盖我的网络接口。但我不想那样做。我的路由器的 DHCP 服务器已经知道 MTU 是1492. 如果询问,DHCP 服务器将使用 DHCP 选项 26 进行响应:

  • 26 MTU 接口=1492

所以这让我发疯了为什么 DHCP 服务器没有告诉我的 Windows 7 机器 MTU 设置作为它在DHCP 报价中返回的项目之一:

  • 54 DHCP 服务器标识符=192.168.1.1
  • 51 IP 地址租用时间=2 hours
  • 1子网掩码=255.255.255.0
  • 15域名=example.local
  • 3路由器=192.168.1.1
  • 6域名服务器= 8.8.8.8, 8.8.4.4,74.82.42.42

没有MTU 接口!所以我机器的以太网卡在1500字节上。

DHCP 服务器做了它应该做的事情

这需要更多的挖掘,但我意识到 DHCP 服务器只提供客户端要求的内容。在我的 Windows 7 DHCP Discover 期间,Windows 7 列举了它想要返回的所有 DHCP 选项的列表:

  • 1子网掩码
  • 15域名
  • 3路由器
  • 6域名服务器
  • 44 NetBIOS over TCP/IP 名称服务器
  • 46 NetBIOS over TCP/IP 节点类型
  • 47 NetBIOS over TCP/IP 范围
  • 31执行路由器发现
  • 33静态路由
  • 121无类静态路由
  • 249无类静态路由(微软)
  • 43供应商特定信息

Windows 7未甚至要求MTU

它必须知道它在做什么

Windows必须有一个理由,为什么它没有要求的MTU; 但我不知道它是什么。起初我以为是因为它使用了Path Maximum MTU Discovery。但PMTU仅适用于 TCP 连接,使用 TCP MSS(最大段大小)选项,并要求本地MSS选项正确。

就我而言,TCP MSS 设置(来自 MTU 选项)是错误的。这是1460 bytes

  1500 interface MTU
-   20 bytes IP header = 1480 bytes
-   20 bytes TCP header
= 1460 bytes MSS
Run Code Online (Sandbox Code Playgroud)

这太高了。

注意:当建立 TCP 连接时,我可以确认 Windows 正在使用来自数据包的 1460 字节的MSSSYN

如果不是PathMTU,那又是什么?

Windows 7 在想什么?这里的预期行为是什么?Microsoft 的网络堆栈开发人员认为应该发生什么?

现在假设我的 Internet MTU 实际上是 1472(它是),并假设我的以太网适配器实际上使用8,192字节以太网帧(它确实如此)。一个公司应该做什么?我是否应该走到企业中的每台机器上并输入:

>netsh interface ipv4 set interface interface="Local Area Connection" mtu=1472 store=persistent
Run Code Online (Sandbox Code Playgroud)

这不合理。即使这是合理的,这也不是我要问的。

我试图了解 Windows想要发生什么。我试图了解它应该如何表现。我想在这里学习一些东西。假设我的 Internet 网关是一个 576 字节的 ATM;我如何指示 Windows 7 机器如果他们想发送到 Internet 的 MTU 是 576 字节?

奖励阅读

Pau*_*aul 5

路径 MTU 不仅仅是 TCP 并且不使用 MSS(尽管正如您所猜测的,MSS 是从 MTU 派生的)。任何接收到太大而无法转发的数据包的跃点都会将ICMP fragmentation needed数据包发送回原点。这是第 3 层的一部分,独立于 TCP。

PMTU 的问题是传入的 ICMP 数据包经常被丢弃或不转发到源,因此源不知道减小数据包大小。

由于您的路由器知道下一跳 MTU 是 1472,因此它应该向您的客户端发送 PMTU 数据包。您可以使用wireshark检查这一点,如果没有这样做,则需要修复。

您有几个解决方法。一种是将路由器的 MTU 内部接口设置为 1472,这意味着它会在路由器进行任何处理之前执行操作。另一个选项是(如果您可以使用路由器执行此操作)是为每个数据包打开 DF 位。这是一种非常残酷的解决方法,因为任何全尺寸数据包最终都会成为两个单独的数据包,一个小,一个大,从而产生开销。

在企业环境中,这三种方法都可以使用,但在路由器 LAN 接口上硬设置 mtu 是很常见的。

(我从未遇到过使用 DHCP 来调解 MTU 的实例,在大多数情况下这不是正确的地方,因为内部 MTU 和边界 MTU 通常不同,您可能会在内部使用巨型帧,但需要减少互联网流量的正常大小)

  • 如果您实施 @Paul 的解决方法(即使全部),最终使客户端接口具有更高的 MTU,您将遇到一些与极少数合作伙伴的 TLS 握手失败。但这仍然非常烦人,因为您将很难找到它,因为大多数连接(即使使用完全相同的技术)都可以工作。到目前为止,我还不知道为什么会发生这种情况,但我来到这里是因为 Windows 服务器与 Backblaze B2 的连接由于使用所有解决方法的设置中的 MTU 而失败。我记得几年前 PayPal 服务器也发生过类似的情况。所以只是留下这个评论作为提示...... (2认同)