listen系统调用
Posted Alex
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了listen系统调用相关的知识,希望对你有一定的参考价值。
1 /* 2 * Perform a listen. Basically, we allow the protocol to do anything 3 * necessary for a listen, and if that works, we mark the socket as 4 * ready for listening. 5 */ 6 7 SYSCALL_DEFINE2(listen, int, fd, int, backlog) 8 { 9 struct socket *sock; 10 int err, fput_needed; 11 int somaxconn; 12 13 /* 查找socket结构 */ 14 sock = sockfd_lookup_light(fd, &err, &fput_needed); 15 if (sock) { 16 somaxconn = sock_net(sock->sk)->core.sysctl_somaxconn; 17 18 /* backlog不能超过设置值 */ 19 if ((unsigned int)backlog > somaxconn) 20 backlog = somaxconn; 21 22 /* 安全模块检查 */ 23 err = security_socket_listen(sock, backlog); 24 if (!err) 25 /* 调用具体协议族的listen函数,只有SOCK_STREAM支持listen */ 26 err = sock->ops->listen(sock, backlog); 27 28 fput_light(sock->file, fput_needed); 29 } 30 return err; 31 }
1 /* 2 * Move a socket into listening state. 3 */ 4 int inet_listen(struct socket *sock, int backlog) 5 { 6 struct sock *sk = sock->sk; 7 unsigned char old_state; 8 int err; 9 10 lock_sock(sk); 11 12 err = -EINVAL; 13 14 /* 检查socket状态和类型,仅支持SOCK_STREAM */ 15 if (sock->state != SS_UNCONNECTED || sock->type != SOCK_STREAM) 16 goto out; 17 18 /* 记录连接当前状态 */ 19 old_state = sk->sk_state; 20 21 /* 检查连接状态,需为close或者listen */ 22 if (!((1 << old_state) & (TCPF_CLOSE | TCPF_LISTEN))) 23 goto out; 24 25 /* Really, if the socket is already in listen state 26 * we can only allow the backlog to be adjusted. 27 */ 28 /* 如果尚未listen过 */ 29 if (old_state != TCP_LISTEN) { 30 /* Enable TFO w/o requiring TCP_FASTOPEN socket option. 31 * Note that only TCP sockets (SOCK_STREAM) will reach here. 32 * Also fastopen backlog may already been set via the option 33 * because the socket was in TCP_LISTEN state previously but 34 * was shutdown() rather than close(). 35 */ 36 /* TFO相关*/ 37 if ((sysctl_tcp_fastopen & TFO_SERVER_WO_SOCKOPT1) && 38 (sysctl_tcp_fastopen & TFO_SERVER_ENABLE) && 39 !inet_csk(sk)->icsk_accept_queue.fastopenq.max_qlen) { 40 fastopen_queue_tune(sk, backlog); 41 tcp_fastopen_init_key_once(true); 42 } 43 44 /* 开始监听 */ 45 err = inet_csk_listen_start(sk, backlog); 46 if (err) 47 goto out; 48 } 49 50 /* 设置backlog,包括已经listen过,调整backlog */ 51 sk->sk_max_ack_backlog = backlog; 52 err = 0; 53 54 out: 55 release_sock(sk); 56 return err; 57 } 58 EXPORT_SYMBOL(inet_listen);
其中inet_csk_listen_start函数将在阅读tcp代码时详细分析;
以上是关于listen系统调用的主要内容,如果未能解决你的问题,请参考以下文章