[[PageNavi(internal22-navi)]]
{{{ comment
h2w-title:切断処理第一段階
}}}
== 切断処理第一段階 == #SECTION07881000000000000000
まず一方のソケットがcloseされた時の動作を説明する。
'''(step 1) ''' TCP用ソケットのcloseを行った場合、tcp_close関数が呼び出される。
1. ソケットのstate_changeメソッド呼び出しにより、このソケットで 待ちに入っているプロセスを起床する。
1. receive_queueにパケットがあるときは、そのパケットを破棄し、 ソケットを即TCP_CLOSE状態にし、終了する。
* TCP_CLOSE状態にすると同時に、遅延ソケット 削除タイマ(net_timer関数)の起動を行う (TIME_DONE)。TCPポートキャッシュからの削除も 行う(tcp_v4_unhash関数)。
* コネクション相手に強制的にRESETを送りつける (tcp_send_active_reset関数)
* receive_queueのパケットを全て読み出してからcloseを行った 場合はソケットの状態をTCP_FIN_WAIT1に変更(tcp_close_state)する。
* FINパケットを送信する(tcp_send_fin関数)
* まだ未送信のパケットがあればFIN情報を相乗りさせ、 (ソケットのsend_headが指すパケット)パケットを送出 (tcp_transmit_skb)。 パケットがない時は、FIN情報だけのパケットを新規 作成(sock_wmalloc)し、送出(tcp_send_skb)する。
* setsockoptでlinger指定されているときは、 ソケットがTCP_FIN_WAIT2になるまで待つ。(送信相手から FIN対するACKが返送されて来るまで待つ)
* TCP_FIN_WAIT2状態になったら、遅延ソケット削除タイマ (net_timer)の起動を行う。(tcp_check_fin_timer関数) linger指定の場合、相手のソケットがcloseしなくとも 一定時間経ったらソケットを削除してしまう。
[[Embed(internal22-images:img110.gif)]]
'''(step 2) ''' 通信相手から終了処理要求(FINパケット)を受けたときは以下のように動作する。
FINパケット受信処理はtcp_fin関数が行う。
* このソケットで待ちに入っているプロセスを起床する。
* FINのシーケンス番号をソケットのfin_seqメンバに記録する
* FINをうけたのがTCP_ESTABLISHED状態であった場合、そのソケットを TCP_CLOSE_WAIT状態へ推移させ、FINに対応するACKを送出する。
一度FINを受けると、そのシーケンス番号(fin_seq)以降のパケットが到着してもパケットを破棄するようになる(tcp_rcv_state_process関数)。
アプリケーションへのFINの通知は、EOFで行う。パケットの読みだし(tcp_rcvmsg関数)の処理中にFINフラグの立ったパケットを読み出すと、次回の読みだし処理(tcp_rcvmsg関数)はEOFを返すようになる。
'''(step 3) ''' 先にcloseを行ったソケットは、TCP_FIN_WAIT1状態になっている。これに対し通信相手のソケットからFINに対応するACKが戻ってくるとソケットをTCP_FIN_WAIT2状態に遷移させる(tcp_rcv_state_process関数)。
TCP_FIN_WAIT2状態が2MSL時間以上続かないよう、2MSL時間後にソケットを削除するためのタイマの起動も行っておく(tcp_reset_msl_timer関数)。接続相手のソケットがcloseを行わなかった場合の保険である。
もしFINに対応するACKパケットが届く前に、通常のデータパケットが届いた場合は破棄(kfree_skb関数)してしまう。破棄はするがACKの返送は行う(tcp_ack_snd_check関数)。エラーにはならない。
----
''(NIS)HirokazuTakahashi [[BR]]2000年06月11日 (日) 22時29分57秒 JST''1
[[PageNavi(internal22-navi)]]