В ядре Linux TCP реализовано, почему «sk_acceptq_is_full» использует «>» вместо «> =»? - PullRequest
1 голос
/ 19 мая 2019

Моя версия ядра Linux - 4.4.0.

Вот мой фрагмент кода

    int listenfd = socket(PF_INET, SOCK_STREAM, 0);

    bzero(&servaddr, sizeof(servaddr));
    servaddr.sin_family = AF_INET;
    servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
    servaddr.sin_port = htons(50001);

    bind(listenfd, (struct sockaddr *)&servaddr, sizeof(servaddr));

    listen(listenfd, 2); // just listen, never accept
    while(1)
    {
        sleep(1);
    }

Я полагаю, что он может выполнить только 2 TCP 3-процесс рукопожатия, поскольку аргумент backlog в listen равен 2 .

Однако, когда я делаю тест, результат будет 3 , а не 2

Итак, я взглянул на исходный код.

В tcp_input.c

int tcp_conn_request(struct request_sock_ops *rsk_ops,
             const struct tcp_request_sock_ops *af_ops,
             struct sock *sk, struct sk_buff *skb)
{
    // code omitted
    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;
    }
     // code omitted
}

используется sk_acceptq_is_full, чтобы проверить, заполнена ли очередь приема

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

Я знал, что sk->sk_ack_backlog - это число полных TCP 3-кодов, которые не являются accept() пользователем. И sk->sk_max_ack_backlog - это аргумент listen()

Похоже, я выяснил причину, по которой результат равен 3 , а не 2 ,

Но что меня озадачивает, почему он использует >, а не >=, чтобы судить, что очередь переполнена? Разве не разумнее использовать >=?

ядро ​​новой версии (5.0.9) такое же.

...