内核TCP / IP实现-关于接受队列长度

时间:2019-04-17 06:21:17

标签: c tcp linux-kernel

我最近正在学习Linux内核(版本4.4)中的TCP / IP实现,并对接受队列感到非常困惑。我知道struct inet_connection_sock中有一个队列,称为接受队列

struct inet_connection_sock {
    ...
    /* @icsk_accept_queue:     FIFO of established children */
    struct request_sock_queue icsk_accept_queue;
    ...
}

其中有一个qlen成员,我认为它用于指示队列的长度。

struct request_sock_queue {
    ...
    /* length of the queue? */
    atomic_t        qlen;
    ...
};

这是我想知道的:当LISTEN套接字接收到SYN数据包时,在函数tcp_conn_request中,将调用inet_csk_reqsk_queue_hash_add将新创建的NEW_SYN_RECV袜子放入ehash表(不是{{1 }})

icsk_accept_queue

但是在此函数中,调用inet_csk_reqsk_queue_added以递增void inet_csk_reqsk_queue_hash_add(struct sock *sk, struct request_sock *req, unsigned long timeout) { reqsk_queue_hash_req(req, timeout); // add to ehash table inet_csk_reqsk_queue_added(sk); // increment icsk_accept_queue.qlen } 。我的问题是,为什么icsk_accept_queue.qlen没有插入任何内容,为什么增加qlen?不是icsk_accept_queue的长度吗?

此外,tcp_conn_requestinet_csk_reqsk_queue_add,将快速打开的袜子(如果启用)添加到icsk_accept_queue

icsk_accept_queue

但是此函数最终使struct sock *inet_csk_reqsk_queue_add(struct sock *sk, struct request_sock *req, struct sock *child) { struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue; spin_lock(&queue->rskq_lock); if (unlikely(sk->sk_state != TCP_LISTEN)) { inet_child_forget(sk, req, child); child = NULL; } else { req->sk = child; req->dl_next = NULL; if (queue->rskq_accept_head == NULL) queue->rskq_accept_head = req; else queue->rskq_accept_tail->dl_next = req; queue->rskq_accept_tail = req; sk_acceptq_added(sk); // increment sk.sk_ack_backlog } spin_unlock(&queue->rskq_lock); return child; } (通过调用sk_acceptq_added)而不是sk.sk_ack_backlog递增。为什么不呢?

0 个答案:

没有答案