Linux上で実行され、サーバーへのTCP接続を生成するJavaおよびcppクライアントアプリケーションがあります。これらのアプリケーションはTCP接続を確立した後、これらのTCP接続のKeepaliveパラメータを変更します。つまり、LinuxのデフォルトのKeepalive秒である7200秒が、特定のTCP接続のアプリケーションで300に変更されます。
$cat /proc/sys/net/ipv4/tcp_keepalive_time
7200
$cat /proc/sys/net/ipv4/tcp_keepalive_intvl
75
$cat /proc/sys/net/ipv4/tcp_keepalive_probes
9
消費者保護計画
setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, 300, sizeof(int));
setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, 60, sizeof(int));
setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, 5, sizeof(int));
Java
sslSocket.setOption(ExtendedSocketOptions.TCP_KEEPIDLE, 300);
sslSocket.setOption(ExtendedSocketOptions.TCP_KEEPINTERVAL, 60);
sslSocket.setOption(ExtendedSocketOptions.TCP_KEEPCOUNT, 5);
私の質問は、Linuxターミナルで確立されたTCP接続(これらのアプリケーションによって生成された特定の接続について)への接続保持間隔/遅延/プローブカウント値が何であるかを確認する方法があることです。
アプリケーションで確立された特定のTCP接続を識別したら、その特定の接続の接続保持値を印刷したいと思います(そして、これらのTCP接続にアプリケーションによって確立された接続保持値があることを確認し、OSのデフォルトではありません)。
答え1
TCP接続の維持は、2つのピア間に独立して存在します(相互の設定をネゴシエートまたは知らない)。したがって、クライアントに接続の維持が設定されているかどうかを確認することができます。
ss
(rt)netlinkソケットを使用する最新のツールは、Linuxでは使用されなくなったこの情報を(少なくとも)部分的に入手できます。netstat
ソケット構成ではなく現在の状態を検索できます。
たとえば、クライアントはホスト192.0.2.4ポート5555への接続を確立し、接続維持アイドル時間は120秒に設定されています。socat
次のように再現できます。
socat -d -d tcp4:192.0.2.4:5555,keepalive=1,keepidle=120 -
-e / --extended
追加オプションが利用可能ですss
(カーネル5.17.xとIP ルート 25.18.0):
$ ss -tne dst == 192.0.2.4 and dport == 5555
State Recv-Q Send-Q Local Address:Port Peer Address:Port Process
ESTAB 0 0 192.0.2.3:40498 192.0.2.4:5555 timer:(keepalive,1min58sec,0) uid:1000 ino:4007748 sk:432 cgroup:/user.slice/user-1000.slice/session-2.scope <->
以下は、timer:(keepalive,1min58sec,0)
ソケットの現在のアクティブ状態の維持に関する情報です。接続が完了するまで約2秒かかりますので、1分58秒が表示されます。 2mnの初期設定はここでは提供されません。
単純なアプリケーションでは、GDBなどのデバッガツールを使用してシステムコールをgetsockopt(2)
注入して、特定のソケットで設定を検索して表示できます(PID(複数のPIDで共有可能)およびFDソケットを検索するss
オプションも必要です)。-p
以下は、その情報が特定のコアに適用されないQ&Aの例です。タブインターフェイスとそのファイル記述子間の接続を見つけるには?
しかし、futexとcoのスレッド間で多くの同期を使用するJavaなどのマルチスレッドアプリケーションでは、デバッガを使用するとタイムアウト割り込みによる副作用がないかどうかはわかりません。
答え2
私の考えにはないと思います。はい私が知っているすべてのシェルでこれを行う方法です。ss
この情報自体は表示されません。おそらく、意味のある方法で他のプロセスにエクスポートされていないプロセス状態にすぎません。
したがって、「ツール型デバッガ」がおそらくこれを達成する唯一の方法でしょう。
ptrace
- ターゲットプロセスに接続して停止し、[実行するgdb
作業]。call
実際には、つまり、少しの状態を保存し、スタックを構築し、正しいレジスタを設定し、コマンドポインタをに設定し、最後のスタックフレームがポップするgetsockopt
まで実行し、結果を処理し、ステータスと元のコマンドポインタを復元して実行し続けます。 。
これはシェルでできることではありません!