2. Overview of ICE (ICE概要)
典型的なICE展開では、通信を希望する2つのエンドポイント (ICEエージェント, ICE agents) があります。ICEは、シグナリングプロトコル (signaling protocol) のNAT越えを目的としたものではなく、別のメカニズムによって提供されることを前提としていることに注意してください。ICEは、エージェントが互いの間にシグナリング接続を確立できることを前提としています。
最初、エージェントは自身のトポロジーを知りません。特に、エージェントはNATの背後にある場合もあれば、そうでない場合もあります (または複数層のNATの背後にある場合もあります)。ICEにより、エージェントはトポロジーに関する十分な情報を発見し、データセッションを確立できる1つ以上のパスを潜在的に見つけることができます。
図1は、典型的なICE展開を示しています。エージェントはLとRとラベル付けされています。LとRはどちらも、それぞれのNATの背後にありますが、それに気付いていない可能性があります。NATのタイプとそのプロパティも不明です。LとRは、候補交換 (candidate exchange) プロセスに参加することができます。このプロセスの目的は、LとRの間にデータセッションを設定することです。通常、この交換はシグナリングサーバー (例えば、SIPプロキシ) を通じて行われます。
エージェント、シグナリングサーバー、NATに加えて、ICEは通常、ネットワーク内のSTUNまたはTURNサーバーと連携して使用されます。各エージェントは独自のSTUNまたはTURNサーバーを持つことができますし、同じものを使用することもできます。
+---------+
+--------+ |Signaling| +--------+
| STUN | |Server | | STUN |
| Server | +---------+ | Server |
+--------+ / \ +--------+
/ \
/ \
/ <- Signaling -> \
/ \
+--------+ +--------+
| NAT | | NAT |
+--------+ +--------+
/ \
/ \
+-------+ +-------+
| Agent | | Agent |
| L | | R |
+-------+ +-------+
図1: ICE展開シナリオ
ICEの背後にある基本的な考え方は次のとおりです。各エージェントには、他のエージェントとの通信に使用できる、さまざまな候補トランスポートアドレス (candidate transport addresses) (特定のトランスポートプロトコルのIPアドレスとポートの組み合わせ、本仕様では常にUDP) があります。これらには以下が含まれる可能性があります。
- 直接接続されたネットワークインターフェース上のトランスポートアドレス
- NATの公開側の変換されたトランスポートアドレス ("サーバー反射アドレス (server-reflexive address)")
- TURNサーバーから割り当てられたトランスポートアドレス ("リレーアドレス (relayed address)")
潜在的には、Lの候補トランスポートアドレスのいずれかを使用して、Rの候補トランスポートアドレスのいずれかと通信できます。しかし、実際には、多くの組み合わせは機能しません。例えば、LとRが両方ともNATの背後にある場合、それらの直接接続されたインターフェースアドレスは直接通信できる可能性は低いです (結局のところ、これがICEが必要な理由です!)。ICEの目的は、どのアドレスペアが機能するかを発見することです。ICEがこれを行う方法は、1つ以上の機能するペアが見つかるまで、すべての可能なペアを (慎重にソートされた順序で) 体系的に試すことです。
2.1. Gathering Candidates (候補の収集)
ICEを実行するために、ICEエージェントは1つ以上のアドレス候補を識別して収集します。候補はトランスポートアドレス (transport address) を持ちます -- 特定のトランスポートプロトコル (ここではUDPのみが指定されています) のIPアドレスとポートの組み合わせです。候補にはさまざまなタイプがあります。一部は物理的または論理的なネットワークインターフェースから派生し、その他はSTUNとTURNを介して発見可能です。
最初のカテゴリの候補は、ローカルインターフェースから直接取得したトランスポートアドレスを持つ候補です。このような候補は「ホスト候補 (host candidate)」と呼ばれます。ローカルインターフェースはイーサネットまたはWi-Fiである可能性があり、または仮想プライベートネットワーク (Virtual Private Network, VPN) やモバイルIP (Mobile IP, MIP) などのトンネルメカニズムを通じて取得されたものである可能性があります。すべての場合において、このようなネットワークインターフェースは、エージェントにとってローカルインターフェースとして表示され、そこからポート (したがって候補) を割り当てることができます。
次に、エージェントはSTUNまたはTURNを使用して追加の候補を取得します。これらには2つのタイプがあります: NATの公開側の変換されたアドレス (サーバー反射候補, server-reflexive candidates) とTURNサーバー上のアドレス (リレー候補, relayed candidates)。TURNサーバーが利用される場合、両方のタイプの候補がTURNサーバーから取得されます。STUNサーバーのみが利用される場合、サーバー反射候補のみがそれらから取得されます。これらの候補とホスト候補との関係を図2に示します。この図では、両方のタイプの候補がTURNを使用して発見されます。図中の表記X:xは、IPアドレスXとUDPポートxを意味します。
To Internet
|
|
| /------------ Relayed
Y:y | / Address
+--------+
| |
| TURN |
| Server |
| |
+--------+
|
|
| /------------ Server
X1':x1'|/ Reflexive
+------------+ Address
| NAT |
+------------+
|
| /------------ Local
X:x |/ Address
+--------+
| |
| Agent |
| |
+--------+
図2: 候補の関係
エージェントがIPアドレスとポートX:xからTURN Allocateリクエストを送信すると、NAT (存在する場合) はバインディングX1':x1'を作成し、このサーバー反射候補をホスト候補X:xにマッピングします。ホスト候補から送信される出力パケットは、NATによってサーバー反射候補に変換されます。サーバー反射候補に送信される入力パケットは、NATによってホスト候補に変換され、エージェントに転送されます。特定のサーバー反射候補に関連付けられたホスト候補が「ベース (base)」です。
注: 「ベース (Base)」は、エージェントが特定の候補に対して送信元とするアドレスを指します。したがって、退化したケースとして、ホスト候補もベースを持ちますが、それはホスト候補と同じです。
エージェントとTURNサーバーの間に複数のNATがある場合、TURNリクエストは各NATでバインディングを作成しますが、最も外側のサーバー反射候補 (TURNサーバーに最も近いもの) のみがエージェントによって発見されます。エージェントがNATの背後にない場合、ベース候補はサーバー反射候補と同じになり、サーバー反射候補は冗長であり、削除されます。
その後、AllocateリクエストはTURNサーバーに到着します。TURNサーバーは、ローカルIPアドレスYからポートyを割り当て、Allocate応答を生成し、このリレー候補をエージェントに通知します。TURNサーバーはまた、AllocateリクエストのソーストランスポートアドレスをAllocate応答にコピーすることにより、サーバー反射候補X1':x1'をエージェントに通知します。TURNサーバーはパケットリレーとして機能し、LとRの間でトラフィックを転送します。Lにトラフィックを送信するために、RはY:yのTURNサーバーにトラフィックを送信し、TURNサーバーはそれをX1':x1'に転送します。これはNATを通過し、X:xにマッピングされてLに配信されます。
STUNサーバーのみが利用される場合、エージェントはSTUN Bindingリクエスト [RFC5389] をSTUNサーバーに送信します。STUNサーバーは、BindingリクエストのソーストランスポートアドレスをBinding応答にコピーすることにより、サーバー反射候補X1':x1'をエージェントに通知します。
2.2. Connectivity Checks (接続性チェック)
Lがすべての候補を収集すると、優先度の高いものから低いものへと順序付けし、シグナリングチャネルを介してRに送信します。RがLから候補を受信すると、同じ収集プロセスを実行し、独自の候補リストで応答します。このプロセスの終わりに、各ICEエージェントは自身の候補と相手の候補の両方の完全なリストを持っています。それらをペアにして、候補ペア (candidate pairs) を形成します。どのペアが機能するかを確認するために、各エージェントは一連の接続性チェックをスケジュールします。各チェックは、クライアントがローカル候補からリモート候補にSTUNリクエストを送信することによって、特定の候補ペアで実行するSTUNリクエスト/応答トランザクションです。
接続性チェックの基本原則はシンプルです:
- 候補ペアを優先順位順にソートします。
- 優先順位順に各候補ペアでチェックを送信します。
- 他のエージェントから受信したチェックを確認します。
両方のエージェントが候補ペアでチェックを実行すると、結果は4ウェイハンドシェイクになります:
L R
- -
STUN request -> \ Lの
<- STUN response / チェック
<- STUN request \ Rの
STUN response -> / チェック
図3: 基本的な接続性チェック
STUNリクエストは、データに使用される完全に同じIPアドレスとポート (例えば、RTP、RTCPまたは他のプロトコル) から送信されることに注意することが重要です。したがって、エージェントは、受信ポートではなくパケットの内容を使用してSTUNとデータを逆多重化します。
接続性チェックにSTUN Bindingリクエストが使用されるため、STUN Binding応答には、エージェントとその相手の間の任意のNATの公開側のエージェントの変換されたトランスポートアドレスが含まれます。このトランスポートアドレスが、エージェントがすでに学習した他の候補のアドレスと異なる場合、それは新しい候補 (ピア反射候補, peer-reflexive candidate) を表し、その後、他の候補と同じようにICEによってテストされます。
上記のアルゴリズムはすべての候補ペアを検索するため、動作するペアが存在する場合、アルゴリズムは候補が試行される順序に関係なく、最終的にそれを見つけます。より高速な (そしてより良い) 結果を生成するために、候補は指定された順序でソートされます。ソートされた候補ペアのリストは「チェックリスト (checklist)」と呼ばれます。
エージェントは、リスト上の次の候補ペアに対して定期的にSTUNリクエストを送信することによってチェックリストを処理します。これらは「通常のチェック (ordinary checks)」と呼ばれます。STUNトランザクションが成功すると、1つ以上の候補ペアがいわゆる「有効なペア (valid pairs)」になり、「有効リスト (valid list)」と呼ばれる候補ペアリストに追加されます。
最適化として、RがLのチェックメッセージを受け取るとすぐに、Rは同じ候補ペアでLに送信される接続性チェックメッセージをスケジュールします。これは「トリガーされたチェック (triggered check)」と呼ばれ、有効なペアを見つけるプロセスを加速します。
このハンドシェイクの終わりに、LとRの両方が、両方向でエンドツーエンドでメッセージを送信 (および受信) できることを知っています。
一般に、優先度アルゴリズムは、類似したタイプの候補が類似した優先度を取得するように設計されているため、より直接的なルート (つまり、データリレーやNATのないルート) が間接的なルート (データリレーやNATのあるルート) よりも優先されます。ただし、これらのガイドライン内で、エージェントはアルゴリズムを調整する方法についてかなりの裁量を持っています。
データストリームは、複数のコンポーネント (components) (独自の候補セットを必要とするデータストリームの部分、例えばRTPとRTCP) で構成される場合があります。
2.3. Nominating Candidate Pairs and Concluding ICE (候補ペアの指名とICEの終了)
ICEは、ICEエージェントの1つを制御エージェント (controlling agent) の役割に割り当て、もう1つを被制御エージェント (controlled agent) の役割に割り当てます。データストリームの各コンポーネントについて、制御エージェントは、データに使用される有効なペア (有効リストから) を指名します。指名の正確なタイミングはローカルポリシーに基づいています。
指名時、制御エージェントは、データストリームの各コンポーネントに対して少なくとも1つの有効なペアが見つかるまでチェックを続行させ、その後、有効なペアを選択し、そのペアでSTUNリクエストを送信し、属性を使用して被制御ピアに指名されたことを示します。これを図4に示します。
L R
- -
STUN request -> \ Lの
<- STUN response / チェック
<- STUN request \ Rの
STUN response -> / チェック
STUN request + attribute -> \ Lの
<- STUN response / チェック
図4: 指名
被制御エージェントが属性付きのSTUNリクエストを受信すると、同じペアをチェックします (チェックがまだ行われていない場合)。上記のトランザクションが成功すると、エージェントはペアに指名フラグを設定し、そのデータストリームコンポーネントの今後のチェックをキャンセルします。エージェントがデータストリームの各コンポーネントに指名フラグを設定すると、ペアは選択されたペア (selected pairs) になります。その後、選択されたペアのみが、そのデータストリームに関連付けられたデータの送受信に使用されます。
2.4. ICE Restart (ICE再起動)
ICEが終了すると、いずれかのICEエージェントによって、1つまたはすべてのデータストリームに対していつでも再起動できます。これは、再起動を示す更新された候補情報を送信することによって行われます。
2.5. Lite Implementations (Lite実装)
特定のICEエージェントは常にパブリックインターネットに接続され、任意の通信者からパケットを受信できるパブリックIPアドレスを持ちます。これらのデバイスがICEをより簡単にサポートできるようにするために、ICEは「lite」と呼ばれる特別なタイプの実装を定義しています (通常の完全な実装とは対照的に)。Liteエージェントはホスト候補のみを使用し、接続性チェックを生成したり、ステートマシンを実行したりしませんが、接続性チェックに応答できる必要があります。