Cancel

Path MTU Discovery

Network

·

August 06, 2022

This RFC is release on 1990.11 obsoletes RFC1063 which is released on 1988.07

1. Protocol Overview

通过设置IP header 的 DF bit 来动态发现一个路径的PMTU1: 以第一跳2的MTU为初始值(已知的),如果收到ICMP code 3-434

由于网络拓扑会随时间改变,PMTU的减少,仍然可以通过DTB meessage得知,只要DF bit 被设置,而PMTU的增加,可以通过主机上的定期任务5来检测。

2. Host(主机)specification

当Host探索PMTU的减少时,速度必须尽可能地快,而探索PMTU的增加时,探索的时间间隔不能频繁(infrequent)6。

更具体地,当探索PMTU的增加时,增加失败的间隔不少于5min,增加成功的间隔不小于1min,建议的间隔分别是是10min和2min。

Host必须向下兼容不包含next-hop MTU的旧风格的DTB message7。

Host估值的PMTU应该不低于68 octets8

3. TCP MSS9 Option

除非被允许,Host进行PMTUD时发送IP包的长度不应该超过 536 + 40 = 576 octets。

而很多TCP实现总是设置MSS选项并且将值设为536,如果目的连接是非本地的。这种行为是对的,因为互联网上到处都是不遵守规则,发送超过576 octets10的的host。

一个host可能根据MTU设置MMS,这不应该对PMTUD造成问题,并且可以劝阻同层发送巨大的数据报

4. Router(路由器) specification

DTB message(ICMP code 3-4) format, 提供额外的origin header,next-hop MTU 不赘叙

5. 处理旧风格的message

即如果message本身没有提供PMTU的信息。

最简单的方式是取当前估计的PMTU与576之间的最小值,并且取消DFbit。

更复杂的方式需要“搜索”准确的PMTU估计值。有几个可能方法,它们根据一个之前的估计值产生一个新的估计值。

比如乘以一个常数比如0.75,但这样收敛又慢,产生的估计值又低于实际的值。所以不推荐。

再比如进行二分搜索,它收敛快一点,但从FDDI11 MTU落到Ethernet12 MTU仍然需要4-5步,而有一个非常的劣势是识别数据报到达另一端的时间是一个复杂实现。因此也不推荐。

有一个看起来效果似乎很好方法是比起盲搜,搜索一组可能出现的值,因为设计者们倾向于用类似的方式选择MTUs,使用其中的最小值13。使用下表的搜索,

Table Common MTUs in the Internet:

Plateau MTU Comments Reference
65535 65535 Official maximum MTU RFC 791
32004 65535 Hyperchannel RFC 1044
17914 17914 16Mb IBM Token Ring  
8166 8166 IEEE 802.4 RFC 1042
  4464 IEEE 802.5 (4Mb max) RFC 1042
4352 4352 FDDI (Revised) RFC 1188
  2048 Wideband Network RFC 907
2002 2002 IEEE 802.5 (4Mb recommended) RFC 1042
  1536 Exp. Ethernet Nets RFC 895
  1500 Ethernet Networks RFC 894
  1500 Point-to-Point (default) RFC 1134
1492 1492 IEEE 802.3 RFC 1042
  1006 SLIP RFC 1055
1006 1006 ARPANET BBN 1822
  576 X.25 Networks RFC 877
  544 DEC IP Portal  
  512 NETBIOS RFC 1088
  508 IEEE 802/Source-Rt Bridge RFC 1042
508 508 ARCNET RFC 1051
296 296 Point-to-Point (low delay) RFC 1144
68 68 Official minimum MTU RFC 791

使用这个表的收敛性最坏情况也比二分搜索相当,因为plateau几乎是2的幂,而如果值不在表中,被低估的值也不会超过2倍。

所有ICMP code 3 都包含源IP header,可以直接使用其中的Total Length字段的值作为输入,生成下一个估计值14。

该表仅是建议参考,应该保持更新,添加一些2的幂加40(IP header + TCP header)的项,作为过渡,也可以包含稍微比2的幂稍小一些的项。但不管怎样,plateau的数量不应该太多,而实现者应该给无源代码客户提供一种方便的更新表值的工具15

6. Host implementation

提供一组关于PMTUD在主机软件上实现的建议。

6.1 Layering(分层)

IP层应该存储PMTU信息,并且ICMP层应该处理DTB message。而分包层16应该能反映PMTU的变化,通过改变发送数据报的大小,并且必须能指定DF bit。我们不希望IP层简单地为每个包设定DF bit,因为分包层可能无法改变它的数据报的大小17

6.2 Storing PMTU Information

存储信息的明显位置是将其作为一个字段,存储在路由表项中。一个主机不会为每一个目标地址有一个路由信息,但应该能为每个活跃目标地址缓存路由18。

使用同一路径的所有的分包层都应该被通知,如果该路径PMTU减少了。这种通知应该区别于普通的包的丢失。

6.3 Purging stale PMTU information

