RTT 未満の値での TCP_USER_TIMEOUT

RTT 未満の値での TCP_USER_TIMEOUT

を考慮してTCP_USER_TIMEOUTの説明:

値が 0 より大きい場合、TCP が対応する接続​​を強制的に閉じてアプリケーションに ETIMEDOUT を返す前に、送信されたデータが未確認のままになる最大時間をミリ秒単位で指定します。

そしてRFCからのこのコメント:

USER TIMEOUT 値が短すぎると、遅延の大きいパスを介した TCP 送信に影響する可能性があります。未処理のセグメントの確認応答が到着する前に、パケット損失などによりユーザー タイムアウトが発生すると、接続が閉じられます。多くの TCP 実装では、USER TIMEOUT 値が数分にデフォルト設定されています。UTO オプションでは短いタイムアウトが提案されますが、短いタイムアウトを通知するアプリケーションでは、これらの影響を考慮する必要があります。

TCP_USER_TIMEOUT が 2 ミリ秒の場合、悲惨な結果になると思います。RTT が 2 ミリ秒未満のネットワークでは、送信されたすべての TCP パケットが ACK を待機してタイムアウトし、接続が閉じられます。ただし、私の環境では、このような状況は発生していません。接続を確立でき、データの送受信は正常に行われます。ただし、コードを抜いたり、受信インターフェイスを切断したりすると、TCP_USER_TIMEOUT が接続の損失を効果的に検出し、接続が適切なタイミングで閉じられることに気付きました。つまり、TCP_USER_TIMEOUT は機能していますが、期待どおりには機能していません。

TCP_USER_TIMEOUT について何を誤解しているのでしょうか? RTT より低い値では接続が切断されないのはなぜですか?

参考までに、私のクライアントは 2.6.32 カーネルを搭載した Scientific Linux 6.1 ボックスです。

答え1

Linux での UTO 実装は不正確でしたが、最近このパッチセットによって修正されました:(念のため、このパッチセットの作成者ではない場合は): https://lkml.org/lkml/2018/7/18/1090

ただし、UTO が発動した後でも、ホストは再送信を停止し、TCP_CLOSE 状態に移行しますが、接続はリセットされません。RST を送信するのはアプリケーションの責任です。

関連情報