CLOSE_WAITの状態が続くとどうなるか

相手のアプリケーションがcloseして、こちらのアプリケーションがcloseせずにいる場合(ハーフクローズの状態、上の図参照)、一定時間後に相手側のFIN_WAIT2と、こちらのCLOSE_WAITが消えた。この現象は、2つのタイマーが関係しているらしい。

  • FIN_WAIT2は、 tcp_fin_timeout でタイムアウトする。デフォルトは60秒。
  • CLOSE_WAITは tcp_keepalive_time 秒後に(デフォルトは2時間)、接続が有効かどうかを確認する(keep-aliveプローブを送信)。
    • 相手側がFIN_WAIT2で待っている場合は、ACKが返ってきて接続が維持される。
    • 相手側が tcp_fin_timeout によってクローズ済みの場合、リセット(RST)が返ってきて、こちら側もクローズになる。
    • 断線などで相手まで到達できなかった場合、 tcp_keepalive_intvl (デフォルト75)秒置きに、tcp_keepalive_probes (デフォルト10)回プローブを送信する。

keep-aliveプローブは、ソケットオプションの SO_KEEPALIVE がオンの場合にのみ送信される。

SO_KEEPALIVEは、アプリケーションがソケットごとに設定できる。タイムアウト値はシステム全体で同じ値が使われる。

自分の環境(VMWare上のFC5)で、tcp_keepalive_timeを変える方法。特に再起動などしなくても、設定が変わっていた。

# echo 30 > /proc/sys/net/ipv4/tcp_keepalive_time

そのほかの値も、 /proc/sys/net/ipv4 以下に書いてある。


参考: 『詳解TCP/IP vol.1』