TCP断开时的状态与Linux nf_conntrack

题目有点大了,但是难免有一些愤怒!
我们的网关产品目前处在系统测试阶段,不太顺利,是太不顺利!各方面都在懈怠,包括我!我除了懈怠,还在找机会逆袭!顺便蔑视一下测试者,希望产生一种想象,即他发现的问题其实不是问题,而是因为他的无知所导致!就在昨天,机会来了,我便气扬了!

很多人觉得我是下三层网络的专家,对于TCP之类的无权问津,但是我对TCP除了辱骂还是辱骂!因为它太复杂了,作为一个低层的设施,如果太复杂,应用层
的复杂空间便小了!编程的人,特别是socket编程的人,总是将IP以及网卡作为一个黑盒子,而着重看待TCP,他们对UDP是不屑一顾的,也不会关注
什么非合作UDP流量。这是搞通讯网络和人和编程的人的本质区别,毕竟分工不同。但是我也是从研究TCP开始的,起初我并无法触及路由器之类的东西,更不
晓得什么流量工程,可是到了后来当我懂了IP以后,我发现IP是多么的美妙,可以让人瞬间高潮!而TCP,就是一团乱麻,在产品系统测试的时候,一个
TCP的疑难杂症可以让一个研发人员折腾一下午甚至好几天,而这几天时间,测试人员爽了,没什么事,可以聊天,看新闻,这是多么悲哀,让人没法释怀!真
TMD想给测试人员上椅刑!旋转升降座椅一定会爆炸,菊花残,满地伤,花落人断肠!
       只可惜,昨天的事在我愤怒状态时,彻底灭了这种格局!事情是这样的。
客户端A:128.129.1.2
网关外网口(连接客户端):128.129.1.1
网关内网口(连接服务器):192.168.220.223
服务器:192.168.30.75

网关上做NAT的redirect转换,将访问服务器的流量重定向到本地的apache服务器,apache服务器行使正向代理功能(正向代理是一个重要概念,请深入理解)。规则如下:
iptables -t nat -A PREROUTING -d 192.168.30.75 -j REDIRECT --to-ports 80
多么简单的规则,然而多么痛的领悟。

测试人员,严格说是黑盒测试人员(非白盒),测试功能就算了,不影响业务就可以了,偏偏要搞什么抓包,关键是抓包还误会我们!问题如下:
连接的建立以及数据的传输,均经过了代理,但是连接的拆除却没有被NAT,直接forward出去了,导致192.168.30.75服务器直接接收到了源IP地址为128.129.1.2的数据包。这是怎么回事?!
       实际上,这是毫无影响的,只要应用程序能够坚持足够长的时间!

我发现,这是服务器30.75主动断开的连接,也就是它主动发送了FIN,此后客户端发送了ACK,然而客户端迟迟没有发送自己方面的FIN,过了两分钟
才发送了FIN/ACK,此时连接只是单方面断开了。此时,在客户端没有发送FIN之前,它处在CLOSE_WAIT状态。由于目前的产品是基于前一个产
品构建的,在前一个产品中,我由于一些特殊的原因将conntrack的和TCP相关的timeout都减到了足够小,比如我将TCP的
conntrack的establish的timeout减少到了120秒(默认是5天),因此断开连接时的各状态timeout更小,因此在两分钟
内,conntrack早就删除了!
      
此时客户端的FIN来了,由于conntrack已经删除,网关会为其建立一个新的conntrack吗?这要看有没有设置loose,我当然设置了,也
就是不再以syn为建立新conntrack的依据,按理说,Linux网关会创建一个新的conntrack,然而它携带了fin标志!这就意味着
Linux不会创建新的conntrack!因此数据包就直接forward了。但是这不会造成什么影响!因为携带fin的数据包拥有自己的控制通道
timeout期限。到期后会自动转换,这是和establish状态的截然不同!这是为什么呢?
      
这样从TCP/IP的设计说起。有一种设计方案叫做带内控制,也就是控制通道和数据通道共享一条网络路径,TCP协议就是这种设计的典型,另一种就是
IP,比如ICMP就是IP的控制协议,然而你不能说IP不是一种完全的带内控制,它虽然和TCP有所区别,那只是因为它的无状态所致!

TCP的控制通道用标志来区分,携带SYN,FIN的数据段都是控制段,Linux的conntrack对TCP的行为就是以这种控制标志为依据的,如果
来了一个establish的数据包-没有syn,没有fin,没有查找到conntrack,在设置loose标志的情况下,Linux为创建一个新的
conntrack项,然后对于控制信号,比如fin段,就不同了,Linux不会创建。然而这并不影响终端的结果,虽然由于Linux没有NAT成功导
致了数据不会正确到达服务器,可是由于已经fin了,终端会自动用timeout处理。
       但是一定要注意方向,这可能会稍微带来一些问题。如果主动发出的FIN被拦截,会有大问题吗?不会的,因为主动发出FIN的一端不管它会不会被拦截,都会更改状态,而被动关闭的那一端虽然收不到FIN,也会行使超时重传限制权利,虽然可能慢一点。
       持续饥饿!保持饥饿!

时间: 2024-10-07 10:40:45

TCP断开时的状态与Linux nf_conntrack的相关文章

