BetaThis is a live doc! Anyone with edit access can make updates in real time without having to publish.
2 min
image-20241028-023009.png

概念

  • MTU:maximum transmission unit, 二层协议里面的最大传输单元

  • MSS:maximum segment size

    • MTU - (TCP header + IP header) = MSS

    • MTU - (20 + 20) = MSS

MTU

MTU 受限于物理传输介质

常见的为以太网,MTU 一般为 1500bytes,实际在链路上传输的大小为 MTU + Ethernet header + FCS = 1500 + 14 + 4 = 1518 bytes

MTU 的大小意味着什么

  • MTU 越大,整个传输的效率就越高

    • 原因:MTU 大时,以太网桢的头尾占比较小,实际传输的数据相对更多,所以效率高

    • 注意:受限于物理因素,效率无法无限增加 - MTU 过大时丢失/损坏概率也大,会导致需要重传,效率反而降低

  • MTU 越小,整个传输的延迟越低

    • 链路上同时只能传输一个包,如果一个包过大,其他包可能来不及传输,造成整体延迟增大

超过 MTU 限制会发生什么

绝大多数的系统和物理设计都是丢失

注:部分设备的实际触发 drop 的 MTU 和声明的最大 MTU 不同(留有一定的缓冲区间)

jumbo frame

Jumbo Frame 可以最大支持 9000 bytes,提高传输的速率。不过现实中基本上见不到、互联网上更见不到

因为 Ethernet 是 2 层协议,负责点对点的传输,如果因特网上如果一个 Jombo Frame 要能从用户传到另一个用户或服务,这需要所有点对点设备都要支持才行

而现实的世界里,基本上网络上所有的路由,交换设备,端设备,路由器,设置的 MTU 都是 1500

MSS

如何修改 MSS

  1. iptables: iptables -I OUTPUT -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss 48

  2. ip route: ip route change 192.168.11.0/24 dev ens33 proto kernel scope link src 192.168.11.111 metric 100 advmss 48

  3. 程序想办法自己往 TCP option 里写 MSS

MSS Calmping

包可能不是直接传输的,中间可能经过了隧道,而隧道自己也有一些元数据需要控制

因此隧道传输时,可能修改包信息降低告知对端的 MSS

MSS 过大会造成什么?

IPv4

如果 MSS > MTU - headers(对于以太网,即大于 1460bytes),那么会导致 IP 分片

IP 分片在实际生产中是避免的 —— 因为若干弊端,都会尽量避免 IP 分片

  • 只能整体重传

    • 如果一个包因为 IP 分片变成了 3 个 fragment,包丢失必须 3 个 fragment 一起重传

  • 处理延迟

    • 对端会等所有的 fragment 到达才会交给上层处理

  • 某些系统是不支持(或特意禁用了)IP Fragment

IPv6

IPv6 是禁止 IP 分片的(IPv4 可以通过指定 DF bit 来禁止分片)

当 MTU 过大时,会直接丢弃包然后回复一个 ICMP 包(Type = 3,Code = 4)

引申:当 ICMP 包被禁用 / 错误路由,会导致黑洞连接

TSO

TCP Segment Offload

在机器上抓包时可能发现「发送的数据大于 MSS」,这是因为如果网卡支持 TSO,那么内核会将 TCP 拆包的工作转移给网卡进行

同理,接收时,开启 TSO 的情况下网卡也可能直接完整 TCP 组包

可以通过 ethtool -K eth0 tx off 关闭 TSO

参考

https://en.wikipedia.org/wiki/Maximum_transmission_unit

https://www.kawabangga.com/posts/4983