Show page source of internal22-291-切断処理第二段階 #25501

[[PageNavi(internal22-navi)]]

{{{ comment
h2w-title:切断処理第二段階
}}}
 

== 切断処理第二段階 == #SECTION07882000000000000000

次に、残された他方のソケットがcloseされた時の動作を説明する。

'''(step 4) '''

アプリケーションがTCP_CLOSE_WAIT状態のソケットからデータを読み尽くすとEOFが戻される。(一般に)これを契機にアプリケーションは、残されたTCP_CLOSE_WAIT状態のソケットをcloseする。

基本的に一つ目のソケットのcloseと同じ処理を行う。異なるのは、ソケットの状態がTCP_CLOSE_WAITからTCP_LAST_ACKに移行する点である。

  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_LAST_ACKに変更(tcp_close_state)する。
  *  FINパケットを送信する(tcp_send_fin関数) 
    *  まだ未送信のパケットがあればFIN情報を相乗りさせ、	(ソケットのsend_headが指すパケット)パケットを送出	(tcp_transmit_skb)。	パケットがない時は、FIN情報だけのパケットを新規	作成(sock_wmalloc)し、送出(tcp_send_skb)する。 
  *  setsockoptでlinger指定されているときは、	ソケットがTCP_LAST_ACKになるまで待つ。(送信相手から	FIN対するACKが返送されて来るまで待つ)

 [[Embed(internal22-images:img111.gif)]]
 

'''(step 5) ''' 先にcloseしたソケットはTCP_FIN_WAIT2状態になっている。TCP_FIN_WAIT2状態がFINパケットを受信(tcp_rcv_state_process関数)すると、tcp_fin関数を呼び出す。tcp_fin関数は、TCP_FIN_WAIT2状態のソケットをTIME_WAIT状態のtcp_tw_bucketとTCP_CLOSE状態のソケットの二つに作り直す(tcp_time_wait関数)。

  *  新規にtcp_tw_bucketを確保(kmem_cache_alloc)し、	TCP_FIN_WAIT2状態のソケットをtcp_tw_bucketにコピーする。	状態はTCP_TIME_WAITに初期化する。
  *  TCPポートキャッシュにTCP_TIME_WAITになったことを反映	(tcp_tw_hashdance関数)させる。
  *  tcp_tw_bucket削除のためのタイマを起動	(tcp_tw_schedule関数)する。2SML時間後にtcp_tw_bucketが	削除されることになる。
  *  TCP_FIN_WAIT2状態のソケットをTCP_CLOSE状態にし、一定時間後に	削除されるようにタイマの起動要求をだす。	まだTCPポートの解放は行わない。TCPポートの解放は	タイマ(net_timer)の延長で行われる。

'''(step 6) ''' 後からcloseしたソケットは、TCP_LAST_ACK状態になっている。これに対し通信相手のソケットからFINに対応するACKが戻ってくる。このACKを受信(tcp_rcv_state_process関数)すると、ソケットをTCP_CLOSE状態に遷移させ、一定時間後に削除されるようにタイマの起動要求をだす。

'''(step 7) '''TIME_WAIT状態のtcp_tw_bucketは、システム上に2MSL時間存在し続ける。生成されてから2MSL時間立つと、タイマ(tcp_twkill関数)がこのTIME_WAIT状態のtcp_tw_bucketの削除を行う。

TIME_WAIT状態のtcp_tw_bucketは、この2MSL時間TCPポートを占有し続けることになる。このTCPポート宛のパケットはtcp_tw_bucketが受信(tcp_timewait_state_process関数)し、応答を返す。

  *  正確には、先にコネクトされた相手ホストの同じポートからの	パケットのみtcp_tw_bucketが受ける。同じTCPポート宛で	あっても他のホストから送られてきたものや、同じ相手ホスト	でも別のポートから送られてきたものはtcp_tw_bucketは	受信しない。これは2MSL時間内であっても同じTCPポートを	再利用し、全く別のソケットとコネクションを確立することが	可能であることを示している。	BSDでの実装と異なり、RFCに忠実である。

'step 4'で送ったFINに対し、'step 5'で送り返したACKがネットワーク上でロストしたとき、再びFINが送られて来ることもあり、再度ACKを送り返さなければならない。

 [[Embed(internal22-images:img112.gif)]]
 

----

''(NIS)HirokazuTakahashi [[BR]]2000年06月11日 (日) 22時29分57秒 JST''1

[[PageNavi(internal22-navi)]]