TCP の信頼性 ~再送制御と RTO~
TCP の信頼性は、以下の記事の通り、シーケンス番号 (Seq#) と応答確認番号 (Ack#) で実装されます。
パケット送信側は Ack が戻ってこないパケットについては『パケットが欠けた』と判断し、再送をしますが、再送タイマのタイムアウト時間 (RTO) は RTT 値を元に計算されます。
RTT 値は、データを送ってから ACK が戻ってくるまでの時間のことで、Window サイズ毎に 1 パケットだけサンプリングされます。
さらにこの RTT 値は Smooth RTT (SRTT) 値の計算に用いられます。SRTT 値の計算式は以下の通りです。
α は 0.9 が推奨されています。
また、RTO は以下の式が利用されています。
Windows の再送間隔と再送回数
Windows では TCP コネクション時の初期値として RTO = 1秒 が使われているようです。以下はブラウザの Chrome にて 1.2.3.4 宛の通信を試みて失敗したときのパケットキャプチャです。
1 秒後に再送し、その次は 2 秒後、その次は 4 秒後、その次は 8 秒後と再送時間を倍にしていき、5 回目を送った後に諦めます。
つまり、Windows では TCP 再送回数はデフォルトで 4 回となっています。
変更したい場合は以下のように「TcpMaxDataRetransmissions」レジストリを修正します。
- Windowsキー+R
- regedit [Enter]
- HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters と辿る
- 右ペインで右クリックし、「新規」⇒「DWORD」で左クリック
- 名前を「TcpMaxDataRetransmissions」に設定する
- 再送回数を10回にしたい場合は16進数ならa、10進数なら10でセットする
- 下記のようになったら再起動
チェックサム
データが欠けるパターンとして、データが送られてこない、というパターンと、送られてきたデータが誤っている、というパターンがあります。
送られてきたデータの誤りを検出する仕組みがチェックサムです。
チェックサムの計算方法は、以下の擬似 IP ヘッダフォーマットを利用します。
チェックサムの対象は擬似 IP ヘッダと TCP ヘッダ (ただしチェックサムのフィールドを 0 に置き換える)、TCP データの 3 つです。
これらを 16 bit 単位に分割し、各々で "1 の補数" を計算し、それらを合計します。さらにその合計値の "1 の補数" を取ることで、チェックサムに入る 16 bit が決まります。
TCP であるにもかかわらず、レイヤーの低い IP ヘッダも一部ではありますがチェックしていることに注目して下さい。
IPv4 では、IP ヘッダ自身のチェックサムも行なっており、IP の上に TCP が使われる場合は IP ヘッダを重複してチェックをかけていることになります。
IPv6においては、TCP と一緒に使われる機会が多いことと、通信技術の向上により誤り率が低くなったことから、IPv6 ヘッダのチェックサムは無くなりました。
その代わり、TCP 等のように、上位レイヤーでこれを実施することが望まれます。
nesukeの推薦図書
以下に該当する人なら熟読することを強く推奨します。
- 周りのネットワークエンジニアよりも一歩抜き出た存在となり、価値を高めたい!
- サーバエンジニアだけどネットワークも含めた総合的なセキュリティへの理解も深めていきたい!
コメント