TCP三次握手中的数据传输
三次握手过程中哪些阶段可以携带数据
问题
TCP 三次握手过程中可以携带数据吗?如果可以,是哪个阶段?
解答
结论:第一次、第二次握手不能携带数据,第三次握手可以携带数据。
三次握手流程
客户端 服务端
| |
| -------- SYN (seq=x) ---------> | 第一次握手:不能携带数据
| |
| <--- SYN+ACK (seq=y, ack=x+1) --- | 第二次握手:不能携带数据
| |
| ---- ACK (seq=x+1, ack=y+1) ---> | 第三次握手:可以携带数据
| |
为什么前两次不能携带数据?
主要是出于安全考虑,防止 SYN 洪泛攻击。
如果第一次握手就能携带数据:
- 攻击者可以在 SYN 包中塞入大量数据
- 服务端收到后需要分配资源处理这些数据
- 攻击者伪造大量不同 IP 的 SYN 请求
- 服务端资源被耗尽,无法响应正常请求
攻击者 服务端
| |
| -- SYN + 大量数据 (伪造IP1) --> | 分配资源处理
| -- SYN + 大量数据 (伪造IP2) --> | 分配资源处理
| -- SYN + 大量数据 (伪造IP3) --> | 分配资源处理
| ... | 资源耗尽
为什么第三次可以携带数据?
第三次握手时:
- 客户端已经处于 ESTABLISHED 状态
- 客户端已确认服务端的收发能力正常
- 连接已经建立,携带数据是合理的优化
// 第三次握手时的状态
客户端:ESTABLISHED(已确认双方通信能力)
服务端:SYN_RCVD(等待最后确认)
// 客户端发送 ACK 时可以顺便带上请求数据
// 减少一次 RTT,提高效率
实际应用:TCP Fast Open (TFO)
TCP Fast Open 是一种优化机制,允许在 SYN 包中携带数据:
首次连接:
客户端 -- SYN + Cookie请求 --> 服务端
客户端 <-- SYN+ACK + Cookie -- 服务端
(客户端缓存 Cookie)
后续连接:
客户端 -- SYN + Cookie + 数据 --> 服务端 // 第一次握手就带数据
服务端验证 Cookie 后直接处理数据
这需要双方都支持 TFO,且通过 Cookie 机制保证安全。
关键点
- 第一、二次握手不能携带数据,第三次可以
- 前两次不带数据是为了防止 SYN 洪泛攻击
- 第三次握手时客户端已处于 ESTABLISHED 状态,带数据可减少 RTT
- TCP Fast Open 通过 Cookie 机制允许首次握手带数据
- SYN 包虽然不带数据,但会消耗一个序列号
目录