jmeter测试接口-打开很多TCP的连接数TIME_WAIT状态(Linux环境)导致报错的解决方法

一 发现问题: 服务器是Linux系统,用jmeter测试接口,发现打开很多的TCP连接,[[email protected] bin]# ulimit -n 65535用这个命令设置了总的连接数:进行压测的时候,连接数可能达到50000以上,很容易报错:查看各个状态的TCP个数:netstat -an | awk '/^tcp/ {++s[$NF]} END {for(a in s) print a,s[a]}',发现连接状态TIME_WAIT的状态很多,(统计80端口连接数netstat -

TCP四次挥手时TIME_WAIT状态以及端口号的分类

TIME_WAIT(时间等待计时器)状态是什么? 简单来说,TIME_WAIT状态是四次挥手中服务器向客户端发送FIN终止连接后进入的状态. 四次挥手的过程: 可以看到TIME_WAIT状态存在于客户端收到服务器FIN并返回ACK时的状态. 当处于TIME_WAIT状态时,我们无法创建新的连接,因为端口被占用. 2. 为什么会有TIME_WAIT状态? 原因如下两点: <1> 可靠的终止TCP连接 若处于TIME_WAIT的客户端发送给服务器确认报文段丢失的话,服务器将在此重新发送FIN报文

TCP 连接建立和断开,以及状态转换

1. TCP报文结构 TCP是一种可靠.面向连接.全双工的传输层协议,其报文格式如下所示:      源端口.目的端口:16位长.标识出远端和本地的端口号.     顺序号:32位长.表明了发送的数据报的顺序.     确认号:32位长.希望收到的下一个数据报的序列号.     TCP协议数据报头长度,因为TCP首部长度不固定.     头长:4位长.表明TCP头中包含多少个32位字.接下来的6位未用. ACK:ACK位置1表明确认号是合法的.如果ACK为0,那么数据报不包含确认信息,确认字段被

TCP/IP协议--TIME_WAIT状态存在的原因

1. 实际问题         初步查看发现,无法对外新建TCP连接时,线上服务器存在大量处于TIME_WAIT状态的TCP连接(最多的一次为单机10w+,其中引起报警的那个模块产生的TIME_WAIT约2w),导致其无法跟下游模块建立新TCP连接. TIME_WAIT涉及到TCP释放连接过程中的状态迁移,也涉及到具体的socket api对TCP状态的影响,下面开始逐步介绍这些概念. 2. TCP状态迁移        面向连接的TCP协议要求每次peer间通信前建立一条TCP连接,该连接可抽

TCP/IP 协议工作原理与Linux系统下调优

TCP/IP建立连接的三次握手过程: 建立TCP连接共需要三个packet Client--> syn=1,ack=0,fin=0 -->  Server Client<--  syn=1,ack=1,fin=0 <--  Server Client-->  syn=0,ack=1,fin=0 -->  Server TCP/IP关闭连接的四个过程: 关闭TCP连接需要四个packet: Client-->  FIN  -->  Server Client&

TCP协议11种状态集!

TCP协议的11种状态集 ### tcp协议11种状态集转换"三次握手5种状态,四次挥手6种状态"服务端:closed-listen-syn_rcvd-established-close_wait-last_ack-close客户端:closed-syn_send-established-fin_wait1-fin_wait2-time_wait-close1. tcp三次握手状态集转换:服务端:(1)closed-listen(开启相应服务),只有在listen状态服务端才可能建立请

TCP之11种状态变迁

1. TCP 之11种状态变迁 TCP 为一个连接定义了 11 种状态,并且 TCP 规则规定如何基于当前状态及在该状态下所接收的分节从一个状态转换到另一个状态.如,当某个应用进程在 CLOSED 状态下执行主动打开时,TCP 将发送一个 SYN,且新的状态是 SYN_SENT.如果这个 TCP 接着接收到一个带 ACK 的 SYN,它将发送一个 ACK,且新的状态是 ESTABLISHED.这个最终状态是绝大多数数据传送发送的状态. 自 ESTABLISHED 状态引出的两个箭头处理连接的终止

机房重构时利用状态模式实现消费时间的计算

在做机房重构时,我们会在学生上下机计算学生上机时间时,会出现消费时间随着基本数据设定表中的数据变化而变化,这里不仅仅是数据的变化,还包括不同时间段内消费时间具体确定问题.主要分为三个时间段的计算 1.准备时间:即在此时间段内,消费金额为0 2.至少上机时间:如果上机时间超过了准备时间,但是少于至少上机时间,那么此时消费时间为至少上机时间 3.按正常消费时间来算:此时,消费时间大于至少上机时间后,则按照正常时间来算 通过对业务的分析,我们发现在不同时间段,最终的消费时间的计算方式是不一样的.如果我

动手学习TCP:服务端状态变迁

上一篇文章介绍了TCP状态机,并且通过实验了解了TCP客户端正常的状态变迁过程. 那么,本篇文章就一起看看TCP服务端的正常状态变迁过程 服务端状态变迁 根据上一篇文章中的TCP状态变迁图,可以得到服务器的正常状态变迁流程如下: CLOSED -> LISTEN -> SYN_RECV -> ESTABLISHED -> CLOSE_WAIT -> LAST_ACK -> CLOSED 具体的将状态跟TCP包关联起来就如下表示: From State To State