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代码时详细分析;

 

转载于:https://www.cnblogs.com/wanpengcoder/p/7618389.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值