[[PageNavi(internal24-navi)]]
{{{ comment
h2w-title:切断処理第二段階
}}}
== 切断処理第二段階 == #SECTION05882000000000000000
次に、残された他方のソケットがcloseされた時の動作を説明する。
'''(step 4) '''
アプリケーションがTCP_CLOSE_WAIT状態のソケットからデータを読み尽くすとEOFが戻される。(一般に)これを契機にアプリケーションは、残されたTCP_CLOSE_WAIT状態のソケットをcloseする。
基本的に一つ目のソケットのcloseと同じ処理を行う。異なるのは、ソケットの状態がTCP_CLOSE_WAITからTCP_LAST_ACKに移行する点である。
1. receive_queueにパケットがあるときは、そのパケットを破棄し、 ソケットを即TCP_CLOSE状態にし、終了する。
* TCP_CLOSE状態にすると同時に、 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(internal24-images:img115.gif)]]
'''(step 5) ''' 先にcloseしたコネクションはTCP_FIN_WAIT2状態になっている。TCP_FIN_WAIT2状態は、サブ状態がTCP_FIN_WAIT2であるtcp_tw_bucketとして存在している。
サブ状態がTCP_FIN_WAIT2であるtcp_tw_bucketがFINパケットを受信(tcp_timewait_state_process関数)すると、tcp_tw_bucketのサブ状態をTCP_TIME_WAITへ移行させる。
* サブ状態をTCP_TIME_WAITへ移行させる。
* tcp_tw_bucket削除のためのタイマを起動(tcp_tw_schedule関数) (tcp_tw_schedule関数)する。2SML時間後にtcp_tw_bucketが 削除されることになる。
* FINに対するACKを送り返す(tcp_v4_timewait_ack関数)。
'''(step 6) ''' 後からcloseしたソケットは、TCP_LAST_ACK状態になっている。これに対し通信相手のソケットからFINに対応するACKが戻ってくる。このACKを受信(tcp_rcv_state_process関数)すると、このソケットの解放を行う(tcp_done関数)。
'''(step 7) '''TCP_TIME_WAIT状態のtcp_tw_bucketは、システム上に2MSL時間存在し続ける。生成されてから2MSL時間立つと、タイマtcp_twcal_tick関数またはタイマtcp_twkill関数が起動され、このTIME_WAIT状態のtcp_tw_bucketの削除(tcp_timewait_kill関数)を行う。
TIME_WAIT状態のtcp_tw_bucketは、この2MSL時間TCPポートを占有し続けることになる。このTCPポート宛のパケットはtcp_tw_bucketが受信(tcp_timewait_state_process関数)し、応答を返す。
'step 4'で送ったFINに対し、'step 5'で送り返したACKがネットワーク上でロストしたとき、再びFINが送られて来ることもあり、再度ACKを送り返さなければならない。
[[Embed(internal24-images:img116.gif)]]
----
''(NIS)HirokazuTakahashi [[BR]]2000年12月09日 (土) 23時55分06秒 JST''1
[[PageNavi(internal24-navi)]]