如果您指定的是 4.3 内核,则类似于:
tcp_v4_do_rcv()
->tcp_rcv_state_process()
->tcp_v4_conn_request()
->tcp_conn_request()
->inet_csk_reqsk_queue_is_full()
Here https://elixir.bootlin.com/linux/v4.3.6/source/net/ipv4/tcp_input.c#L6151我们可以看到有关队列的最重要的细节:
/* TW buckets are converted to open requests without
* limitations, they conserve resources and peer is
* evidently real one.
*/
if ((sysctl_tcp_syncookies == 2 ||
inet_csk_reqsk_queue_is_full(sk)) && !isn) {
want_cookie = tcp_syn_flood_action(sk, skb, rsk_ops->slab_name);
if (!want_cookie)
goto drop;
}
/* Accept backlog is full. If we have already queued enough
* of warm entries in syn queue, drop request. It is better than
* clogging syn queue with openreqs with exponentially increasing
* timeout.
*/
if (sk_acceptq_is_full(sk) && inet_csk_reqsk_queue_young(sk) > 1) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_LISTENOVERFLOWS);
goto drop;
}
请注意inet_csk_reqsk_queue_is_full()
:
static inline int inet_csk_reqsk_queue_is_full(const struct sock *sk)
{
return inet_csk_reqsk_queue_len(sk) >= sk->sk_max_ack_backlog;
}
最后比较当前队列icsk_accept_queue
with sk_max_ack_backlog
之前设置的大小inet_csk_listen_start()
。所以是的,backlog
影响传入队列在目前的情况下。
你可以看到两者sk_acceptq_is_full()
and inet_csk_reqsk_queue_is_full()
与相同插座进行比较sk_max_ack_backlog
这是通过设置listen()
:
static inline bool sk_acceptq_is_full(const struct sock *sk)
{
return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
}
有用的链接:1 https://blog.dubbelboer.com/2012/04/09/syn-cookies.html, 2 http://veithen.io/2014/01/01/how-tcp-backlog-works-in-linux.html