送信処理アルゴリズム

IPv4だけに限って説明する。IPv4とIPv6はtcp_funcテーブルにより処理を切り替えるが、ここではIPv4用の方だけを説明する。

アプリケーションからのデータ送信処理要求は、socketレイヤを経由しinet_sendmsg関数を呼び出す(struct proto_ops inet_stream_opsインターフェイステーブル経由)ことにより実現される。inet_sendmsg関数は、即tcp_sendmsg関数を呼び出す。(struct proto tcp_protインターフェイステーブル経由)。

tcp_sendmsg関数は、アプリケーションに指定されたデータ量を格納できるだけのパケット(sk_buff)を複数確保(alloc_skb)し、データを格納し送信を試みる(tcp_send_skb関数)(もしバッファが上限いっぱいになりパケットを確保できなときは、確保できるまで待ちに入る)ユーザ空間からパケットへデータをコピーするときには、同時にチェックサムも計算する(csum_and_copy_form_user関数)。

データをパケットにコピーするとき、もし既にソケットのwrite_queueにリンクされているが、まだ送信が開始されてないパケット(send_headが指しているパケット)に空き領域があれば(skb_tailroom関数)、まずこの空き領域に送信データを詰める。

img104.gif

tcp_send_skb関数は、渡されたパケットをソケットのwrite_queueへリンクし、write_seqシーケンス番号をそのパケットサイズ分進める。もし即送信可能な場合(tcp_snd_test関数)、パケットの複製を行い(skb_clone関数)送信を開始する(tcp_transmit_skb関数)。ソケットのsnd_nxtシーケンス番号も送信パケットのサイズ分進める。

このとき、送信処理が失敗したときに動作する再送タイマ(tcp_retransmit_timer関数)の起動要求も行う(tcp_reset_xmit_timer(TIME_RETRANS)関数)。

tcp_transmit_skb関数はTCPヘッダの作成を行い、チェックサムの計算(tcp_v4_send_check)を行ない(これは2回目のチェックサム計算だが、前回は行ったデータ部分のチェックサム結果に、ヘッダ部分のチェックサムを計算し加える操作を行う)、IPレイヤの送信関数(ip_queue_xmit)を呼び出す。ACK情報は今回送出したパケットに載せてあるため、遅延ACK要求は必要なくなり、要求をクリア(tcp_event_ack_sent関数)する。

注意 送信処理が終了しても、送信パケットが解放されずソケットにリンクされたままになっていることに注意。ウィンドウサイズを越えた送信パケットだけでなく、実際に送信を行ったパケットも再送の可能性があるため一定時間保留しておく。

img105.gif

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