TCPのシーケンスで準正常の動作をケーススタディしてみました。


【正常シーケンス】

正常シーケンスにおけるH8OSの動作を右図に示します。
このシーケンスは、コネクションの確立、クライアントからサーバへ5byteデータを送信し、その応答にサーバは7byteのデータを返信、それに対するクライアントからのACKに対し、サーバは6byteのデータを送信、クライアントから3byteのデータを送信、クライアントからコネクションをクローズ、という例です。
H8OSをトレースしたところでは、PSHフラグを一切判定しておらず、データ通信状態(TCP_ESTAB)でのデータの有無は受信データが0でないかどうかで判定しています。

図0:正常シーケンス
【準正常シーケンス】

(1) コネクション確立の応答の紛失
TCP_SYNRCDV状態ではSYNを受けても何も動作しない不具合がある。


図1:コネクション確立の応答の紛失


(2) コネクション確立のACKの紛失
ACKを受けないとTCP_ESTAB状態に遷移せず、データパケットを受けても無視されてしまう。


図2:コネクション確立のACKの紛失

(3) 受信データのACK紛失
再送パケットを受けると余計なインクリメントを行った確認番号を送信してしまう。
また、APLでは再送パケットであるかどうかを判定できない。再送パケットであるかどうかを判定できるように、シーケンス番号をAPLに通知するように改良した。


図3:受信データのACK紛失

(4) 送信データのACK紛失
送信データを紛失した場合にはH8OSでは再送を行わないので、APLで再送処理を行う必要がある。
また、受信したACK番号が、自分が送ったACK番号+送信したデータ長と同じになっていないようであればACKの抜けであるので、その場合にも再送が必要となる。オリジナルのH8OSではACK番号はAPLに通知されないので、ACK番号をAPLに通知するように改良した。


図4:送信データのACK紛失

(5) 送信したACKの紛失
ACKが紛失するとクライアントはデータの再送を行うが、 H8OSでは再送か否かを判定できない。受信した再送データに対して APLは同じ処理を実行するが、ACK番号は前回と同じものにならないので、 おそらくクライアントは無視する。その結果このTCPセッションは利用不可となる。クライアントからクローズすればセッションは終了する。
上記に対応できるようにするために、シーケンス番号をAPLに通知するように改良してAPLで再送データか否かを判定可能とすると共に、ACK番号が正しく設定されるように改良した。


図5:送信データのACK紛失


戻る