为什么要发现路径上的MTU
我们知道,IP报文在发送时,需要判断IP报文大小和发送端口的MTU(Maximum Transmission Unit,MTU),如果IP报文大于发送端口的MTU,报文需要分片后再发送,以保证发送的报文大小不超过发送端口的MTU。
这种场景,对于TCP报文是不适应的。
因为如果TCP报文被路径上某个路由器分片后发送,那么不同的分片到达目的端的时间不一样,那么TCP的RTT就无法正确评估,进而影响TCP对路径拥塞程度的判断。
所以TCP需要有个机制,能发现中间路由设备的MTU,避免报文分片。
TCP是如何进行路径MTU发现的
Tcp根据对比本地发送端口的MTU和对端的MSS,选择发送报文的大小,同时设置所有报文ip头里的DF标志(不允许中间路由器分片),当中间路由器转发这个报文时候,发现报文大小大于发送端口的MTU,路由器就丢掉这个报文,并发送一个ICMP“不能分片”的差错通告。
发送端收到这个ICMP报文,就获知中间路由的MTU大小,并按照路由器MTU大小重传报文。
由于ICMP“不能分片”导致的重传,拥塞窗口不需要变化,但是需要慢启动。
由于网络路径是不停变化的,隔一段时间,发送方可以尝试再次发送较大长度的报文,如果路径变化,路径已经切换到更大MTU的路由器上,这种尝试是可以提高发送效率的。这种尝试一般会在10分钟~30分钟之后触发。
一个路径MTU探测的例子
tcp路径MTU发现
1、报文1、2、3为tcp握手,协商接收方mss=512
2、报文4发送512字节,同时报文5使用FIN拆掉链接
3、路由器转发报文4时候由于MTU原因丢弃了报文4,路由器发送报文6通知客户端ICMP“不能分片”差错和路由器本地mtu=296
4、客户端使用报文8和报文10分别重发这2*256个字节,即重传报文报文4