応答(ACK)受信と送信再開

ウィンドウサイズを越えた送信要求があった場合、送信パケットはソケットのwrite_queueに繋いだまま保留にされる。送信処理開始を待っているパケットの先頭はsend_headメンバにより押えられている。

送信相手から返信されたACKパケットを受け取るとtcp_ack関数が呼び出される。tcp_ack関数は、ACKシーケンス番号で示されたシーケンス番号以前のデータのパケットの破棄を行い(tcp_clean_rtx_queue関数)、ウィンドウ情報(ソケットのsnd_wnd,snd_unaメンバ)の更新を行う。

ACKシーケンス番号とウィンドウサイズにより、下図のようにウィンドウがスライドし、送信再開が可能となる。send_head以降に繋がれていた送信パケットのうち、下記新しいウィンドウに入るパケットの送信を開始する。

tcp_data_snd_check関数は、データパケット受信処理の最後で呼び出される。送信ウィンドウ内に新しいパケットが入った場合、送信の起動をかける(tcp_write_xmit関数)。相手へ送信不能の状態であればプローブタイマ(tcp_probe_timer関数)の起動を要求(tcp_reset_xmit_timer(TIME_PROBE0)関数)する。

tcp_write_xmit関数は送信可能となったパケット全てに対してパケットの送信(tcp_transmit_skb関数)を行う。送信したパケットの分だけソケットのsend_headポインタを進める。

プローブタイマ(tcp_probe_timer関数)は、シーケンス番号を進めずデータなしのパケットを相手に送りつけることにより、相手から最新のACKまたは最新のウィンドウサイズを返してもらう。(ウィンドウサイズが0の状態でACKパケットがロストした場合、送受信が止まったまま再開されなくなることを避けるため)

img106.gif

(NIS)HirokazuTakahashi
2000年12月09日 (土) 23時55分06秒 JST
1