/procでTCP接続リストを読む

/procでTCP接続リストを読む

各プロセスの既存のTCP接続をすべて列挙するコード(同様)を実装しようとしていますnetstat -lptn。私はそれに頼るのではなく、直接実装することを好みますnetstat。このために/proc/<PID>/net/tcp

以下にリストされている多くのTCP接続が表示されますが、/proc/<PID>/net/tcpコマンドを介しては表示されませんnetstat -lptn

/proc/1/net/tcpたとえば、いくつかのTCP接続でこれを見ました/proc/2/net/tcp(Ubuntu 16で試しました)。私が理解したところ、これはTCP接続があってはならないプロセスに関連しています/proc/1/net/tcp。また、/sbin/initそれに関連するTCP接続もあってはなりません/proc/2/net/tcpkthreadd

答え1

あなたのアプローチについて多くの誤解があります。一つずつ検討します。

  1. ソケットは特定のプロセスに関連付けられません。ソケットが作成されると、参照数は1です。ただし、別の方法(ファイル記述子を渡すdup2などfork)を使用して同じソケットへの参照を多数作成して、参照数を増やすことができます。これらの参照のいくつかは、多くのスレッドで利用可能な開かれたファイル記述子テーブルから入手できます。これらのスレッドは同じスレッドグループ(PID)に属することも、別のスレッドグループに属することもできます。この-pフラグを使用すると、netstat各プロセスにアクセスできるソケットを列挙し、既知の各ソケットのプロセスを見つけようとします。候補プロセスが複数ある場合、関心のあるプロセスが表示されるという保証はありません。
  2. /proc/<PID>/net/tcpこのプロセスに関連するソケットだけがリストされているわけではありません。プロセスが属するネットワーク名前空間のすべてのTCPv4ソケットを一覧表示します。デフォルト設定では、システム内のすべてのプロセスが単一のネットワーク名前空間に属するため、すべてのPIDに対して同じ結果が表示されます。また、ネットワークを使用していないスレッド/プロセスがこのファイルにコンテンツを持っている理由も説明します。ネットワーク自体を使用しなくても、他のプロセスはネットワークを使用できるネットワーク名前空間に属します。
  3. /proc/<PID>/net/tcpリスニングと接続ソケットが含まれています。-lこれを渡すと、リスニングソケットnetstatのみが表示されます。出力をより密接に一致させるには、-a代わりにが必要です-l
  4. /proc/<PID>/net/tcpTCPv4ソケットのみを含みます。/proc/<PID>/net/tcp6また、すべてのTCPソケットを表示するにはそれを使用する必要があります。

自分のプロセスと同じ名前空間にあるソケットにのみ興味がある場合は、他のPIDを繰り返す必要はありません。 yes/proc/net/tcp以降、代わりにシンボリックリンクを使用できます。/proc/net/tcp6/proc/net/proc/self/net

答え2

有効/proc/<pid>/fd- プロセスで使用されているソケットを含む、開いているすべてのファイル記述子を一覧表示します。例えば

/proc/1278482/fd:
total 0
dr-xr-xr-x. 9 user user  0 Apr 22 23:30 ../
dr-x------. 2 user user  0 Apr 22 23:30 ./
lr-x------. 1 user user 64 Apr 22 23:30 4 -> pipe:[640683476]
lrwx------. 1 user user 64 Apr 22 23:30 3 -> socket:[640754628]
lrwx------. 1 user user 64 Apr 22 23:30 2 -> /dev/pts/10
l-wx------. 1 user user 64 Apr 22 23:30 1 -> /home/user/my_sockets.txt
lrwx------. 1 user user 64 Apr 22 23:30 0 -> /dev/pts/10

その後、そのエントリ(たとえば640754628)を見つけて、/proc/<pid>/net/tcp -> inode[6]ソケットのすべての詳細を取得できます。

tcp:
  sl  local_address rem_address   st tx_queue rx_queue tr tm->when retrnsmt   uid  timeout inode
1864: 0100007F:A650 0100007F:18EB 01 00000000:00000000 00:00000000 00000000   500        0 640754628 1 0000000000000000 20 4 30 10 -1

(上記の例は127.0.0.1:6379へのローカル接続です)

関連情報