TCP建立(3次握手)与终止(4次挥手)
TCP建立(3次握手)与终止(4次挥手)
1. 三路握手
(1) 服务器调用socket, bind, listen完成被动打开。
(2)客户调用connect主动打开,导致客户TCP发送一个SYN分节,其中包含客户在待建立的连接中发送的数据的初始序列号。通常SYN不携带数据,其IP数据报只含有一个IP首部,一个TCP首部和可能的TCP选项。
(3)服务器必须确认(ACK)客户的SYN, 同时发送自己的SYN分节,它含有服务器将在同一连接中发送的数据的初始序列号。服务器在单个分节中发送SYN和对客户的SYN的ACK(确认)。
(4)客户必须确认服务器的SYN。
交换至少需要3路分组, TCP的三路握手。
备注: SYN占据一个字节的序列号空间。每个SYN的ACK的确认号是SYN的序列号+1。ACK中的确认号是发送这个ACK的一段所期望的下一个序列号。
SYN组成: 1byte的序列号 + IP首部 + TCP首部 + 可能的TCP选项。
不含有数据, 在SYN时已经把TCP选项告诉对端。
1.1 握手详解
第一次握手: 客户端发送一个TCP的SYN标志位置1的包含有:客户打算连接的服务器的端口,以及初始序号X,保存在包头的序列号(Sequence Number)字段里。
第二次握手: 服务器发回确认包(ACK)应答。即SYN标志位和ACK标志位均为1同时,将确认序号(Acknowledgement Number)设置为客户的SYN加1以.即X+1。
第三次握手. 客户端再次发送确认包(ACK) SYN标志位为0,ACK标志位为1.并且把服务器发来ACK的序号字段+1,放在确定字段中发送给对方.并且在数据段放写SYN的+1
SYN攻击:
在三次握手过程中,服务器发送SYN-ACK之后,收到客户端的ACK之前的TCP连接称为半连接(half-open connect).此时服务器处于Syn_RECV状态.当收到ACK后,服务器转入ESTABLISHED状态.
Syn攻击就是: 攻击客户端在短时间内伪造大量不存在的IP地址,向服务器不断地发送syn包,服务器回复确认包,并等待客户的确认,由于源地址是不存在的,服务器需要不断的重发直至超时,这些伪造的SYN包将长时间占用未连接队列,正常的SYN请求被丢弃,目标系统运行缓慢,严重者引起网络堵塞甚至系统瘫痪。
Syn攻击是一个典型的DDOS攻击。检测SYN攻击非常的方便,当你在服务器上看到大量的半连接状态时,特别是源IP地址是随机的,基本上可以断定这是一次SYN攻击.在Linux下可以如下命令检测是否被Syn攻击
netstat -n -p TCP | grep SYN_RECV
一般较新的TCP/IP协议栈都对这一过程进行修正来防范Syn攻击,修改tcp协议实现。主要方法有SynAttackProtect保护机制、SYN cookies技术、增加最大半连接和缩短超时时间等.但是不能完全防范syn攻击。
2. TCP连接终止
(1)某个应用程序首先调用close,该端执行主动关闭(active close)。导致该端TCP发送FIN分节,表示数据发送完毕。
(2)接受FIN的对端执行被动关闭(passive close),该FIN由TCP确认。FIN(放在以排队的数据之后)作为EOF传给接受端引用程序,因为FIN意味着接收端进程在相应连接中再无额外数据可接受。
(3)过一段时间,接收到FIN的进程调用close套接字,这导致TCP发送一个FIN。
(4)接收到FIN的原发送端(主动关闭的一端)确认这个FIN。
这些通常需要4个分节。(1)中FIN可能随数据发送, (2)ACK(3)FIN可能合并为一个分节。
FIN也占据1byte序列号,每个FIN的ACK确认号就是这个FIN的序列号+1。
在(2)(3)之间也可能传递数据,这是半关闭(half-close)。
备注: 套接字关闭时,所在端都会发送FIN。这包括显示的close或者Unix终止(正常或非正常),所有打开的描述符都关闭,打开的任何TCP连接都发送一个FIN。
3. TCP状态图转换
TCP的一个连接定义了11中状态。使用netstat监视状态的变化。
转换规则: TCP规则规定了如何基于当前状态以及在该状态下所接受的分节从一个状态转换为另一个状态。
主要状态:
(1) SYN_SENT: 客户端(主动打开connect), TCP发送SYN后。
(2) SYN_RCVD: 服务器(被动打开listen), TCP接受SYN, 发送SYN,ACK后。
(3) ESTABLISHED: 客户端收到服务器的SYN, 发送ACK后状态。服务器收到客户的ACK后状态。
(4) FIN_WAIT_1: 客户端(主动关闭),TCP发送FIN后状态。主动关闭端一定会有的状态。
(5)CLOSE_WAIT:服务器(被动关闭)收到客户FIN,发送ACK后状态。被动关闭端一定会有的状态。
(6) FIN_WAIT_2: 客户端收到服务器的ACK后状态。主动关闭端一般会有的状态,不是必须有。
(7)LAST_ACK: 服务器关闭,TCP发送FIN后状态。被动关闭端一定会有的状态。
(8)TIME_WAIT:客户端接受服务器的FIN,TCP发送ACK后状态。主动关闭端的状态,可以避免。
注意:CLOSE_WAIT状态过多,很可能是忘记close()造成的。
TIME_WAIT可以避免,但是不建议这么做,而是修改相关参数配置。
4. 分组交换
client MSS = 536, server MSS = 1460。
捎带发送(piggybacking): 服务器对客户请求的确认是伴随着应答发送的,通常在服务器处理请求并产生应答的时间少于200ms时产生。
若服务器耗时更长,则先ACK再应答。