前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >TCP的MTU Probe和MSS(1)

TCP的MTU Probe和MSS(1)

作者头像
glinuxer
发布2019-04-10 11:19:36
4.8K0
发布2019-04-10 11:19:36
举报
文章被收录于专栏:专注网络研发

在前面两篇文章中,我们研究了在TCP三次握手时MSS选项的值:一般情况下,都是由出口路由的MTU大小决定:MTU-40。也就是说,TCP在握手阶段,通过MSS选项,通知对端本端可以接收的最大报文长度是多少。

但是TCP连接只是一个“虚拟”的连接,其下层是无连接的IP网络。在IP网络中,数据包的传输路径是可变的,也就是说一个TCP连接,其报文可能从不同的IP路径传输到对端。不同的传输路径,自然会经过不同的网络设备,其MTU值自然不同。这样的话,即使对端按照MSS的值发送TCP报文,也可能会超过其中间路径的MTU值,导致数据包发送失败。

这就引出了一个问题:TCP如何避免这种PMTU(Path MTU)发生变化的情况呢?这就引出了TCP PMTU Probing。这个TCP功能是一个系统级别的参数,可以通过/proc/sys/net/ipv4/tcp_mtu_probing来打开这个功能。

在内核发送或者接收syn报文时,就会调用tcp_mtup_init。

这个函数负责MTU探测的初始化,设置当前探测的上限、下限等。这里的下限比较明确,是通过系统设置的最小MSS值(默认为512字节)转换为MTU(加上40字节)。上限则是由rx_opt(接收的对端选项)的mss_clamp决定的。对于主动连接来说,其值为MSS的默认值(目前是536字节,在RFC1122和RFC2581中定义)。

那么探测的行为什么时候发生呢?第一个念头是通过定时器,定期的去探测PMTU。然而这实际上是非必要的。内核在这块的处理比较巧妙。MTU探测的工作函数tcp_mtu_probing是在tcp_write_timeout中调用的。

当TCP重传超过设置的sysctl_tcp_retries1值(/proc/sys/net/ipv4/tcp_retries1)时,就会调用tcp_mtu_probing。当PMTU小于MSS时,TCP报文就会传输失败——因为默认情况下,系统都会设置禁止IP分片,这时就需要进行tcp_mtu_probing。

接下来,我们来看tcp_mtu_probing的代码。

在这份代码中,MTU的下线探测还是比较激进的。首先,取探测下限search_low计算的MSS的一半值,然后与系统配置的tcp_base_mss相比,取较小值。这个较小值,不能低于可能的最小值68-tcp_header_len,并根据结果重新设置了探测下限。通过这样的方法,内核会探测到真实的PMTU,从而保证TCP报文可以顺利发送。

因为今天加班比较晚,所以只能把前几天写到一半的文章先发出去了,这里留下了一个问题:从上面的分析可以发现,启用MTU Probe时,目前只会降低MTU大小,这样岂不是导致TCP的报文大小越来越小,从而传输效率越来越低呢。但内核才不会做这种傻事呢,下一篇将分析MTU Probe如何处理MTU增大的情况

(未完待续。。。。。。)

专注于Linux网络开发,每两周一更

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2017-08-28,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 LinuxerPub 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档