写点什么

聊聊 IP packet 的 TTL 与 tcp segment 的 MSL

  • 2023-04-26
    湖北
  • 本文字数:2048 字

    阅读完需:约 7 分钟

1 前言 - 网络知识的重要性

近几年在排查解决应用系统在客户现场遇到的复杂问题时,越来越觉得除了扎实的 LINUX 操作系统知识,对 TCP/IP 网络知识的深入理解也是至关重要的。


有鉴于此,后续笔者会陆续分享一些网络基础知识和故障排查案例,有兴趣的可以深入交流下。


本文介绍下 IP packet 的 TTL 与 TCP segment 的 MSL,两者都跟数据包在网络上的生存时间有关。

2 IP packet 的 TTL

IP 数据报头部中有个 TTL 字段,TTL 是 time to live 的缩写,即生存时间,不过其单位不是秒或分钟等具体时间,而是代表一个 IP 数据报可以经过的最大路由数,IP 数据报每经过一个路由器,它的值就减 1,当此值为 0 时该数据报就会被丢弃,同时发送 ICMP 报文通知源主机。TTL 的初始值是由发送该数据报的源主机设置的,不同操作系统 TTL 的初始值可能不同,比如 Windows 的 TTL 的初始值是 128,而 Linux 的 TTL 初始值大多是 64。


有没有办法查看 TTL 呢?可以通过 tcpdump 或 wireshark 等抓包工具查看某个具体数据报的 TTL:



事实上有经验的同学,可以根据数据包的 TTL,推测这批数据包的捕获点是客户端服务端还是中间端。(后续有机会再总结下)。

3 TCP segment 的 MSL

MSL 是 Maximum Segment Lifetime 的英文缩写,可译为“报文最大生存时间/最长报文段寿命”,它是任何 TCP segment 在网络上存在的最长时间,超过这个时间该报文就会被丢弃,也就是说任何 TCP Segment 在网络上的存活时间都不会超过 MSL.


RFC793 定义了 MSL 为 2 分钟,但这完全是从工程上来考虑,对于现在的网络,MSL=2 分钟可能太长了一些,因此不同的 TCP 实现可以根据具体情况配置使用更小的 MSL。


那么如何查看 MSL 的值呢?在 LINUX 中事实上并没有直接配置 MSL 而是配置了 tcp_fin_timeout,由于 tcp_fin_timeout=2MSL,所以我们可以查看 tcp_fin_timeout 并据此推断 MSL:


### 查看 tcp_fin_timeoutsysctl net.ipv4.tcp_fin_timeout cat /proc/sys/net/ipv4/tcp_keepalive_time ### 修改 tcp_fin_timeoutsysctl -w net.ipv4.tcp_fin_timeout=30  或编辑 /etc/sysctl.conf  
复制代码



如上图可见,LINUX 中默认 net.ipv4.tcp_fin_timeout 的值是 60s,所以 MSL 默认是 30s.


事实上,通过命令 ss -no state time-wait 就能看到处于 time-wait 状态的 tcp 连接,并能看到其剩余的超时时间:



所以概括起来,IP 的 TTL 与 TCP 的 MSL,两者都跟数据包在网络上的传输与生存时间有关,两者不能直接在数值上对比大小,但在效果上 MSL 要大于 TTL。

4 TCP 四次挥手的状态转移与 MSL

下面我们来看几张 TCP 四次挥手释放连接的图示:





从上图可以看到,在 TCP 连接释放的过程中,从 TIME_WAIT 状态到 CLOSED 状态有一个超时设置,这个超时设置是 2MSL(RFC793 定义 MSL 为 2 分钟)。


那么为什么在 TIME_WAIT 后必须等待 2MSL 时间呢?主要原因有两点:


  • 为了保证客户端(我们记为 A 端)发送的最后一个 ACK 报文段能够到达服务器端:这个 ACK 报文段在网络传输过程中有可能丢失,从而使处在 LASK—ACK 状态的服务端(我们记为 B 端)收不到对已发送的 FIN 报文段的回包,此时 B 会超时重传这个 FIN 报文段,而 A 就能在 2MSL 时间内收到这个重传的 FIN 报文段,接着 A 重传一次确认,重新启动 2MSL 计时器。最后,A 和 B 都正常进入到 CLOSED 状态。如果 A 在 TIME_WAIT 状态不等待一段时间,而是在发送完 ACK 确认后立即释放连接,那么就无法收到 B 重传的 FIN 报文段,因而也不会再发送一次确认报文段,这样,B 就无法正常进入 CLOSED 状态。

  • 假如 A 发送的第一个请求连接报文段丢失而未收到确认,A 就会重传一次连接请求,后来 B 收到了确认,建立了连接,数据传输完毕后,就释放了连接。这种情况下 A 共发送了两个连接请求报文段,其中第一个丢失,第二个到达了 B。假如现在 A 发送的第一个连接请求报文段没有丢失,而是在某些网络节点长时间滞留了,以至于延误到连接释放后的某个时间才到达 B,这本来是已失效的报文段,但 B 并不知道,就会又建立一次连接。而等待的这 2MSL 就是为了解决这个问题的,A 在发送完最后一个确认报后再经过时间 2MSL,就可以使本链接持续时间内所产生的所有报文段都从网络中消失,这样就可以使下一个新的连接中不会出现这种旧的连接请求报文段。


由于从 TIME_WAIT 状态到 CLOSED 状态有一个 2MSL 的超时等待时间,该时间内如果有其它新建的连接尝试使用同样的端口,就会报端口不可用的错误,比如笔者在折腾 apache kyuubi 时就遇到了如下错误:


5 网络相关资料推荐

为了深入了解网络知识并掌握网络故障的排查,笔者阅读了大量资料,一些比较推荐的资料如下:


  • 《TCP_IP 详解卷 1:协议》,经典无需多言,笔者收藏了英文第二版的原版,时不时翻出来阅读下;

  • 《TCP_IP 详解卷 2:实现》,经典无需多言,推荐英文原版;

  • 《图解 TCP IP(第 5 版)》,(日)竹下隆史老师所著,也很不错;

  • 《Wireshark 网络分析的艺术》,林沛满老师的书籍,以现实故障案例讲知识,诙谐易懂;

  • 《Wireshark 网络分析就这么简单》,林沛满老师的书籍,以现实故障案例讲知识,诙谐易懂;

  • 《Network Analysis using Wireshark2 CookBook》,讲解网鲨工具的使用,推荐;

  • 历年 SharkFest 的精彩分享,可以在油管上看,笔者重点看了近三年的视频。

发布于: 刚刚阅读数: 3
用户头像

Keep Striving! 2018-04-25 加入

明哥,十四年 IT经验,六年大数据经验; 做过大数据集群的搭建运维,大数据应用系统的开发优化,也做过大数据平台的技术选型以及架构咨询; 目前聚焦于泛大数据生态,包括数据仓库/数据湖,云计算和人工智能。

评论

发布
暂无评论
聊聊 IP packet 的 TTL 与 tcp segment 的 MSL_TCP/IP_明哥的IT随笔_InfoQ写作社区