转自:https://yq.aliyun.com/articles/42389
若要理解本文意图说明的问题,可能需要以下知识背景:
listen 系统调用的backlog参数含义,以及与net.core.somaxconn参数的关系;
SYN flood攻击与防护;
SYN queue和accept queue的用途,以及在不同linux版本中的实现差异;
在SYN queue未满的情况下,在收到SYN包后,TCP协议栈自动回复SYN+ACK包,之后在收到 ACK 时,根据accept queue状态进行后续处理;
1. 若SYN queue已满,在收到SYN时
- 若设置net.ipv4.tcp_syncookies = 0 ,则直接丢弃当前SYN包;
- 若设置net.ipv4.tcp_syncookies = 1 ,则令want_cookie = 1继续后面的处理;
- 若accept queue已满,并且qlen_young的值> 1 ,则直接丢弃当前SYN包;
- 若accept queue未满,或者qlen_young的值<= 1 ,则输出"possible SYN flooding on port %d. Sending cookies.\n",生成 syncookie 并在SYN,ACK中带上;
— 以下源码取自 linux-2.6.32 版本 —
int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
{
...
#ifdef CONFIG_SYN_COOKIES
int want_cookie = 0;
#else
#define want_cookie 0 /* Argh, why doesn't gcc optimize this :( */
#endif
...
/* TW buckets are converted to open requests without
* limitations, they conserve resources and peer is
* evidently real one.
*/
// 判定 SYN queue 是否已满
if (inet_csk_reqsk_queue_is_full(sk) && !isn) {
#ifdef CONFIG_SYN_COOKIES
if