由于没有机制能实现发现当前的使用的PMTU因为它太小而过时了,所以需要一个实现能够老化缓存的值,以便有机会发现的新的更大的PMTU19。而上层协议绝对不能因为PMTU的增加而重发,因为这没有包的丢失。

一个实现PMTU老化的方法是给路由表项添加时间戳字段,这个字段初始化为一个保留值,表明这个PMTU没有改变。当PMTU减少时,时间戳更新为当前时间。计时器驱动的程序扫描整个路由表,当一个表项的时间戳不是保留值时,如果超时了,则:

  1. 将估计的PMTU设置为关联的第一跳的MTU
  2. 使用这个路由的分包层被通知PMTU的增加

PMTU估计值可能从路由表消失,如果路由表项被移除掉20,一个解决方法是当ICMP 重定向消息导致路有变化或者当路由被删除的时候通知分包层

6.4 TCP layer actions

TCP数据报的大小受PMTU和MSS的双重制约。

当DTB message到达的时候,特定连接的特定于DTB message的数据报立刻重传,当然需要使用新的PMTU。

现代TCP实现包含拥塞控制和慢启动算法,DTB message不应该影响拥塞窗口,但是应该触发慢启动机制21。

TCP的性能可能会下降,如果发送方的最大窗口大小22不是精确的分片(segment)大小的几倍。如果使用了PMTUD,分片的大小发生改变,就会出现这种情况。因此应该根据新PMTU的大小调整最大窗口大小,来适应新的分片的大小,使保持一个整数倍的关系。

PMTUD不应该影响MSS选项的数值。

6.5. Issues for other transport protocols

像原始NFS协议这种如果有难处,还是分片传输吧。

6.6. Management interface

一个PMTUD的实现应该为系统工具程序提供:

  1. 指定不在给定路由上做PMTUD23
  2. 改变给定路由的PMTU
  3. 改变PMTU老化的时间间隔

7. Likely values for Path MTUs

合并到第五章

8. Security considerations

通过发送恶意DTB message可以实现两种DOS攻击:

  1. 提供过于小的PMTU,使得连接变慢
  2. 提供过于大的PMTU,这可能会造成暂时的阻塞,因为受害者的包会被路由器丢弃,在一个往返的时间里,主机会发现错误,但频繁的重复攻击会导致大量的数据报被丢弃。而一个主机永远不能根据DTB message提供的PMTU来提高估计值的上限,因为这会使得面对这种攻击变得很脆弱。
  1. Path MTU ↩

  2. First Hop ↩

  3. Fragmentation required, and DF flag set, carrying next-hop MTU and IP header and first 8 bytes of original datagram’s data ↩

  4. 也就是PTB(Packet Too Big) message,或者DTB(Datagram Too Big) message ↩

  5. 发送更高的PMTU假设的数据包,看是否能通过,大多数情况下PMTU不会改变,因此不应该太频繁地启用。 ↩

  6. 因为需要发送比当前估计的PMTU更大的数据报,并且PMTU不太可能增加 ↩

  7. 可以通过检测next-hop MTU字段是否为0,来识别旧风格的DTB,根据ICMP的规定,未使用的字段必须为0 ↩

  8. 1 octect = 1 byte in CPU = 8 bit ↩

  9. Max Segment Size, IP datagram size minus IP header and TCP header (40 bytes, totally) ↩

  10. 576 is safe max IP datagram size for TCP, or 536 for MSS ↩

  11. Fiber Distributed Data Interface, 光纤网,用于校园网、广域网 ↩

  12. 比起FDDI,高带宽效率低,但延迟也低 ↩

  13. as “plateau” ↩

  14. 基于4.2BSD实现的路由器会发送错误的Total length,它额外加上了origin header length,而且以octets而不是4xoctets的形式表现 ↩

  15. BSD 派生的Unix内核提供ioctl来做这件事 ↩

  16. 在IP结构里,发送多大的数据报是由IP上层的协议决定的,我们称这样的协议为分包层(Packetization Layer) ↩

  17. 比如一个内核外的UDP应用, 比如最原始版本的NFS协议,一个跨网络管理文件的系统,这种情况下应该允许分片(fragmentation) ↩

  18. 这个需求已经被处理ICMP重定向消息的需要强制满足了 ↩

  19. 这个时间从上一次PMTU不减开始,以10min为标准 ↩

  20. 这可能发生在ICMP重定向消息或者特定的路由守护进程几分钟后删除了旧的路由信息,还可能是在一个多网卡(multi-homed host)的主机上拓扑的变化可能导致不同网卡的使用 ↩

  21. 也就是只重传第一个分段,直到收到ACK ↩

  22. 最大窗口区别于拥塞窗口,拥塞窗口的大小总是分片大小的几倍,而最大窗口(send space)在很多系统(比如从4.2BSD衍生出来的)通常是1024 octets的几倍,是固定的 ↩

  23. 可以在路由项上设置一个标志位,当有这个标志位时,DF bit一定会被清除,不管上层请求是什么 ↩

© minghu6

·

theme

Simplex theme logo

by golas