Webサーバ

インターネット/トランスポート層 – TCP/IPスタック

tcpip_layer5

インターネット・プロトコル・スイート

インターネット/トランスポート層として、リンク層上にTCP/IPを実装します。今回の実装では、uIP*1を利用しました。

uIP

uIPは、Swedish Institute of Computer ScienceのAdam Dunkels氏が開発したオープンソースのTCP/IPスタックです。商用、非商用どちらでもフリーで利用できます。uIPはC言語で記述された、8bit CPUでも実装可能な小コードサイズとRAM使用サイズを特徴としたTCP/IPスタックであり、豊富なアプリケーションサンプル(Webサーバ、Webクライアント、SMTPクライアント、Telnetサーバ等)が付属しています。

uIPは以下のディレクトリで構成されています。

uipディレクトリにTCP/IPスタックコードが、apps/webserverディレクトリにWebサーバのアプリケーションサンプルが格納されています。今回は、主にこの2つのディレクトリのデータを利用して、TCP/IP及びHTTPの実装を行います。

uIPの移植

ターゲットとするシステムに組み込む為に、uIPコンフィグレーション・ファイルの設定とタイマー機能の実装を行います。

コンフィグレーションファイルの設定

uip-conf.hを書き換えて、各パラメータの設定を行います。主に、uIPで使用されるデータタイプの定義と、バッファサイズの指定を行います。

タイマーの実装

タイマーは、TCPの状態遷移をTIME_WAITからCLOSEDに遷移させる為や、パケットの再送タイミングとして使用されます。
今回は、SH-4Aの32bitタイマユニット(TMU2)を利用してタイマーを実装しています。以下の設定では、TMU2に対して1秒ごとにアンダーフローインタラプトが発生するように指定を行っています。(clock_init())

(clock-arch.h)

(clock-arch.c)

uIPの組み込み

TCP/IP処理のメインルーチンは、Ethernet Frameの受信インタラプトをトリガとして処理を開始します。Ethernet Frameを受信すると、typeフィールドの値を確認し、データがIP(Internet Protocol)の場合とARP(Address Resolution Protocol)の場合で処理を分岐します。

FrameデータがARPパケットの場合、uip_arp_arpin()をコールして応答用のARPパケットを生成します。応答用ARPには送信元のMACアドレスがセットされます。ARPパケットの生成後、ether_write_frame()をコールしてEthernet Frameを送信します。

FrameデータがIPの場合、次の順に処理を行います。

  1. uip_arp_ipin()をコールして、送信元のIPアドレスとMACアドレスの対応を確認し、内部ARPテーブルのアップデートを行います。
  2. uip_input()をコールしてTCPパケットの処理を行います。現在のTCPの遷移状態に従って、処理を行うイベントを判別し、UIP_APP_CALL()をコールします。HTTPは、この関数内で処理されます。
  3. UIP_APP_CALL()の結果、送信用のIPパケットが存在すれば、uip_arp_out()をコールしてEthernet Headerの作成を行います。
  4. ether_write_frame()をコールして、Ethernet Frameを送信します。
ether_pic5

uIP動作フロー

実際のコードは以下のようになります。コード中のuip_lenとuip_bufは、uIPで定義されているグローバル変数です。uIPとリンク層は、uip_lenとuip_bufを用いてデータの受け渡しを行います。uip_bufは送受信用のデータを格納する為に使用され、uip_lenは、送受信用データの長さを格納する為に使用されます。
(実装コード:SH4インタラプトハンドラ INTR IRQ2)


スポンサーリンク







  • このエントリーをはてなブックマークに追加
スポンサーリンク