質問: time_wait 時の振る舞い 現在、詳解 tcp/ip vol.1 の第 18 章を読んでいます. p.275 の 2msl 待ち状態の説明なのですが, 「msl 値を実装する場合のルールは,tcp がアクティブクローズを実行し,最後の ack を送ったとき,コネクションは msl が2回繰り替えされる時間だけ time_wait に止まっていなければいけないというものだ.これにより,最後の ack が消失した場合(この場合,他方のエンドはタイムアウトし,最後の fin を再転送する)でも,tcp は再度 ack を送ることが可能になる」 「コネクションが 2msl 待ちにあるときに遅れて到着したセグメントは、いかなるものでも破棄される」 と書いてあります. 前者にある,再転送された fin も破棄されるのですか? 破棄されるのに,それに対する ack を送ることは可能なのですか?可能と書いてあるだけで,実際には,再転送された fin に対する ack は送られないということでしょうか? そこがいまいち理解できません.いくつか調べたのですが,そこのところを詳しく書いてあるものは見当たりませんでした...
回答: > 再転送された fin も破棄されるのですか? 「破棄」という言葉が曖昧ですが、再転送されてきた fin は無視はされず、ack を返します。time_wait 状態はそのための状態です。 > 破棄されるのに,それに対する ack を送ることは可能なのですか? 「破棄」とは、単にtcp/ipスタックがパケットを無視するという意味ではありません。そして、ここでいう「セグメント」とは「アプリケーションデータ」と言い換えたほうがいいかもしれません。 ("segment" という単語は、アプリケーションが送ろうとしたデータがパケットへ分割された後の「破片」を暗に意味しています) この部分の言葉を補うとするなら、こんな感じです: 「コネクションが 2msl待ちにあるときに遅れて到着したデータは、 いかなるものでもアプリケーションに渡されず、破棄される」 このような動作とすべき理由は明らかです。 コネクションが 2msl待ち (time_wait状態) になったということは、相手方がこちらに送信したいデータについて、すべて受け取ったということを意味します[1]。この状態で、相手から何らかのtcpセグメント(アプリケーションデータ) を受け取るということは、それはネットワーク側で複製されてしまったパケットか、何らかの理由で相手が無駄に再送してきたパケットのいずれかのはずです。そのようなパケットに乗っているデータをアプリケーションに渡すと tcp の役目を果たせません [2] ので、破棄することになります。 > 再転送された fin に対する ack は送られないということでしょうか? いいえ、time_wait 状態で再度 fin を受信したら、必ず ack しなければなりません(そして再度 2msl待たなければなりません)。 そうしないと、通信する双方において、送信したいデータがすべて相手方に受信されたことが保証することができなくなってしまいます。 [1] rfc 793, 3.1. header format "fin" はもう送るデータは無いよ、ということを意味する。 [2] 相手のアプリケーションが送ろうとしたデータが、勝手に増殖した ことになるため。