路径最大传输单元发现PMTUD(Path MTU Discovery)是一种TCP/IP协议栈功能,用于动态发现路径上允许的最大传输单元PMTU(Path Maximum Transmission Unit)。当发送的数据包超过路径上某个链路的MTU时,路由器会丢弃该数据包并发送ICMP错误消息给发送方,通知其调整数据包大小,以避免在数据传输过程中发生分片。这对于优化网络性能和避免因数据包过大导致的丢包问题非常有用。
PMTUD对网络性能的影响
PMTUD机制通过发送端和网络设备之间的交互来动态地发现并适应网络路径上允许的PMTU。这个过程有助于提高网络的效率和可靠性,同时减少了因分片而导致的潜在问题。
避免IP分片:通过确保数据包大小不超过路径中任何一跳的最小MTU值,PMTUD可以帮助避免在网络中进行IP分片。分片会增加网络设备的处理负担,可能导致数据包丢失和延迟。关于TCP连接中如何避免IP分片,请参见TCP连接中如何避免IP分片。
提高网络效率:通过使用适当的数据包大小,PMTUD有助于减少网络拥塞和提高数据传输效率。较大的数据包可以减少头部开销,提高吞吐量,但前提是路径上的所有链路都能支持这样的数据包大小。
减少丢包和延迟:避免分片可以减少因分片引起的丢包和延迟问题,因为分片后的数据包如果任何一个片段丢失,整个原始数据包都需要重新传输。
自动调整数据包大小:PMTUD允许发送端根据网络路径上的实际MTU动态调整数据包大小,而不需要事先知道网络的具体配置。
提高网络的健壮性:通过动态发现路径上的MTU,PMTUD有助于网络适应不同的链路类型和配置,提高了网络的健壮性和灵活性。
支持PMTUD的组件或系统
操作系统:许多现代操作系统都支持PMTUD,包括但不限于Linux、Windows等。当前阿里云ECS实例普遍支持PMTUD。
网络设备:一些先进的网络设备,如路由器和交换机,可能内置了PMTUD功能,可以在数据包通过时自动进行PMTUD处理。但并非所有设备都支持PMTUD,不支持PMTUD的设备在收到大于自身MTU长度且设置了DF标志的IP数据包时,回送给发送端的ICMP消息里可能不会包含其MTU值。
中间件或库:在某些编程环境中,可能会提供专门的库或中间件来处理PMTUD。
应用程序:一些网络应用程序可能会实现自己的PMTUD逻辑,以便在发送数据包时动态调整数据包大小。
网络协议:PMTUD普遍适用于基于IPv4和IPv6的传输层协议,包括但不限于TCP、UDP和ICMP等。
云服务提供商:阿里云的网络转发组件会依据RFC标准进行PMTUD处理,以保证网络连通性。详细信息,请参见PMTUD工作原理。
PMTUD工作原理
PMTUD通过在IP数据包中设置“不分片”标志(DF=1),并利用ICMP消息动态发现和适应两个网络主机之间通信路径上允许的PMTU,以避免数据包在传输过程中被分片。具体工作过程如下:
发送端设置DF标志:当发送端主机发送IP数据包时,设置IP头部的“不分片”(DF)标志位为1,表示在网络路径上不允许对该数据包进行分片。
遇到MTU限制:当设置了DF为1的数据包在传输过程中遇到一个MTU更小的网络设备或链路时,如果数据包的大小超过了该设备的MTU,那么该设备会丢弃该数据包。
IPv4协议中:可以根据DF标志的选择来决定是否执行PMTUD。如果DF标志位为0,且该网络设备支持分片,那么当数据包大小超过路径上某个节点的MTU时,该节点可能会对数据包进行分片,而不是丢弃它。
说明对于阿里云上部分不支持分片的转发设备(例如专线、跨域等通信场景下边缘网关),即使DF标志位为0,也不会分片,而是丢弃数据包,然后发送ICMP错误消息。
IPv6协议中:PMTUD是强制性的,要求所有主机和路由器必须支持PMTUD,因此IPv6数据包的DF标志是隐含设置的,所有数据包都被视为设置了DF=1。
发送ICMP错误消息:丢弃数据包的网络设备如果支持PMTUD,则会向发送端主机发送一个ICMP的错误消息,通知发送方发生了MTU问题。这个消息中包含了该网络设备的MTU(即从源端主机到该网络设备之间的PMTU)。
对于IPv4协议,设备会发送一个ICMP“需要分片但设置了不分片”(Type 3, Code 4)的错误消息回给发送方。
对于IPv6协议,设备会发送一个ICMPv6“包装失效”消息(Type 2, Code 0)给发送方。
PMTU发现及消息处理:发送端主机收到ICMP错误消息后,解析并缓存PMTU,然后根据ICMP消息中提供的MTU值进行如下处理:
默认情况下,发送端主机的操作系统内核会对数据包按照ICMP消息中提供的MTU值进行分片,然后重新发送分片后的数据包。
应用程序适配并处理ICMP消息:当支持PMTUD的应用程序收到这类ICMP消息时,可以根据ICMP消息中的MTU,调整数据包的大小,然后重新发送调整后的数据包。这种方式能通过避免网络分片获得更好的网络性能,但是一般情况下,要求对应用程序做相应修改才能实现。
说明对于TCP连接,PMTUD的发现结果会影响到TCP层的MSS值。TCP层会根据PMTU值调整MSS,使用新的MSS值来发送后续的数据包,以确保TCP数据段不需要在网络层被分片。详细信息,请参见数据传输过程中适配PMTUD机制动态调整MSS避免分片。
缓存PMTU值:发送端主机会在操作系统的路由表中生成一条路由缓存,包含发往该目的IP的MTU值,作用于后续发往同一目的地的数据包,以避免在网络路径上发生分片。
定期更新PMTU:PMTU值不是永久不变的,当网络路径发生变化或操作系统路由缓存老化时,主机会重新进行PMTUD过程,以更新PMTU值。
如何合理使用PMTUD
启用PMTUD
您需要确保网络中的所有设备都支持并启用了PMTUD(例如在Linux系统中,/proc/sys/net/ipv4/ip_no_pmtu_disc文件内容为0)。当前阿里云ECS实例普遍支持PMTUD。
老旧的内核版本或者特定类型操作系统可能不支持PMTUD,导致无法正确处理PMTUD过程中的ICMP消息,从而无法动态发现路径上的允许的PMTU。
如果设备不支持,您可能需要通过手动的方式确认MTU(例如,使用ping命令手动探测PMTU),然后调整发送端数据包大小或者调整网络设备的MTU(例如,手动修改网络接口的MTU)。
确保发送端可以接收ICMP差错报文
检查并配置防火墙和安全设备:您需要检查并配置防火墙和安全设备,以允许必要的ICMP消息通过。在某些网络环境中,防火墙或其他安全设备可能会过滤掉ICMP消息,特别是类型3代码4的“ICMP需要分片但DF设置”消息,这会阻断PMTUD过程。
安全组放行ICMP流量:ECS实例响应PMTUD需要实例的安全组放行ICMP流量以接收来自不同转发组件的ICMP协商数据包。详细信息,请参见安全组应用案例之特定协议访问。
检查网络流量是否达到限速值:网络流量太高可能会导致ICMP消息被丢弃。您可以检查网络流量是否达到限速值。
对于Linux实例,请参见如何查看Linux系统网络流量负载情况?
对于Windows实例,您可以通过任务管理器查看网络使用情况。
应用适配响应ICMP消息
修改应用程序以响应PMTUD中的ICMP错误报文,并根据PMTU调整数据包大小(缩小数据包长度)。
如果应用程序没有适配PMTUD机制,或者在接收到PMTUD相关的ICMP消息后没有适当调整数据包大小。这可能导致操作系统内核对数据包进行分片,造成数据包无法成功传输。
如果应用程序无法适配PMTUD动态调整数据包大小,您可以在应用程序中手动设置一个较小的MSS值,以适应PMTU。
TCP连接中如何避免IP分片
TCP是一个面向连接的、可靠的传输层协议,旨在确保数据的完整性和顺序。IP分片可能导致分片丢失或重组错误,影响TCP传输的可靠性。通过MSS协商和PMTUD机制,TCP连接可以在大多数情况下避免IP分片,从而提高网络性能和可靠性。
建立连接时通过MSS协商机制避免发生IP分片
最大报文段长度MSS(Maximum Segment Size)是传输控制协议TCP中的一个参数,它指定了TCP层在每次传输中能够发送的最大数据量,不包括TCP头部。
MSS的协商是TCP/IP协议栈内部自动处理的,无需用户或应用程序的直接干预。这个过程确保了数据段的大小适合于两端的网络环境,避免了因数据包过大而导致的分片或因数据包过小而导致的效率降低。
在建立TCP连接的过程中,双方会通过TCP三次握手进行MSS的协商。在SYN报文中,发送端会包含一个MSS选项,这个值通常是基于该端点的MTU减去IP和TCP首部的固定开销得出的。接收端收到SYN报文后,会根据自己的MTU来确认一个合适的MSS值,并在SYN+ACK报文中返回给发送端。这样,双方就确定了通信时使用的最大段大小,从而有助于避免因IP分片带来的效率降低和重传问题。
数据传输过程中适配PMTUD机制动态调整MSS避免分片
MSS协商并不能保证在传输路径中的所有网络设备(如路由器)的MTU都大于或等于协商的MSS值。如果传输路径中的某个网络设备的MTU小于TCP数据包的大小,即使MSS已经协商过,仍然可能发生IP层的分片。另外,无连接的协议,如UDP、ICMP等没有MSS协商机制。此时,PMTUD机制就尤为重要。PMTUD允许通信双方动态地发现整个传输路径上允许的PMTU,应用通过适配响应ICMP错误消息,并据此调整MSS值,以避免分片的发生。