聊聊 IP packet 的 TTL 与 tcp segment 的 MSL

简介: 聊聊 IP packet 的 TTL 与 tcp segment 的 MSL

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:

image.png

事实上有经验的同学,可以根据数据包的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_timeout
sysctl net.ipv4.tcp_fin_timeout 
cat /proc/sys/net/ipv4/tcp_keepalive_time 
### 修改 tcp_fin_timeout
sysctl -w net.ipv4.tcp_fin_timeout=30  
或编辑 /etc/sysctl.conf


image.png

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

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

image.png


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

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

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

image.png

image.png


image.png

从上图可以看到,在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时就遇到了如下错误:

image.png


5 网络相关资料推荐

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

  • 《TCP_IP 详解卷1:协议》,经典无需多言,笔者收藏了英文第二版的原版,时不时翻出来阅读下;
  • 《TCP_IP 详解卷2:实现》,经典无需多言,推荐英文原版;
  • 《图解TCP IP(第5版)》,(日)竹下隆史老师所著,也很不错;
  • 《Wireshark网络分析的艺术》,林沛满老师的书籍,以现实故障案例讲知识,诙谐易懂;
  • 《Wireshark网络分析就这么简单》,林沛满老师的书籍,以现实故障案例讲知识,诙谐易懂;
  • 《Network Analysis using Wireshark2 CookBook》,讲解网鲨工具的使用,推荐;
  • 历年 SharkFest 的精彩分享,可以在油管上看,笔者重点看了近三年的视频。
相关实践学习
通过Ingress进行灰度发布
本场景您将运行一个简单的应用,部署一个新的应用用于新的发布,并通过Ingress能力实现灰度发布。
容器应用与集群管理
欢迎来到《容器应用与集群管理》课程,本课程是“云原生容器Clouder认证“系列中的第二阶段。课程将向您介绍与容器集群相关的概念和技术,这些概念和技术可以帮助您了解阿里云容器服务ACK/ACK Serverless的使用。同时,本课程也会向您介绍可以采取的工具、方法和可操作步骤,以帮助您了解如何基于容器服务ACK Serverless构建和管理企业级应用。 学习完本课程后,您将能够: 掌握容器集群、容器编排的基本概念 掌握Kubernetes的基础概念及核心思想 掌握阿里云容器服务ACK/ACK Serverless概念及使用方法 基于容器服务ACK Serverless搭建和管理企业级网站应用
相关文章
|
7月前
|
缓存 网络协议 算法
深入TCP协议——tcp_tw_reuse和tcp_tw_recycle
前情提要:深入理解Linux网络——TCP协议三次握手和四次挥手详细流程 我们已经知道TCP四次挥手中,主动方在收到被动方的FIN数据包之后会进入TIME_WAIT状态等待2MSL的时间后才进入CLOSED。在 Linux 操作系统下,TIME_WAIT 状态的持续时间是 60 秒,这意味着这 60 秒内,客户端一直会占用着这个端口,这是有一定的开销的。如果如果主动关闭连接方的 TIME_WAIT 状态过多,占满了所有端口资源,则会导致无法创建新连接。
|
网络协议 安全 Unix
TCP MSS选项
本文档是 Internet 工程任务组 (IETF) 的产品。它代表了 IETF 社区的共识。它已接受公众审查,并已获互联网工程指导小组 (IESG) 批准出版。并非 IESG 批准的所有文件都适用于任何级别的互联网标准;请参阅 RFC 5741 的第 2 节。
189 0
|
网络协议 安全 Unix
TCP 选项和最大分片大小 (MSS)
本文档是 Internet 工程任务组 (IETF) 的产品。它代表了 IETF 社区的共识。它已接受公众审查,并已被互联网工程指导小组 (IESG) 批准出版。并非所有 IESG 批准的文件都适用于任何级别的互联网标准;请参阅 RFC 5741 的第 2 节。
661 0
|
网络协议
OGG-01232 Receive TCP params error: TCP/IP error 104 (Connection reset by peer), endpoint:
源端: 2015-02-05 17:45:49 INFO OGG-01815 Virtual Memory Facilities for: COM anon alloc: mmap(MAP_ANON) anon free: munmap file alloc: mmap(MAP_SH...
3127 0
|
SQL 网络协议
[20180126]内核参数tcp_keepalive.txt
[20180126]内核参数tcp_keepalive.txt --//linux内核参数tcp_keepalive,用来检查网络链路是否有效.缺省: # echo /proc/sys/net/ipv4/tcp_keepalive* | xargs   -n 1...
1145 0

热门文章

最新文章