当前位置:网站首页>Listen in the network

Listen in the network

2022-07-01 13:28:00 To maintain world peace_

listen Main work

         Request and initialize the receive queue , Full connection receive queue and half receive queue

int __sys_listen(int fd, int backlog)
{
	struct socket *sock;
	int err, fput_needed;
	int somaxconn;
	// according to fd lookup socket Kernel object 
	sock = sockfd_lookup_light(fd, &err, &fput_needed);
	if (sock) {
		// Get the kernel somaxconn Parameters ;net.core.somaxconn, And backlog  Take the small one 
		somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn;
		if ((unsigned int)backlog > somaxconn)
			backlog = somaxconn;

		err = security_socket_listen(sock, backlog);
		if (!err)// Call protocol stack initialization listen
			err = sock->ops->listen(sock, backlog);

		fput_light(sock->file, fput_needed);
	}
	return err;
}

backlog And in the system net.core.somaxconn Select a small kernel parameter

sock->ops->listen function

int inet_listen(struct socket *sock, int backlog)
{
	struct sock *sk = sock->sk;
	unsigned char old_state;
	int err, tcp_fastopen;

    // If it is listening , allows backlog Parameter adjustment , Set the full connection queue length 
	WRITE_ONCE(sk->sk_max_ack_backlog, backlog);
	

	// No listen state , Enter listening 
	if (old_state != TCP_LISTEN) {

		tcp_fastopen = sock_net(sk)->ipv4.sysctl_tcp_fastopen;
		if ((tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) &&
		    (tcp_fastopen & TFO_SERVER_ENABLE) &&
		    !inet_csk(sk)->icsk_accept_queue.fastopenq.max_qlen) {
			fastopen_queue_tune(sk, backlog);
			tcp_fastopen_init_key_once(sock_net(sk));
		}
		// Start listening 
		err = inet_csk_listen_start(sk, backlog);
		if (err)
			goto out;
		tcp_call_bpf(sk, BPF_SOCK_OPS_TCP_LISTEN_CB, 0, NULL);
	}
	err = 0;

out:
	release_sock(sk);
	return err;
}

Full connection queue structure

struct inet_connection_sock {
	/* inet_sock has to be the first member! */
	struct inet_sock	  icsk_inet;
	struct request_sock_queue icsk_accept_queue;
    ...
}


struct request_sock_queue {
	spinlock_t		rskq_lock;
	u8			rskq_defer_accept;

	u32			synflood_warned;
	atomic_t		qlen;
	atomic_t		young;
	// Full connection queue 
	struct request_sock	*rskq_accept_head;
	struct request_sock	*rskq_accept_tail;

	struct fastopen_queue	fastopenq;  /* Check max_qlen != 0 to determine
					     * if TFO is enabled.
					     */
};

int inet_csk_listen_start(struct sock *sk, int backlog)
{
	struct inet_connection_sock *icsk = inet_csk(sk);
	struct inet_sock *inet = inet_sk(sk);
	int err = -EADDRINUSE;

	//icsk_accept_queue Receiving queue 
	// Receive queue kernel object initialization 
	reqsk_queue_alloc(&icsk->icsk_accept_queue);

	sk->sk_ack_backlog = 0;
	inet_csk_delack_init(sk);

	inet_sk_state_store(sk, TCP_LISTEN);
	if (!sk->sk_prot->get_port(sk, inet->inet_num)) {
		inet->inet_sport = htons(inet->inet_num);

		sk_dst_reset(sk);
		err = sk->sk_prot->hash(sk);

		if (likely(!err))
			return 0;
	}

	inet_sk_set_state(sk, TCP_CLOSE);
	return err;
}

static inline void fastopen_queue_tune(struct sock *sk, int backlog)
{
	struct request_sock_queue *queue = &inet_csk(sk)->icsk_accept_queue;
	int somaxconn = READ_ONCE(sock_net(sk)->core.sysctl_somaxconn);
	// Semi connected queue length 
	queue->fastopenq.max_qlen = min_t(unsigned int, backlog, somaxconn);
}

summary :listen It mainly applies for work and initializes the receiving queue , Full connection receive queue and half receive queue

Full connection receive queue length

        backlog And net.core.somaxconn Smaller value between

原网站

版权声明
本文为[To maintain world peace_]所创,转载请带上原文链接,感谢
https://yzsam.com/2022/182/202207011300441258.html