先看TCP报文格式
```
0 1 2 3 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 +-------------------------------+-------------------------------+ | Source Port | Destination Port | +-------------------------------+-------------------------------+ | Sequence Number | +---------------------------------------------------------------+ | Acknowledgment Number | +-------+-------+-+-+-+-+-+-+-+-+-------------------------------+ | Data | |C|E|U|A|P|R|S|F| | | Offset|Rsved |W|C|R|C|S|S|Y|I| Window | | | |R|E|G|K|H|T|N|N| | +-------+-----------+-+-+-+-+-+-+-------------------------------+ | Checksum | Urgent Pointer | +-------------------------------+-------------------------------+ | Options | +---------------------------------------------------------------+ | data | +---------------------------------------------------------------+
```
三握:
C S
close close
1 syn 随机seq x +ack0 进入syn_send
2 收syn , 发syn+ack,随机seq y, ack=x+1, 进入sync_recv
3 收syn+ack, 进入established , 发送ack = y+1
4 收ack, 校验ack 为y+1 , 进入established
-- 三握 中 syn, ack, 不可携带数据, 最后一次ack 可携带
-- 若S未收到 4中的 ack, 会超时重传 syn+ack, 大于次数后close, S 大量 sync_recv 就是半开攻击场景.
-- 若C收到S的syn+ack 后,回复rst , S收到后close
-- 若C收到S的大量RST, 且S的port 正常, 可能是S队列满 ,查看日志 dmesg | grep -i "TCP: drop open request"; 查看队列长度 sysctl net.ipv4.tcp_max_syn_backlog ; sysctl net.core.somaxconn
-- 三次可防止历史syn连接, 同步序列号.
四挥:
C S
established established
1 发fin+ack,进入fin_wait_1
2 发ack,不含数据, 进close_wait
收ack,进入fin_wait_2
待发送数据seq=C的ack,ack=C的seq+1
回复 ack, seq=S的ack ,ack=S的seq+datalen
未收到重传, 继续发
3 发fin , 进last_ack
4 立即回复ack, 进入time_wait
收ack , 进close
wait 2msl 后close
-- C 和 S 都可发起四挥.
-- 立即回ack且不含数据
-- 若发出fin 后未收到ack 而是收到对方的fin , 进入closing , 等待对方的ack , 等不到重传
-- 只要有ack no 的ack 标记都置位
-- 主动关闭方进入 time_wait , 被动关闭方 才有last_ack
-- 发送fin时,表示不发数据但还可以收数据,
-- ack 报文不重传, 未收到 会重发 fin
-- 大量time_wait 怎么办, 作为主动关闭方, 调优参数 tcp_tw_reuse , 或linger 直接rst
-- 进程崩溃了, 进程关了, 会直接rst
http1.1 --> keep-alive TCP链接复用,但链接是串行的。浏览器基于域名限制最多6个并行。
http2 并行复用,基于steamid , client 生成steamid 为奇数,server为偶数; 但基于tcp 如果弱网重传所有steam全部等待重传。 必须基于tls,https
http3 基于QUIC 的 UDP , 首次建立速度快, 不再需要tcp的丢包重传了, 多资源并行请求。 QUIC底层支持加密, 不再依赖https