nar*_*llo 7 c sockets networking tcp linux-kernel
我阅读了一些文章,并检查了inet_listen()-> inet_csk_listen_start()等Linux内核代码,看来syscall的backlog参数listen()只影响接受的队列,而不影响 SYN接收的队列:
sk->sk_max_ack_backlog = backlog;
Run Code Online (Sandbox Code Playgroud)
即象征意义accept-queue + syn-received-queue != backlog。我不知道发生了什么事。本文指出:
接受和SYN队列的最大允许长度取自应用程序传递给listen(2)syscall的backlog参数。
但是MAN页中没有类似的东西。
此外,在Linux的情况下:是backlog的提示,提到这里也确实限制了队列?
如果是 4.3 内核,您指定的内容类似于:
tcp_v4_do_rcv()-> tcp_rcv_state_process()-> tcp_v4_conn_request()-> tcp_conn_request()->inet_csk_reqsk_queue_is_full()
在这里我们可以看到关于队列的最重要的细节:
/* 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;
}
Run Code Online (Sandbox Code Playgroud)
请注意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;
}
Run Code Online (Sandbox Code Playgroud)
最后,它将当前队列icsk_accept_queue与sk_max_ack_backlog之前设置的大小进行比较inet_csk_listen_start()。所以是的,在当前情况下backlog会影响传入队列。
您可以看到两者sk_acceptq_is_full()并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;
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
80 次 |
| 最近记录: |