
組み込み用ソフトとしてのTCP/IPを開発している。つまり私は,組み込みのエンジニアでもあり,プロトコルのエンジニアでもある。一見,組み込みとプロトコルの二足のわらじを履き替えながら作業しているように思えるかもしれないが,実際は少し違う。例えると,組み込みのワラとプロトコルのワラで編み込んだ二色のわらじを履いているようなものだ。
それぞれのワラは特性がまったく異なる。このため,履き心地は甚だ悪い。色の取り合わせも悪趣味かもしれない。そもそも,この二色のわらじを編むことでも苦労が絶えない。それでもこの数年間,毎日,二色のわらじを編み,履きつづけてきた。
どちらのワラに優先度をおくのかは,まだ自分でもはっきりしていない。例えばあるRFCを読む。すると必要なメモリの消費量が思い浮かぶ。結局,そのRFCを読まなかったことにしたくなる。顧客から出されたハードウエアの仕様書を見て,「動くわけないじゃん」と心の中でため息をつくこともある。こんな日が続くと,RFCの編集者が使っているであろうシステムと,私が担当するシステムの違いに思いをはせ,暗い気分になったりする。
それでも,情けないCPUとちょぴりのメモリ,果てはデバイスを特定できない割り込みコントローラで構成されるシステムに,メモリ食いのRFCを何とか押し込んで無事にTCP/IPを動かしたときは,「こんな経験が出来るのは私達だけだ」と思わず鼻息が荒くなる。
紆余曲折はあったが,2000年の秋に,IPv6をサポートする組み込み用TCP/IPスタックを発表できた。2001年4月には,「AVE-TCPv6.0 SDK」という名称で,ソース・コードでの販売にもこぎ着けた。
しばしば,「組み込み用途のTCP/IPとUNIXなどの汎用OS向けTCP/IPとではどこが違うのか」という質問を受ける。プロトコルから見れば双方に違いはない。そうでないと,インターオペラビリティが確保できなくなってしまう。
では違いはどこにあるか。私は,スタック自身が使用できるメモリ量の差と,スタックが使用するサービスをOSに期待できるかどうか,つまり使用できるリソースの差だけではないかと思っている。
少し前までは,FA用器材などに組み込み用ソフトを提供することが多かったので,メモリ量は期待できた。だが,最近は個人向けのポータブルな機器への組み込みの要求が増えているため,TCP/IPで使用できるメモリ量はますます乏しくなっている。
汎用OSのTCP/IPの場合,内部で保持するテーブルなどのメンテナンスやメモリ管理はOS内部のユーティリティを使える。これが組み込みになると,RTOSがそれらの機能を持たないので,すべてを自前で準備しなければならない。
例えば,UNIXの実装では,アプリケーションからの要求はsocketに集約され,メモリの管理はmbufで実現され,ルーティング・テーブルはradixで管理されている。これらのカーネル内のサービスはUNIXのプロトコルを効率よく動かすために準備されたものだが,TCP/IPの進化と共に進化し,洗練されてきている。
もちろん,このようなサービスのしがらみで逆に苦労しているUNIXエンジニアもいるだろう。幸か不幸か組み込み用途のTCP/IPでは,このような洗練されたサービスがまったく期待できない。そのため,APIは独自,メモリ管理は手作り,ルーティング・テーブルはもとよりすべてのテーブルのサーチもメンテナンスもすべて自前となる。
メモリ管理の方法としては,UNIXのmbufのように,プロトコルが必要に応じて獲得するアプローチがある。だが,この方法はピーク時の必要量を算出しにくいので,概してメモリ量が貧弱な組み込み用途には採用できない。UNIXの場合なら,最悪panicしてもそれはrootの責任であり,カーネルを再構築してrebootすれば済む。しかし組み込みにおいて再構築とは,製品回収を意味するからだ。
こうした問題を回避するために,AVE-TCPv6.0では,メモリ管理をサブモジュールごとに細かく分離した。NICのドライバがパケットを受信するための領域,ARPやNDPがハードウエア・アドレスを解決中のパケットを保存するための領域,リアセンブル途中のIPパケットを保存するための領域,TCPの送受信ウインドウのための領域--と用途別に細かく分類し,それぞれに単純なメモリ管理機能を持たせたのだ。こうして,ピーク時のメモリ消費量を明確にしている。
ルーティング・テーブルやその他の情報を格納するテーブルもすべて自前で管理する。そのためのユーティリティもスタック内に記述した。組み込み用のプロトコル・スタックの開発は,これらの作業量が極めて多いのが特徴といえる。
二色のわらじを履いている私は,もっぱらこうしたプロトコル以前の部分の実装に悩む日々を送っている。
汎用機で動作するCOBOLの事務処理プログラマをスタートに,CP/M,MS-DOSのアプリケーション・プログラマ,UNIXの移植エンジニアなどを経て,組み込み用のTCP/IPの開発,移植,メンテナンス,サポートに携わる。職場ではソフトウエアの移植に悩み,家庭では胡蝶蘭の移植に苦心している。来年は花が咲くかもしれない。
組み込み用ソフト
外見はコンピュータに見えないが,内部にコンピュータを持った機器のソフトウエア。応用例としては,テレビ,ビデオ,冷蔵庫等の家電機器,自動販売機や工場のライン制御等の工業用機器,果ては自動車から人工衛星までと幅広い。パソコンなどと比べるとCPUは性能・機能に乏しく,メモリ量も少ないことが多い。なお,現在,日本で最も多く出荷されている組み込み応用製品は携帯電話である。
読まなかったことにした
IPv6 Jumbograms(RFC 2675) 64Kバイトから4Gバイトまでの長さのIPv6パケットについて記述したRFC。
メモリ食い
IPv4のTotal LengthもIPv6のPayload Lengthも16ビット長なので,パケットの最大長は65535バイトに達する。不用意にIPパケットのリアセンブルを実装すると,かなりのメモリを消費する。
鼻息が荒くなる
リソース
資源のこと。狭義にはソフトウエアで利用できるメモリの量。広義にはあるソフトウエアで利用できるハードウエアや他のソフトウエアの機能。
テーブル
ソフトウエアで表現した表。IPパケットのあて先を判定するために参照される表がルーティング・テーブル。
RTOS
組み込みソフトウエアのためのOS。real time operating systemの略。国産のRTOSの仕様としてはITRONが有名である。
socket
UNIXでアプリケーション・プロトコルを記述するときに使用されるオブジェクト。TCP/IPの標準的なAPIでもある。
mbuf
UNIXでプロトコルが使用するデータを格納するために使われるメモリの構造体。
radix
ルーティング・テーブルなどを高速検索するために,最近のUNIXに導入された技術。
panic
UNIXが正常に動作できなくなり,ハングアップするときに表示される文字列。UNIXのシステム・ダウンを意味する。
root
UNIXのシステム管理者が使用するユーザ名。
NIC
network interface controllerの略。Ethernetに接続するためのハードウエアのこと。
ARP
ソフトウエアのアドレスからハードウエアのアドレスへの変換に使用されるプロトコル。IPv4のアドレスからEthernetのアドレスへの変換に使われる。IPv4の仕様には含まれていない。
NDP
IPv6のアドレスからハードウエアのアドレスへの変換にも使用されるプロトコル。ICMPv6の仕様の一部である。