在 /proc/sockstat 中,哪些 TCP 状态算作“正在使用”,哪些算作“分配”?

Par*_*ime 3 linux networking kernel tcp

例如,在 /proc/net/sockstat 中, CLOSE_WAIT 中的 TCP 套接字是否被计为 'inuse' 或 'alloc' ?

在内核源net/ipv4/proc.c中,我看到 从/proc/net/sockstat获取信息时调用了sockstat_seq_show 。

但是我看不出套接字与分配(alloc)和“inuse”有什么区别

[me@myhostname ~]$ cat /proc/net/sockstat
sockets: used 481
TCP: inuse 52 orphan 1 tw 66 alloc 62 mem 12
UDP: inuse 11 mem 5
UDPLITE: inuse 0
RAW: inuse 0
FRAG: inuse 0 memory 0
Run Code Online (Sandbox Code Playgroud)

在 net/tcp_states.h 中,枚举了可能的状态

enum {
    TCP_ESTABLISHED = 1,
    TCP_SYN_SENT,
    TCP_SYN_RECV,
    TCP_FIN_WAIT1,
    TCP_FIN_WAIT2,
    TCP_TIME_WAIT,
    TCP_CLOSE,
    TCP_CLOSE_WAIT,
    TCP_LAST_ACK,
    TCP_LISTEN,
    TCP_CLOSING,    /* Now a valid state */
    TCP_NEW_SYN_RECV,

    TCP_MAX_STATES  /* Leave at the end! */
Run Code Online (Sandbox Code Playgroud)

};

以上哪些算作“inuse”,哪些算作“alloc”?

Arm*_*ali 5

\n

以上哪些算作“inuse”,哪些算作“alloc”?

\n
\n\n

通过定位,您已经接近答案sockstat_seq_show- 我们可以看到“inuse”是 的值sock_prot_inuse_get(net, &tcp_prot),而“alloc”是 的值proto_sockets_allocated_sum_positive(&tcp_prot)。现在,进一步追踪调用链并不总是那么容易,但如果我没有弄错的话,我会得出以下结论。

\n\n
    \n
  1. \'alloc\' - 底部是 的总和percpu_counter tcp_sockets_allocated,在 中递增tcp_init_sock();套接字状态被初始化为TCP_CLOSE。无论套接字在其存在期间经历什么状态变化,“alloc”都不依赖于 - 所有 TCP 状态都算作“alloc”
  2. \n
  3. \'inuse\' - 这是(每个 CPU)计数器的总和net->core.inuseprot_inuse(对于本例中的 TCP),它本质上是通过调用sock_prot_inuse_add(\xe2\x80\xa6, 1)resp 来递增和递减的。(\xe2\x80\xa6, -1)分别inet_hash()inet_unhash()。中的条件inet_hash()if (sk->sk_state != TCP_CLOSE),因此除了 之外的所有 TCP 状态都TCP_CLOSE 计为 \'inuse\'
  4. \n
\n\n
\n

我认为这意味着理论上任何处于 >= TCP_CLOSE 状态的套接字都不会被算作“正在使用”

\n
\n\n

在我看来,不可能是这样,因为 TCP_LISTEN > TCP_CLOSE 也是如此,并且处于 TCP_LISTEN 状态的套接字肯定被算作“inuse”,例如

\n\n
(cd /proc/net; cat sockstat; nc -l 8888& sleep 1; cat sockstat; kill $!; cat sockstat)|grep TCP\n
Run Code Online (Sandbox Code Playgroud)\n