【问题标题】:Does listen's backlog number include SYN-received connections count in case of TCP in Linux?在 Linux 中的 TCP 情况下,listen 的积压数是否包括 SYN 接收的连接数?
【发布时间】:2020-01-30 16:33:48
【问题描述】:

我阅读了一些帖子并检查了诸如inet_listen()->inet_csk_listen_start() 之类的 Linux 内核代码,似乎 listen() 系统调用的 backlog 参数只影响接受的队列,但不影响SYN 接收队列:

sk->sk_max_ack_backlog = backlog;

即象征性地accept-queue + syn-received-queue != backlog。 我无法弄清楚发生了什么。 This article 状态:

Accept 和 SYN 队列的最大允许长度被占用 从 backlog 参数传递给 listen(2) 系统调用 应用。

但是MAN page没有类似的东西。

同样在 Linux 的情况下:backloghere 提到的提示还是真的限制了队列?

【问题讨论】:

  • 用户空间 listen() 函数和底层的实际系统调用并非特定于 IP 套接字。自然,他们的文档没有涉及内核 IP 实现的具体细节。
  • 它依赖于系统。您的链接表明它是关于 Linix 的。
  • @user207421 是的,这是关于 Linux 实现的。固定标题。

标签: c sockets networking tcp linux-kernel


【解决方案1】:

如果您指定的是 4.3 内核,它类似于:

tcp_v4_do_rcv()->tcp_rcv_state_process()->tcp_v4_conn_request()->tcp_conn_request()->inet_csk_reqsk_queue_is_full()

Here我们可以看到关于队列最重要的细节:

/* 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_queuesk_max_ack_backlog 的大小进行比较,inet_csk_listen_start() 之前设置了该大小。所以是的,backlog 在当前情况下会影响传入队列

您可以看到sk_acceptq_is_full()inet_csk_reqsk_queue_is_full() 都与通过listen() 设置的同一个套接字的sk_max_ack_backlog 进行比较:

static inline bool sk_acceptq_is_full(const struct sock *sk)
{
    return sk->sk_ack_backlog > sk->sk_max_ack_backlog;
}

有用的链接:12

【讨论】:

    猜你喜欢
    • 2012-06-22
    • 2016-08-04
    • 1970-01-01
    • 2020-02-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多