TCP-连接管理

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010853261/article/details/82085738

本文主要内容:

  1. TCP连接的建立与终止
  2. TCP参数选项
  3. TCP的路径最大传输单元发现
  4. TCP状态转换
  5. 重置报文段
  6. TCP服务器选项
  7. 与TCP连接管理相关的攻击

1.TCP的状态机

其实网络上的传输,是没有具体的连接的。而TCP的连接其实是在两端维护的一种连接连接,使两端看起来好像连接着一样。所以TCP的状态转变是非常重要的。

下图是TCP连接的状态机的变化图。包括TCP的连接、断开、传输数据的对照图,另外,下面这两个图非常非常的重要,你一定要记牢。
这里写图片描述

这里写图片描述

经常被问到的是,TCP的连接为什么需要三次握手,断开需要四次挥手:

对于建链接的3次握手:
主要是要初始化Sequence Number 的初始值。通信的双方要互相通知对方自己的初始化的Sequence Number(缩写为ISN:Inital Sequence Number)——所以叫SYN,全称Synchronize Sequence Numbers。也就上图中的 x 和 y。这个号要作为以后的数据通信的序号,以保证应用层接收到的数据不会因为网络上的传输的问题而乱序(TCP会用这个序号来拼接数据)。

对于4次挥手:
其实你仔细看是2次,因为TCP是全双工的,所以,发送方和接收方都需要Fin和Ack。只不过,有一方是被动的,所以看上去就成了所谓的4次挥手。如果两边同时断连接,那就会就进入到CLOSING状态,然后到达TIME_WAIT状态。下图是双方同时断连接的示意图(你同样可以对照着TCP状态机看):

这里写图片描述

对于4次挥手:

TCP状态转换图中:ESTABLISHED是通信双方双向传输数据的状态。FIN_WAIT_1、FIN_WAIT_2以及TIME_WAIT状态用一个虚线方款括起来表示主动关闭。图中总共有11种状态:

  1. CLOSED:关闭状态,没有连接活动或正在进行;
  2. LISTEN:监听状态,服务器正在等待连接进入;
  3. SYN_RCVD:收到一个连接请求,尚未确认;
  4. SYN_SENT:已经发出连接请求,等待确认;
  5. ESTABLISHED:连接建立,正常数据传输状态;
  6. FIN_WAIT 1:(主动关闭)已经发送关闭请求,等待确认;
  7. FIN_WAIT 2:(主动关闭)收到对方关闭确认,等待对方关闭请求;
  8. TIME_WAIT:完成双向关闭,等待所有分组死掉;
  9. CLOSING:双方同时尝试关闭,等待对方确认;
  10. CLOSE_WAIT:(被动关闭)收到对方关闭请求,已经确认;
  11. LAST_ACK:(被动关闭)等待最后一个关闭确认,并等待所有分组死掉。

TCP半关闭

由于TCP的连接与数据传输是双向的,所以TCP支持半关闭状态,也就是A->B的通道关闭之后,B还可以向A传输数据。不过TCP的半关闭特性在实际应用中很少使用,当我们调用系统调用函数close()函数的时候,都是指直接关闭两个方向的连接。

同时打开和关闭

TCP中对于同时打开:它仅建立一条连接而不是两条连接,状态变迁图如下:同时发送SYN包,然后收到进行确认直接进入ESTABLISHED状态,可以看到同时打开需要连接建立需要4个报文段,比三次握手多一次!
这里写图片描述

TCP的同时关闭和正常关闭是一样报文,只是在于报文是顺序的还是交叉的。

TCP的初始序列号

在一个端到端的连接中TCP报文段在经过网络路由后,可能会存在延迟抵达和排序混乱的情况,为了解决这一个问题需要仔细选择初始序列号。

在发送用于建立连接的SYN之前通信双方会选择一个初始序列号,初始序列号会随时间而改变,因此每一个连接都拥有不同的初始序列号。在TCP标准中初始序列号可被视为一个32位的计数器,该计数器数值每4微秒增加1。

TCP连接超时

当Server断开的时候,Client会不断重试发送SYN信号企图建立连接。连接的时间差以一种指数回退的方式。

关于建连接时SYN超时

试想一下,如果server端接到了clien发的SYN后回了SYN-ACK后client掉线了,server端没有收到client回来的ACK,那么,这个连接处于一个中间状态,即没成功,也没失败。于是,server端如果在一定时间内没有收到的TCP会重发SYN-ACK。在Linux下,默认重试次数为5次,重试的间隔时间从1s开始每次都翻售,5次的重试时间间隔为1s, 2s, 4s, 8s, 16s,总共31s,第5次发出后还要等32s都知道第5次也超时了,所以,总共需要 1s + 2s + 4s+ 8s+ 16s + 32s = 2^6 -1 = 63s,TCP才会把断开这个连接。

2.TCP选项

TCP的头部除了固定header还有多个选项,常用的选项有:
MSS:最大段大小选项
SACK:选择确认选项
WSOPT:窗口缩放选项
TSOPT:时间戳选项
UTO:用户超时选项

最大段大小选项MSS

