Linuxカーネルに関する技術情報を集めていくプロジェクトです。現在、Linuxカーネル2.6解読室の第2章までを公開中。
サーバ側処理前半処理の最後に送出したSYN+ACKパケットにより、クライアント側のソケットはSYN_SENTからESTABLISH状態に遷移する。このときクライアントはACKパケットを返送して来る。このACKパケットに対し、サーバはESTABLISH状態のソケットを生成する。
パケットはtcp_v4_rcv, tcp_v4_do_rcv関数を通して入って来る。受信ソケットがTCP_LISTEN状態である場合、まずtcp_v4_hnd_req関数が呼び出される。受信したパケットがACKパケットである場合、tcp_v4_hnd_req関数は以下のように動作する。
tcp_v4_hnd_req関数は、まず受信したパケットに対応するopenreqがあるか検索(tcp_v4_search_req関数)し、tcp_check_req関数を呼び出す。
tcp_check_req関数は、受信したパケットがSYNパケットである場合は、パケットをロストしたことを意味するので、SYN+ACKパケットの再送を行う(tcp_v4_send_synack関数)。受信したパケットがACKパケットである場合は、クライアント側のソケットがTCP_ESTABLISHEDになったことを意味する。サーバ側でもそれに対応するのソケットを生成する(syn_recv_sockメソッド tcp_v4_syn_recv_sock関数)。
tcp_v4_syn_recv_sock関数は、新規にSYN_RECV状態のソケット生成をし(tcp_create_openreq_child)初期化する(openreqの情報をソケットにコピー)。(もしsetsockoptでKEEP ALIVE有効を指定されていた場合は、ここでKEEPALIVEタイマの起動をかける。tcp_reset_keepalive_timer関数)
新しいソケットが生成されたら古いopenreqを解放(tcp_synq_unlink関数)し、新しく生成したソケットを親ソケットのアクセプトキューにリンクする(tcp_acceptq_queue関数)。
更に、新規に生成したSYN_RECV状態のソケットに対しては、最後にtcp_chiled_process関数が呼び出される。tcp_chiled_process関数は、tcp_rcv_state_process関数がを呼び出し、ソケットの状態をESTABLISHEDに推移させ、その後ソケットのdata_readyメソッド呼び出しで、accept待ちのサーバを起こす。
次々にコネクション要求が到達すると、上図のような状態になる。acceptされるのを待っているESTABLISHED状態のソケットが、accept_queueにリンクされ、コネクション確立処理途中のSYN_RECV状態のopenreqがソケットのsyn_tableに複数リンクされた状態になる。
(NIS)HirokazuTakahashi
2000年12月09日 (土) 23時55分06秒 JST1
[PageInfo]
LastUpdate: 2008-08-27 14:17:45, ModifiedBy: hiromichi-m
[Permissions]
view:all, edit:login users, delete/config:members