SYN Queue & Accept Queue

内核中的两个存放连接信息的队列。存放的连接元数据,四元组、MSS、window scale 等。
其用途简单来说:

  • 收到 SYN 以后放进 SYN queue(半连接队列)
  • 收到 ACK 以后放进 Accept Queue(全连接队列)
  • 用户进程调用 accept() 以后,从 Accept Queue 中取出

1. SYN Queue 溢出时行为

1.1. SYN Cookie 机制

SYN Queue 溢出时 linux 的行为与 SYN Cookie 这个用于对抗 SYN flood 攻击的机制有关。
SYN Cookie 原理:设计出一个可逆的 hash 函数,可以基于时间戳、四元组等 TCP 连接信息算出 hash 值,并作为 SYN+ACK 报文的序列号。如果 peer 是正常的客户端,则下个发送过来的 ACK 是这个序列号 +1,将其减一即可逆推出所有的 TCP 元数据,直接放入 Accept Queue 即可。
这样一来,SYN_RCVD 状态的 socket 就可以不必放入 SYN queue 中,防止被打爆。

1.2. 溢出行为

由内核参数控制。

  • net.ipv4.tcp_syncookies = 0,表示关闭 SYN Cookie 机制,如果 SYN 队列已满,那么新到的 SYN 报文将被丢弃。
  • net.ipv4.tcp_syncookies = 1,表示 SYN Cookie 机制仅在 SYN 队列满时才正式启用。
  • net.ipv4.tcp_syncookies = 2,表示无条件启用 SYN Cookie 机制。

1.3. 修改 SYN Queue 大小

net.ipv4.tcp_max_syn_backlog

2. Accept Queue 溢出时行为

2.1. 溢出行为

由内核参数 net.ipv4.tcp_abort_on_overflow 控制。

  • net.ipv4.tcp_abort_on_overflow = 0 ,(默认),会丢弃 peer 发来的第三次握手的 ACK,而重传第二次握手时的 SYN+ACK 。
  • net.ipv4.tcp_abort_on_overflow = 1 ,则会直接向 peer 发送 RST。

    2.1.1. 为何要重传 SYN+ACK?

  • 协议规定:由于 Accept Queue 满,这个 socket 只能继续待在 SYN Queue 中,即还是处于 SYN_RECV 状态,此时只能回复 SYN+ACK。
  • 有利于状态机恢复:另一方面,peer 收到重复的 SYN+ACK 时,会认为是丢包,故会重传 ACK。如果下一个 ACK 到来时,Accept Queue 又有空间了,则可以正常完成握手、放入队列中。

2.2. 典型溢出现象

默认情况下,内核参数 net.ipv4.tcp_abort_on_overflow 是 0。此时如果发生 SYN Queue 溢出,则 server 一直在发送 SYN+ACK,client 一直在发送 ACK(+PSH)。

2.3. 修改 Accept Queue 大小

net.core.somaxconn 和 socket 的 backlog 参数中的最小值决定。

3. 参考

知识共享许可协议
本作品采用知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议进行许可。
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