web-dev-qa-db-ja.com

TCP / procからの接続リストを読み取る

私は既存のすべてのTCP接続ごとの接続を列挙するコードを実装しようとしています(netstat -lptnと同様)。私はそれを自分で実装し、netstatに依存しないことを好みます。それを行うために、 /proc/<PID>/net/tcpからデータを解析しています。

多くのTCP接続が/proc/<PID>/net/tcpの下にリストされていますが、netstat -lptnコマンドによってリストされていないことがわかりました。

たとえば、/proc/1/net/tcp/proc/2/net/tcpにはいくつかのTCP接続が存在することがわかります(Ubuntu 16で試してみました)。私が理解しているように、/proc/1/net/tcp/sbin/initプロセスに関連しており、TCP接続。/proc/2/net/tcpkthreaddに関連しており、これもTCP接続を持つことはできません。

5
Dima

あなたのアプローチには多くの誤解があります。 1つずつ説明します。

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

独自のプロセスと同じ名前空間のソケットのみに関心がある場合は、異なるPIDを反復処理する必要はありません。 /proc/net/tcp/proc/net/tcp6へのシンボリックリンクであるため、代わりに/proc/netおよび/proc/self/netを使用できます。

9
kasperd