客户端:发起 SYN 报文,并进入到 SYN-SENT 状态
服务端:接收到报文后发送 SYN-ACK 报文,并进入到 SYN-RCVD 状态
客户端:发送 ACK 报文,并进入到 ESTABLISHED 状态
服务端:收到后 ACK 报文后,进入到 ESTABLISHED 状态,至此 TCP 连接建立成功,开始进行数据通信
这就完了吗?
网络传输本来就是不稳定,即使有种协议存在也不能保证100%的稳定,为什么建立三次握手就能保证数据的可靠送达呢?等等有很多问题值得思考。
1.为什么三次握手之后才能建立起连接?
主要是为了初始化 Sequence Number,即上图中的 seq,他的作用就是确保数据包的有序传输,数据也是通过 seq 进行数据的拼接
2.如果客户端没有收到服务端发送 SYN-ACK 报文怎么办呢?
此时服务端会进行重试,Linux 默认是等待 63s 后断开连接。
第一次等待 1 秒,第二次等待 2 秒,第三次等待 4 秒,第四次等待 8 秒,第五次等待 16 秒,再等待 32 秒后服务器会断开连接。
总共等待时间为 1 + 2 + 4 + 8 + 16 + 32 = 63 秒。
3.这么久?如果疯狂向服务端发送请求报文却不去回复服务器,服务器 TCP 资源岂不是会被耗尽?
确实如此,这就是 SYN-Flood 攻击,典型的 DoS (Denial of Service,拒绝服务) 攻击,效果就是服务器 TCP 连接资源耗尽,停止响应正常的 TCP 连接请求。
后续
关于 SYN-Flood 的防护措施,以及 linux 如何针对这种问题提供解决方案的,后续文章给出分享。
网友评论