Hatena::ブログ(Diary)

とあるSIerの憂鬱


20150503141725
2011 | 01 | 03 | 04 | 05 | 06 | 07 | 08 | 09 | 10 | 11 | 12 |
2012 | 01 | 02 | 03 | 04 | 05 | 06 | 07 | 09 | 11 | 12 |
2014 | 07 | 08 | 10 | 11 | 12 |
2015 | 01 | 02 | 03 | 04 | 05 | 06 |
2017 | 05 | 07 |
 | 

2012-12-22

Windows における TCP の再送機能を確認する

サーバー側と通信中に途中経路上で問題が発生するなどしてパケットをロストした場合、UDPであれば単純にそのパケットは失われる。TCPであれば再送機能が動作して、ある程度の期間の通信経路断(ケーブルが抜けるとか)は乗り越えてくれるはず。それ故にTCPなのだから。

今回は『ある程度の期間』とか『はず』というところを実際に検証してみた。この検証を行うきっかけになったものの関係で Windows Server 2008 R2 をクライアント側にし、Telnetクライアント側からTelnetサーバー側へのパケット通信を再送させる。

再送機能を制御しているパラメータ

TcpMaxDataRetransmissions

TCP通信において、パケットの再送を何回行うかを制御しているパラメータ。デフォルトは 5 であり、5回再送することになっている。

検証1 (デフォルト状態)

TcpMaxDataRetransmissions

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters に TcpMaxDataRetransmissions は定義されていないため、デフォルトの5が使われるべき。
f:id:incarose86:20121222235853p:image

検証内容

telnet 通信の確立後、数回 [ENTER] キーを入力して反応があることを確認。その後サーバー側のファイアウォールを有効にして telnet 通信ポート(23)を塞ぐ。そうしてから再度クライアント側で [ENTER] キーを入力する。このときの通信を Wireshark でパケットキャプチャして観察する。

検証結果

f:id:incarose86:20121222235851p:image


時系列(秒時点)動作前回送信からの経過時間(秒)初回送信からの経過時間(秒)
41.812[ENTER]入力によるデータ送信(初回)0.0000.000
42.1501回目の再送 (TCP Retransmission)0.3380.338
42.8212回目の再送 (TCP Retransmission)0.6711.009
44.1473回目の再送 (TCP Retransmission)1.3262.335
46.7994回目の再送 (TCP Retransmission)2.6524.987
52.0885回目の再送 (TCP Retransmission)5.28910.276
62.649TCPリセット送信(クローズ)10.56120.837
結果評価
  • 1回目の再送までの時間はラウンド・トリップ・タイム(RTT)をベースにして計算されるため、今回は 0.338(秒) が RTT だった。
  • n回目の再送は『前回送信からの経過時間』が RTT × 2n-1 に一致。再送時間が倍々になっていくという実装が確認できた。
  • TCPの接続が切られるのは5回目の再送がタイムアウトしたと判断されるタイミングであり、(許可されていれば)6回目の再送を行うタイミングである(今回は[ENTER]入力の20.837秒後)。
  • TCPの接続が切られるまでの累積時間は RTT × (20 + 21 + 22 + 23 + 24 + 25) = RTT × (26 - 1) になる。TcpMaxDataRetransmissions を使用して次の式で表せる。

RTT × (2TcpMaxDataRetransmissions + 1 - 1)

  • 実際のところは最後の再送までに経路回復しなければ通信の維持は困難だと考えると、経路ダウンの許容時間は最後の再送までの累積時間(最後の再送のタイムアウト時間を除く)であり、次の式になる。

RTT × (2TcpMaxDataRetransmissions - 1)


検証2 (TcpMaxDataRetransmissions を 7 に変更)

TcpMaxDataRetransmissions

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Tcpip\Parameters に TcpMaxDataRetransmissions を明示的に定義した。
f:id:incarose86:20121222235849p:image

検証内容

検証1と同様。

検証結果

f:id:incarose86:20121222235847p:image


時系列(秒時点)動作前回送信からの経過時間(秒)初回送信からの経過時間(秒)
36.131[ENTER]入力によるデータ送信(初回)0.0000.000
36.4721回目の再送 (TCP Retransmission)0.3410.341
37.1742回目の再送 (TCP Retransmission)0.7021.043
38.5933回目の再送 (TCP Retransmission)1.4192.462
41.4024回目の再送 (TCP Retransmission)2.8095.271
47.0185回目の再送 (TCP Retransmission)5.61610.887
58.2346回目の再送 (TCP Retransmission)11.21622.103
80.6367回目の再送 (TCP Retransmission)22.40244.505
125.439TCPリセット送信(クローズ)44.80389.308
結果評価
  • 再送回数は確かに5回から7回に増えた。
  • それ以外については検証1で確認できたことと同じ。

追加検証

6回目の再送から7回目の再送が行われるまでの間にサーバ側のファイアウォールを再度無効にし、telnet 通信ポート(23) を開放した。この場合は 7 回目の再送にサーバ側が応答し、通信を継続できた。
f:id:incarose86:20121222235845p:image

トラックバック - http://d.hatena.ne.jp/incarose86/20121222/1356193183
リンク元
 |