最大段大小指TCP协议所允许的从对方接收到的最大报文段,因此这也是发送方在发送数据时所能够使用的最大报文段。当建立一个TCP连接时候,通信的每一方都要在SYN报文段里面的MSS选项中说明自己允许的最大段大小。默认536字节。

SACK

SACK(Selective ACK)是TCP选项,它使得接收方能告诉发送方哪些报文段丢失,哪些报文段重传了,哪些报文段已经提前收到等信息。根据这些信息TCP就可以只重传哪些真正丢失的报文段。需要注意的是只有收到失序的分组时才会可能会发送SACK,TCP的ACK还是建立在累积确认的基础上的。

3. TCP的路径最大传输单元MTU

如果在IP层要传输一个数据报比链路层的MTU还大,那么IP层就会对这个数据报进行分片。一个数据报会被分为若干片,每个分片的大小都小于或者等于链路层的MTU值。当同一网络上的主机互相进行通信时,该网络的MTU对通信双方非常重要。但当主机间要通过很多网络才能通信时,对通信双方最重要的是通信路径中最小的MTU,因为在通信路径上不同网络的链路层MTU不同。通信路径中最小的MTU被称为路径MTU。

MTU=MSS+TCP Header+IP Header.

TIME_WAIT状态

TIME_WAIT状态也称为2MSL等待状态。MSLuejiushi最大段生存周期,也就是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。

当TCP执行一个主动关闭并发送最终的ACK时候,Client的连接必须处于TIME_WAIT状态,并保持两倍的MSL时间,这样就能够让TCP重新发送最终ACK以避免出现丢失情况。重发ACK不是因为TCP重传了ACK,而是因为另一方重发了FIN数据段,事实上Server总是重传FIN直到收到一个最终的ACK。

1)为什么 TIME_WAIT 状态需要保持 2MSL 的时间?
因为如果 TIME_WAIT 状态保持时间不足够长 ( 比如小于 2MSL) ,第一个连接就正常终止了。 第二个拥有相同相关五元组的连接出现,而第一个连接的重复报文到达,干扰了第二个连接。 TCP 实现必须防止某个连接的重复报文在连接终止后出现,所以让 TIME_WAIT 状态保持时间足够长 (2MSL) ,连接相应方向上的 TCP 报文要么完全响应完毕,要么被丢弃。建立第二个连接的时候,不会混淆。

2)IME_WAIT状态的作用?
主动关闭的Socket端会进入TIME_WAIT状态,并且持续2MSL时间长度,MSL就是maximum segment lifetime(最大分节生命期),这是一个IP数据包能在互联网上生存的最长时间,超过这个时间将在网络中消失。MSL在RFC标准上建议是2分钟,而源自berkeley的TCP实现传统上使用30秒,因而,TIME_WAIT状态一般维持在1-4分钟。

3)TIME_WAIT状态存在的理由?
a)可靠地实现TCP全双工连接的终止
b)允许老的重复分节在网络中消逝

5.重置报文段RST

RST是TCP头部的RST位字段。 如果一个报文报将该字段置位就表示是一个重置报文段。下面主要梳理一下会发送RST报文段的场景

1)针对不存在端口的连接请求
当一个连接请求到本地却没有相关进程在目的端口监听就会产生一个重置报文段RST

2)半开连接:在未告知另一端的情况下通信的另一端关闭或则终止连接,就认为该条TCP连接处于半开状态。这种情况一般发生在一方主机宕机情况下,只要不通过半开连接传输数据,正常工作一方不会监测出另一端已经崩溃。服务器重启之后会丢失之前所有连接记忆,TCP规定会回复一个RST报文段作为响应,然后两端的连接被关闭。

6. TCP服务器选项

  • TCP端口号
  • 限制本地IP地址
  • 限制外部节点
  • 进入连接队列

连接队列(半连接队列和全连接队列)

半连接队列主要保存处于SYN_REVD状态的连接;全连接队列保存处于ESTABLISHED状态的队列。

在Linux系统中:
1)当一个连接请求到达(SYN报文段)将会检查系统的参数 net.ipv4.tcp_max_syn_backlog(默认1000)。如果处于SYN_RECV状态的连接数超过了这个阈值,进入的连接就会被拒绝(这里可用于攻击手段)

2)每一个处于监听状态的节点都拥有一个固定长度连接队列,其中的连接已经被TCP完全接受(完成三次握手),但是还没被应用程序接受。称为全连接队列(backlog)、backlog的数目必须在0与系统指定的最大债之间,最大值是net.core.somaxconn(默认值128)。注意这里的限制于应用程序已经建立的连接没有任何关系。

3)如果队列已经没有足够空间分配给新的连接,TCP会延迟对SYN的响应,从而给应用程序一个跟上节奏的机会直到超时。 LInux在这一方面坚持在能力允许范围内不忽略进入的连接,但是如果系统变量net.ipv4.tcp_abort_on 已被锁定新进入的连接会被重置报文段RST重置。

7. 与TCP连接管理相关的攻击

SYN泛洪就是一种,这种攻击产生一系列的TCP尝试连接的攻击(SYN报文段)。

猜你喜欢

转载自blog.csdn.net/u010853261/article/details/82085738