1.3 アーキテクチャ
前節ではネットワーク設計でまず欠かせない要件をいくつか見た ── コンピューターネットワークは一般的で、費用対効果に優れ、公平で、ロバストな接続を多数のコンピューターに提供しなければならない。さらに厄介なことに、ネットワークは常に変化する。ネットワークを支える下位の技術の変化、およびアプリケーションプログラムからの要請の変化を取り込みながらネットワークは進化しなければならない。加えて、ネットワークは様々なレベルのスキルを持つ人間によって簡単に管理できなければならない。こういった要件を満たすネットワークの設計は簡単な仕事ではない。
この複雑性に対処するために、ネットワーク設計者はネットワークの設計と実装における手引きとして一般的な設計図 ── ネットワークアーキテクチャ (network architecture) と呼ばれることが多い ── を開発した。本節では全てのネットワークアーキテクチャに共通する中心的なアイデアを紹介することで、「ネットワークアーキテクチャ」の意味をより詳細に定義する。また OSI (7 層) アーキテクチャとインターネットアーキテクチャという最もよく言及される二つのアーキテクチャも説明する。
1.3.1 層とプロトコル
複雑性を管理するシステム設計者が利用する基礎的なツールに抽象化 ── 細かく定義されたインターフェースの後ろに実装の詳細を隠すこと ── がある。抽象化のアイデアは、システムが持つ重要な特徴の一部を捉えるモデルを定義し、そのモデルをオブジェクトでカプセル化し、システムの他のコンポーネントから操作できるインターフェースをそのオブジェクトから提供し、オブジェクトがどのように実装されるかに関する詳細をオブジェクトのユーザーに開示しないというものである。抽象化では、数多くの状況で有用となるサービスを提供しつつも、下位のシステムで効率良く実装できるモデルを特定することが課題となる。これは前節でチャンネルの考え方を紹介したときに行っていたことと全く同じである: アプリケーション開発者のために、ネットワークの複雑性を隠蔽する抽象化を我々は提供しようとしている。
特にネットワークシステムでは、抽象化から層化が自然に導かれる。層化の一般的なアイデアは、下位のハードウェアが提供するサービスから初めて、そこに上位の (より抽象的な) サービスを積んでいくというものである。上位の層で提供されるサービスは下位の層で提供されるサービスを使って実装される。
例えば前節における要件の議論で考えたネットワークでは、アプリケーションプログラムと下位のハードウェアの間に抽象化の層が二つ存在すると考えることができる (図 8)。ハードウェアのすぐ上にあるのはホスト間の接続を提供する層であり、どんな複雑なネットワークトポロジーがホスト間に存在したとしても、それを同じように抽象化する。その上にある層は利用可能になったホスト接続サービスを利用してプロセス間のチャンネルを実装する層であり、例えば「ネットワークがたまにメッセージを喪失する」といった事実を隠蔽する。
層化は二つの有用な機能を提供する。まず、層化によってネットワークの構築という問題が管理しやすい小部分に分かれる。行いたい処理を全て行うモノリシックなソフトウェアのパーツを実装するのではなく、問題を部分ごとに解決する層をいくつか実装することで全体を実装できる。次に、層化によって設計のモジュール性が増す。新しいサービスを追加するとき、機能の変更が必要になる層は一つだけで、他の層が提供する機能は全て再利用できる可能性がある。
しかし、システムを層が一つずつ積み上がったものとみなすのは単純化が過ぎる。多くの場合システムの各層では複数の抽象化が提供され、それぞれが同じ下位の抽象化を使って異なるサービスを上位の層に提供する。前節で議論した二種類のチャンネルはこの例である: リクエスト/リプライサービスを提供するチャンネルと、メッセージストリームサービスを提供するチャンネルの二つが存在する。これら二つのチャンネルが複数の層を持つネットワークの特定の層で両方用意されるかもしれない。図 9 にそのようなネットワークの例を示す。
層に関する以上の議論を基礎として、ネットワークのアーキテクチャをさらに正確に議論する準備が整った。まず、ネットワークの層を構成する抽象オブジェクトはプロトコル (protocol) と呼ばれる。つまり、プロトコルは上位のオブジェクト (アプリケーションプロセスや上位のプロトコルなど) がメッセージの交換に利用する通信サービスを提供する。例えば、前述したリクエスト/リプライチャンネルとメッセージチャンネルにそれぞれ対応するリクエスト/リプライプロトコルとメッセージプロトコルをサポートするネットワークを考えることができる。
それぞれのプロトコルは二つの異なるインターフェースを定義する。第一に、プロトコルの通信サービスを利用する同じコンピューター上の他のオブジェクトに向けてサービスインターフェース (service interface) を定義する。このサービスインターフェースは、ローカルなオブジェクトがプロトコルに対して行える操作を定める。例えばプロトコル/リプライプロトコルはアプリケーションがメッセージを送信および受信するための操作をそれぞれサポートするだろう。HTTP プロトコルではリモートサーバーからハイパーテキストのページを取得する操作がサポートされ、ウェブブラウザといったアプリケーションは新しいページを取得する必要が生じたとき (例えばユーザーが現在表示中のページに含まれるリンクをクリックしたとき) にそういった操作を呼び出す。
第二に、プロトコルは他のマシンに存在する相手 (ピア) に向けたピアインターフェース (peer interface) を定義する。このピアインターフェースは、通信サービスを実装するためにプロトコルピア間でやり取りされるメッセージの形式と意味を定める。例えば、あるマシンのリクエスト/リプライプロトコルが他のマシンのピアと通信する方式はピアインターフェースで定義される。HTTP の場合には、HTTP プロトコルの仕様が GET
コマンドはどのような形式か、コマンドと共に使える引数は何か、そしてウェブサーバーはそういったコマンドを受け取ったときに何をすべきかといったことを細かく定める。
まとめると、プロトコルはローカルに公開される通信サービス (サービスインターフェース) と、そのサービスを実装するためにピアとやり取りするメッセージの規約 (ピアインターフェース) を定義する。この事実を図 10 に示す。
ピア同士が物理媒体を通じて直接通信するハードウェアのレベルを除けば、ピア同士の通信は間接的に行われる ── 各プロトコルは下位のプロトコルのいずれかを使ってメッセージをピアとやり取りし、下位のプロトコルは自身のピアとメッセージをやり取りする。加えて、一つの層に複数のプロトコルが存在し、それぞれが異なる通信サービスを提供することがあり得る。そのため、ネットワークシステムを構成するプロトコルの集合を表すときはプロトコルグラフ (protocol graph) が使われる。プロトコルグラフの頂点はプロトコルに対応し、辺は「... は ...に依存する」の関係を表す。ここまで例として使ってきた仮定的な層状システムのプロトコルグラフを 図 11 に示す。RRP (リクエスト/リプライプロトコル) と MSP (メッセージストリームプロトコル) は二つの異なるプロセス間チャンネルを実装し、どちらもホスト間の接続サービスを提供する HHP (ホスト間プロトコル) に依存している。
この例で、ホスト 1 のファイルアプリケーションが RRP によって提供される通信サービスを使ってホスト 2 のピアにメッセージを送る状況を考えよう。このとき、ファイルアプリケーションは自身の代わりにメッセージを転送してもらうよう RRP に要求する。RRP はピアと通信するために HHP のサービスを起動し、これを受けて HHP のサービスがメッセージをホスト 2 のピアに送信する。メッセージがホスト 2 の HHP インスタンスに到着すると、HHP はメッセージを RRP に受け渡し、RRP はファイルアプリケーションにメッセージを受け渡す。このシナリオにおいて、アプリケーションは RRP と HHP からなるプロトコルスタック (protocol stack) を利用していると言う。
「プロトコル」という単語が二つの異なる意味で使われていることに注意してほしい。「プロトコル」が抽象的なインターフェース ── つまり、サービスインターフェースが定義する操作と、ピアインターフェースが定義するピア間で交わされるメッセージの形式と意味 ── を意味する場合もあれば、その二つのインターフェースを実際に実装するモジュールを「プロトコル」と呼ぶ場合もある。インターフェースとインターフェースを実装するモジュールを区別するために、本書では前者のことをプロトコル仕様 (protocol specification) と呼ぶ。一般に仕様は散文、疑似コード、状態遷移図、パケットの形式を示す図、その他の抽象的な記法を使って記述される。異なるプログラマーが異なる方法で仕様に準拠した実装を作成できるプロトコル仕様が望ましいとされる。ただし同じ仕様の異なる実装が正しくメッセージを交換できることを保証するのは一つの課題である。二つ以上のプロトコルモジュールが正確にプロトコル仕様を実装するとき、それらのモジュールは相互運用 (interoperate) すると言う。
あるアプリケーションの集合が与えられたとき、その通信要件を満たすプロトコルとプロトコルグラフは数多く考えられる。幸いにも、プロトコルグラフに対するポリシーを定める標準化団体が存在する。IETF (Internet Engineering Task Force) や ISO (International Standards Organization, 国際標準化機構) がその例である。本書ではプロトコルグラフの要素と形状を定める規約をネットワークアーキテクチャ (network architecture) と呼ぶ。本書の範囲ではないものの、標準化団体はプロトコルを紹介、検証、そして最終的には団体が管理するアーキテクチャに属するプロトコルとして承認するための詳細に定められた手続きを持つ。ここでは IETF と ISO が定義するアーキテクチャを簡単に説明する。ただその前に、プロトコルを積み重ねる仕組みに関して説明しておくべき事項が二つある。
1.3.2 カプセル化
図 11 において、アプリケーションプログラムがピアにメッセージを送るために RRP へメッセージを渡したとする。RRP の視点からすると、アプリケーションから渡されたメッセージは解釈を持たない単なるバイト列に過ぎない。そのバイト列が表すのが整数の配列なのか、メールの文章なのか、デジタル画像なのかを RRP は全く気にかけない。RRP はバイト列を自身のピアまで届けるように命じられただけである。しかしそうだとしても、RRP は何らかの制御情報をピアに送って、送信したメッセージを受け取ったときに何をすべきかをピアに伝える必要がある。RRP はメッセージにヘッダー (header) を付けることでこれを行う。一般に、ヘッダーとはピア同士の通信のためにピアが利用する小さな ── 数バイトから数十バイト程度の ── データ構造を言う。名前の通り、ヘッダーはメッセージの先頭に付けられることが多い。ただし、ピア同士の通信に関する情報がメッセージの末尾に付く場合もあり、そのときはヘッダーではなくトレイラー (trailer) と呼ばれる。RRP によって付けられるヘッダーの正確なフォーマットは RRP のプロトコル仕様によって定義される。メッセージの残りの部分 ── つまり、アプリケーションに代わって RRP が転送しているデータ ── はメッセージの本体 (body) あるいはペイロード (payload) と呼ばれる。以上の状況を指して、アプリケーションのデータはRRP が作成する新しいメッセージの中に カプセル化 (encapsulation) されると言う。
このカプセル化のプロセスはプロトコルグラフの各頂点で繰り返される。例えば HHP は RRP のメッセージに HHP 独自のヘッダーを付けることでそれをカプセル化する。HHP が何らかのネットワークを通してメッセージをピアに届けると仮定すれば、宛先のホストに到着したメッセージには逆の順番で処理が行われる: 最初に HHP がメッセージの最初にある HHP ヘッダーを解釈 (例えばヘッダーの内容に応じて適切な処理を実行) し、メッセージの本体 (HHP ヘッダーを除いた部分) を RRP に渡す。RRP はそのメッセージに含まれる RRP ヘッダーが指示する処理を実行し、本体 (RRP ヘッダーを除いた部分) をアプリケーションプログラムに渡す。ホスト 2 で RRP からアプリケーションプログラムに渡されるこのメッセージは、ホスト 1 でアプリケーションプログラムが RRP に渡したメッセージと完全に一致する。下位の通信サービスの実装のために付けられたヘッダーをアプリケーションプログラムが見ることはない。以上の処理を図 12 に示す。なお、この例でネットワーク内のノード (スイッチやルーター) はメッセージの先頭にある HHP ヘッダーを調べる場合がある。
「下位プロトコルは上位プロトコルから渡されたメッセージを解釈しない」は「渡されたメッセージから意味のある情報を取り出す方法を知らない」という意味であることに注意してほしい。下位のプロトコルが渡されたデータに対して単純な変形 (圧縮や暗号化など) を施す場合はある。その場合、プロトコルはオリジナルのアプリケーションのデータと上位プロトコルが加えた全てのヘッダーからなるメッセージの本体全体を変形する。
1.3.3 多重化と逆多重化
パケット交換の根本にあるアイデアは「複数のデータフローを単一の物理リンクで多重化する」だったことを思い出してほしい。このアイデアはパケット交換だけではなく、プロトコルグラフを上り下りするメッセージにも適用できる。例えば図 11 において、RRP は論理的な通信チャンネルを実装しているとみなせる。ホスト 1 で二つの異なるアプリケーションからのメセージは RRP が実装する単一のチャンネルで多重化され、ホスト 2 で適切なアプリケーションへと逆多重化される。
これが実装で何を意味するかと言えば、RRP がメッセージへ付け足すヘッダーにはメッセージが属するアプリケーションを記録する識別子が含まれるという単純な事実を意味する。この識別子を RRP の逆多重化鍵 (demultiplexing key, 略して demux key) と呼ぶ。送信元ホストで RRP は適切な逆多重化鍵をメッセージのヘッダーに加える。そのメッセージが宛先ホストの RRP に届けられると、RRP はヘッダーを取り出し、逆多重化鍵を調べ、正しいアプリケーションにメッセージを逆多重化する。
RRP だけが逆多重化を行うわけではない。ほぼ全てのプロトコルがこの仕組みを実装し、例えば HHP はメッセージを RRP と MSP のどちらに渡せばいいかを判断するための逆多重化鍵を利用する。しかし、プロトコルの間には ── 単一のネットワークアーキテクチャ内のプロトコルの間にさえ ── 逆多重化鍵に何を使うかに関する合意が存在しない。8 ビットフィールドを使う (つまり最大でも 256 個の上位プロトコルしか扱えない) プロトコルもあれば、16 ビットあるいは 32 ビットのフィールドを使うプロトコルもある。また、ヘッダーに含まれる逆多重化鍵が一つの場合もあれば二つの場合もある。前者ではメッセージを届けるべき上位プロトコル (あるいはアプリケーションプログラム) を特定するのに通信の両端で同じ逆多重化鍵が使われ、後者では両端で異なる鍵が使われる。
1.3.4 OSI モデル
ISO はコンピューター同士を接続する統一された方法を正式に定義した最初の組織の一つである。ISO が定義したアーキテクチャは OSI (Open Systems Interconnection) アーキテクチャと呼ばれる。このアーキテクチャではネットワークの機能が 7 つの層に分割され、各層の機能は一つ以上のプロトコルによって実装される (図 13)。この意味で、図 13 が示すのはプロトコルグラフそのものではなく、プロトコルグラフの参照モデル (reference model) である。この参照モデルは「7 層モデル (the 7-layer model)」と呼ばれることが多い。現在 OSI アーキテクチャをベースとしたネットワークは存在しないものの、このモデルが定義する用語はよく使われるので、軽く触れるだけの価値は今でもある。
一番下から見ていくと、物理層 (physical layer) は通信リンクを通した生のビットの転送を担当する。データリンク層 (data link layer) はビットの連なりをフレーム (frame) と呼ばれる大きな単位にまとめる。ネットワークアダプターやノードのオペレーティングシステムで実行されるデバイスドライバは通常データリンク層を実装する。これはホストに届けられるのが実際には生のビットではなくフレームであることを意味する。続いてネットワーク層 (netrowk layer) はパケット交換ネットワークにおけるノード間のルーティングを担当する。この層においてノード間でやり取りされるデータの一単位はフレームではなくパケット (packet) と通常呼ばれる。ただし本質的にはフレームとパケットは同じものである。ここまでの下から三つの層はスイッチやネットワークの外から接続されるホストを含めた全てのネットワークノードで実装される。続くトランスポート層 (transport layer) では、我々がこれまでプロセス間のチャンネルと呼んできたものが実装される。この層ではデータ交換の単位がフレームやパケットではなくメッセージとなる。トランスポート層およびそれより上位の層はエンドホストにのみ存在し、中間のスイッチやルーターには存在しない。
ここからは最上位層 (第 7 層) から下に向かって見ていこう。まずアプリケーション層がある。アプリケーション層の代表的なプロトコルに HTTP (Hypertext Transfer Protocol) がある。HTTP はワールドワイドウェブの基礎であり、ウェブブラウザがウェブサーバーにページをリクエストするときに使われる。その下のプレゼンテーション層 (presentation layer) はピアがやり取りするデータのフォーマットを管理する ── 例えば整数のビット数は 16, 32, 64 のどれなのか、最上位ビットが送られるのは最初なのか最後なのか、映像ストリームはどのような形をしているのか、といった約束事を担当する。最後のセッション層 (session layer) は一つのアプリケーションに含まれる異なるトランスポートストリームを一つにまとめるときに使われる名前空間を提供する。例えば音声ストリームと映像ストリームが存在するビデオ会議アプリケーションで利用される。
1.3.5 インターネットアーキテクチャ
図 14 と 図 15 に示すインターネットアーキテクチャ (Internet architecture) は、主に利用される二つのプロトコルの名前を取って TCP/IP アーキテクチャ (TCP/IP architecture) と呼ばれることもある。インターネットアーキテクチャは ARPANET と呼ばれる初期のパケット交換ネットワークでの経験から生まれたものであり、その名の通りインターネットで利用されている。インターネットと ARPANET はどちらもアメリカ国防省の研究開発資金提供機関の一つ ARPA (Advanced Research Projects Agency, 高等研究計画局) の資金で開発された。インターネットと ARPANET は OSI 参照モデルより前から存在しており、この二つのネットワークを構築する中で得られた経験は OSI 参照モデルに大きな影響を及ぼした。
OSI 7 層モデルによるインターネットの説明は (多少解釈を歪めれば) 不可能ではないものの、通常はもっと簡単なスタックが代わりに使われる。図 14 で最下位にあるのは NET1, NET2 といった様々なネットワークプロトコルである。実際には、こういったプロトコルはハードウェア (例えばネットワークアダプター) とソフトウェア (例えばネットワークデバイスドライバ) を組み合わせて実装される。例えば IEEE 802.11 (Wi-Fi) 規格などの無線プロトコルやイーサネットプロトコルがこの層に存在する (これらのプロトコルの中にも層は存在するものの、インターネットアーキテクチャはそういった層に関して何も仮定しない)。次の層には IP (Internet Protocol) が一つだけ存在する。IP は様々なネットワークテクノロジの相互接続を単一の論理的なインターネットワークへと変換する。IP の上には二つの主要なプロトコルが示されている ── TCP (Transmission Control Protocol) と UDP (User Datagram Protocol) である。TCP と UDP はそれぞれ異なる種類の論理チャンネルをアプリケーションプログラムに提供する: TCP は信頼性のあるバイトストリームチャンネルを、UDP は信頼性のないデータグラム (datagram) の転送チャンネルを提供する (ここでデータグラムはメッセージと同じ意味だと考えて構わない)。インターネットの言葉では、TCP と UDP をエンドツーエンドプロトコル (end-to-end protocol) と呼ぶこともある。ただし「トランスポートプロトコル」と呼んだ方が正確ではある。
このトランスポート層の上には HTTP, FTP, Telnet, SMTP (Simple Mail Transfer Protocol) といったよく使われるアプリケーションの相互運用を可能にする幅広いアプリケーションプロトコルが存在する。アプリケーション層プロトコルとアプリケーションの違いは、様々なワールドワイドウェブブラウザ (Firefox, Chrome, Safari, Netscape, Mosaic, Internet Explorer など) が存在する事実を考えると理解できるだろう。ウェブサーバーにも同程度に数多くの異なる実装が存在する。ウェブ上の任意のページにどのアプリケーションプログラムからでもアクセスできるのは、それぞれが同一のアプリケーション層プロトコル HTTP に準拠しているためである。なお、紛らわしいことに、アプリケーションが利用するアプリケーション層プロトコルがアプリケーションの呼び名になる場合がある (例えば「FTP」は FTP プロトコルを実装するアプリケーションの名前としてよく使われる)。
IETF と 標準化
インターネットアーキテクチャを「IETF アーキテクチャ」とは呼ばないものの、このアーキテクチャおよびそこに属する多くのプロトコル (TCP, UDP, IP, DNS, BGP など) の仕様を策定する標準化団体は IETF だと言っても過言ではないだろう。ただ、インターネットアーキテクチャには他の団体が策定するプロトコルも多く取り込まれている。いくつか例を挙げるだけでも、IEEE のイーサネットと Wi-Fi の規格、W3C の HTTP/HTML に関するウェブ仕様、3GPP のセルラーネットワーク規格 4G と 5G、そして ITU-T の映像符号化規格 H.232 などがある。
アーキテクチャの定義やプロトコルの仕様策定を行う団体の他にも、インターネットの相互運用性という大きな目標へ向けた活動を行うさらに別の団体が存在する。IANA (Internet Assigned Numbers Authority, インターネット番号割当機関) はそのような団体の一つである。IANA はその名前の通り、様々なプロトコルを正しく動作させるために必要な一意識別子の管理を行う。IANA はインターネットの全体的な財産管理を行う非営利団体 ICANN (Internet Corporation for Assigned Names and Numbers) の一部署である。
ネットワークの分野で活動する人の多くはインターネットアーキテクチャと OSI の 7 層アーキテクチャの両方を知っており、二つのアーキテクチャ間の対応関係にも一般的な合意が存在する。インターネットアーキテクチャのアプリケーション層は第 7 層に、トランスポート層は第 4 層に、IP 層 (インターネットワーキング層または単にネットワーク層) は第 3 層に、その下のリンク層 (またはサブネット層) は第 2 層に対応する。
インターネットアーキテクチャは注目に値する特徴を三つ持つ。第一に、図 15 に示すように、インターネットアーキテクチャは厳密な層化を要求しない。アプリケーションはトランスポート層を迂回して IP あるいは下位のネットワークを直接使って構わない。さらに言えば、プログラマーは既存の任意のプロトコルの上で動作する新しいチャンネル抽象化やアプリケーションを定義して構わない。
第二に、図 14 のプロトコルグラフをよく見ると、砂時計の形をしているのが分かる ── 上は広く、中央は細く、下は広い。実は、この形はインターネットアーキテクチャの中心的哲学を示している。つまり、IP がアーキテクチャ全体の要となる ── IP は幅広いネットワークの間でパケットをやり取りする共通の方法を定める。IP の上にはトランスポートプロトコルをいくつでも作成でき、それぞれのプロトコルがアプリケーションプログラムに様々なチャンネル抽象化を提供する。そのため、メッセージをホストからホストへ届ける問題はプロセスからプロセスへの有用な通信サービスを提供する問題と完全に切り離される。また IP の下に許されているネットワークテクノロジに制限はない。イーサネット、無線リンク、単一のポイントツーポイントリンクなど、何を使っても構わない。
インターネットアーキテクチャが持つ最後の特徴 (より正確には、IETF の文化が持つ特徴) は、新しいプロトコルが正式にインターネットアーキテクチャの一部となる前に、プロトコルの仕様と少なくとも一つ (場合によっては二つ) の実装が必要になることである。IETF が採用する規格には動作する実装の存在が要求される。設計コミュニティが文化的に課しているこの条件は、インターネットアーキテクチャのプロトコルが効率的に実装できることを保証するために存在する。インターネットの文化が動作するソフトウェアにどれほどの価値を置くかは、IETF 会合でよく見かける T シャツに書かれた次の格言に見ることができるだろう:
王を、大統領を、そして投票を我々は拒絶する。我々は大まかな合意と動作するコードを信じる。
── David Clark
教訓
本節で紹介したインターネットアーキテクチャの三つの特徴の中では、「砂時計」の設計哲学が繰り返すに値するほどの重要性を持つ。砂時計の細いくびれは注意深く選ばれた最小限のグローバル機能であり、上位のアプリケーションと下位の通信テクノロジの共存、機能の共有、そして素早い進化を可能にする。インターネットがユーザーからの新しい要望と変化を続ける技術に素早く応える上でこの細いくびれを持ったモデルは極めて重要である。