天天看点

学习笔记 | TCP 三次握手,四次挥手

学习笔记 | TCP 三次握手,四次挥手
  • 序号 :用于对字节流进行编号,例如序号为 301,表示第一个字节的编号为 301,如果携带的数据长度为 100 字节,那么下一个报文段的序号应为 401。
  • 确认号 :期望收到的下一个报文段的序号。例如 B 正确收到 A 发送来的一个报文段,序号为 501,携带的数据长度为 200 字节,因此 B 期望下一个报文段的序号为 701,B 发送给 A 的确认报文段中确认号就为 701。
  • 数据偏移 :指的是数据部分距离报文段起始处的偏移量,实际上指的是首部的长度。
  • 确认 ACK :确认位,对接受到报文的确认。当

    ACK=1

    时确认号字段有效,否则无效。TCP 规定,在连接建立后所有传送的报文段都必须把 ACK 置 1。
  • 同步 SYN :在连接建立时用来同步序号。表示此报文是一个连接请求或连接接收报文。 当

    SYN=1,ACK=0

    时表示这是一个连接请求报文段。若对方同意建立连接,则响应报文中

    SYN=1,ACK=1

  • 终止 FIN :用来释放一个连接,当

    FIN=1

    时,表示此报文段的发送方的数据已发送完毕,并要求释放连接。
  • 窗口 :窗口值作为接收方让发送方设置其发送窗口的依据。之所以要有这个限制,是因为接收方的数据缓存空间是有限的。
  • RST:复位连接,表示TCP连接中出现严重错误。
  • PSH:推送位,尽可能快地数据送往接收进程。

为什么需要三次握手,两次不行吗?

学习笔记 | TCP 三次握手,四次挥手

第一次握手:客户端发送网络包,服务端收到了。

  • 这样服务端就能得出结论:客户端的发送能力、服务端的接收能力是正常的。

第二次握手:服务端发包,客户端收到了。

  • 这样客户端就能得出结论:服务端的接收、发送能力,客户端的接收、发送能力是正常的。
  • 不过此时服务器并不能确认客户端的接收能力是否正常。

第三次握手:客户端发包,服务端收到了。

  • 这样服务端就能得出结论:客户端的接收、发送能力正常,服务器自己的发送、接收能力也正常。
学习笔记 | TCP 三次握手,四次挥手

SYN洪泛攻击 —— SYN cookie

  • SYN洪泛攻击发生在OSI第四层,这种方式利用TCP协议的特性,就是三次握手。攻击者发送TCP SYN,SYN是TCP三次握手中的第一个数据包,而当服务器返回ACK后,该攻击者就不对其进行再确认,那这个TCP连接就处于挂起状态,也就是所谓的半连接状态,服务器收不到再确认的话,还会重复发送ACK给攻击者。这样更加会浪费服务器的资源。攻击者就对服务器发送非常大量的这种TCP连接,由于每一个都没法完成三次握手,所以在服务器上,这些TCP连接会因为挂起状态而消耗CPU和内存,最后服务器可能死机,就无法为正常用户提供服务了。
  • SYN cookie为解决的办法。
  • 另外回答建连的问题时,可以提到 SYN 洪水攻击发生的原因,就是 Server 端收到 Client 端的 SYN 请求后,发送了 ACK 和 SYN,但是 Client 端不进行回复,导致 Server 端大量的链接处在 SYN_RCVD 状态,进而影响其他正常请求的建连。可以设置 tcp_synack_retries = 0 加快半链接的回收速度,或者调大 tcp_max_syn_backlog 来应对少量的 SYN 洪水攻击。

四次挥手

学习笔记 | TCP 三次握手,四次挥手

这里面试官可能会问为什么需要等待 2 倍最大报文段生存时间之后再关闭链接,原因有两个:

  • 保证 TCP 协议的全双工(即数据在两个方向上能同时传递)连接能够可靠关闭;
  • 保证这次连接的重复数据段从网络中消失,防止端口被重用时可能产生数据混淆。
学习笔记 | TCP 三次握手,四次挥手

思考:为什么上图中的A在TIME-WAIT状态必须等待2MSL时间呢?

  • 第一,为了保证A发送的最后一个ACK报文能够到达B。这个ACK报文段有可能丢失,因而使处在

    LAST-ACK状态

    的B收不到对已发送的

    FIN+ACK报文段

    的确认。B会超时重传这个

    FIN+ACK

    报文段,而A就能在

    2MSL

    时间内收到这个重传的

    FIN+ACK

    报文段。如果A在

    TIME-WAIT

    状态不等待一段时间,而是在发送完ACK报文段后就立即释放连接,就无法收到B重传的

    FIN+ACK

    报文段,因而也不会再发送一次确认报文段。这样,B就无法按照正常的步骤进入

    CLOSED

    状态。
  • 第二,A在发送完ACK报文段后,再经过

    2MSL

    时间,就可以使本连接持续的时间所产生的所有报文段都从网络中消失。 这样就可以使下一个新的连接中不会出现这种旧的连接请求的报文段。

什么是2MSL

  • MSL是

    Maximum Segment Lifetime

    英文的缩写,中文可以译为“报文最大生存时间”,他是任何报文在网络上存在的最长时间,超过这个时间报文将被丢弃。因为tcp报文(segment)是ip数据报(datagram)的数据部分,具体称谓请参见《数据在网络各层中的称呼》一文,而ip头中有一个

    TTL域

    TTL

    time to live

    的缩写,中文可以译为“

    生存时间

    ”,这个生存时间是由源主机设置初始值但不是存的具体时间,而是存储了一个ip数据报可以经过的最大路由数,每经过一个处理他的路由器此值就减1,当此值为0则数据报将被丢弃,同时发送ICMP报文通知源主机。RFC 793中规定MSL为2分钟,实际应用中常用的是30秒,1分钟和2分钟等。
  • 2MSL即

    两倍的MSL

    ,TCP的TIME_WAIT状态也称为

    2MSL等待状态

    ,当TCP的一端发起主动关闭,在发出最后一个ACK包后,即第3次握手完成后发送了第四次握手的ACK包后就进入了

    TIME_WAIT状态

    ,必须在此状态上停留两倍的MSL时间,等待2MSL时间主要目的是怕最后一个ACK包对方没收到,那么对方在超时后将重发第三次握手的FIN包,主动关闭端接到重发的FIN包后可以再发一个ACK应答包。在TIME_WAIT状态时两端的端口不能使用,要等到2MSL时间结束才可继续使用。当连接处于2MSL等待阶段时任何迟到的报文段都将被丢弃。不过在实际应用中可以通过设置

    SO_REUSEADDR

    选项达到不必等待2MSL时间结束再使用此端口。
  • TTL与MSL是有关系的但不是简单的相等的关系,MSL要大于等于TTL。

继续阅读