メインコンテンツまでスキップ

16. 詳細な例 (Detailed Example)

このセクションでは、TURN の使用例を提供し、交換されるメッセージの内容を詳細に示します。この例では、概要(図 1)に示されているネットワーク図を使用します。

各メッセージについて、メッセージに含まれる属性とその値が表示されます。便宜上、実際のオクテットを表示するのではなく、値は人間が読める形式で表示されます。例えば、「XOR-RELAYED-ADDRESS=192.0.2.15:9000」は、XOR-RELAYED-ADDRESS 属性が存在し、アドレスが 192.0.2.15、ポートが 9000 であることを示します。ここで、アドレスとポートは XOR 演算が適用される前に表示されています。文字列のような値を持つ属性(例:SOFTWARE="Example client, version 1.03" および NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm")の場合、属性の値は読みやすさのために引用符で表示されていますが、これらの引用符は実際の値には現れません。

 TURN                                 TURN           Peer          Peer
client server A B
| | | |
|--- Allocate request -------------->| | |
| Transaction-Id=0xA56250D3F17ABE679422DE85 | |
| SOFTWARE="Example client, version 1.03" | |
| LIFETIME=3600 (1 hour) | | |
| REQUESTED-TRANSPORT=17 (UDP) | | |
| DONT-FRAGMENT | | |
| | | |
|<-- Allocate error response --------| | |
| Transaction-Id=0xA56250D3F17ABE679422DE85 | |
| SOFTWARE="Example server, version 1.17" | |
| ERROR-CODE=401 (Unauthorized) | | |
| REALM="example.com" | | |
| NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | |
| | | |
|--- Allocate request -------------->| | |
| Transaction-Id=0xC271E932AD7446A32C234492 | |
| SOFTWARE="Example client 1.03" | | |
| LIFETIME=3600 (1 hour) | | |
| REQUESTED-TRANSPORT=17 (UDP) | | |
| DONT-FRAGMENT | | |
| USERNAME="George" | | |
| REALM="example.com" | | |
| NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | |
| MESSAGE-INTEGRITY=... | | |
| | | |
|<-- Allocate success response ------| | |
| Transaction-Id=0xC271E932AD7446A32C234492 | |
| SOFTWARE="Example server, version 1.17" | |
| LIFETIME=1200 (20 minutes) | | |
| XOR-RELAYED-ADDRESS=192.0.2.15:50000 | |
| XOR-MAPPED-ADDRESS=192.0.2.1:7000 | |
| MESSAGE-INTEGRITY=... | | |

クライアントは最初に、TURN セッションに使用するホストトランスポートアドレスを選択します。この例では、クライアントは図 1 に示されているように 10.1.1.2:49721 を選択しました。次に、クライアントはサーバートランスポートアドレスでサーバーに Allocate リクエストを送信します。クライアントは、このトランザクション用に 96 ビットのトランザクション ID 0xA56250D3F17ABE679422DE85 をランダムに選択し、これが固定ヘッダーのトランザクション ID フィールドにエンコードされます。クライアントは、クライアントソフトウェアに関する情報を提供する SOFTWARE 属性を含めます。ここでの値は「Example client, version 1.03」で、これは Example クライアントと呼ばれるものの バージョン 1.03 であることを示しています。クライアントは、デフォルトの 10 分よりも長い有効期間をアロケーションに持たせたいため、LIFETIME 属性を含めます。この属性の値は 3600 秒で、1 時間に相当します。クライアントは、Allocate リクエストに常に REQUESTED-TRANSPORT 属性を含める必要があります。この仕様で許可されている唯一の値は 17 で、これはサーバーとピア間の UDP トランスポートを示します。クライアントはまた、後で Send インディケーションで DONT-FRAGMENT 属性を使用したいため、DONT-FRAGMENT 属性を含めます。この属性は属性ヘッダーのみで構成され、値部分はありません。最後に、クライアントが最近サーバーと対話していないと仮定し、したがって USERNAME、REALM、NONCE、または MESSAGE-INTEGRITY 属性を含めません。メッセージ内の属性の順序は任意である(MESSAGE-INTEGRITY および FINGERPRINT 属性を除く)ことに注意してください。クライアントは異なる順序を使用することもできました。

サーバーは、すべてのリクエストを認証する必要があります。したがって、サーバーが最初の Allocate リクエストを受信すると、リクエストに認証属性が含まれていないため、リクエストを拒否します。STUN [RFC5389] 長期認証情報メカニズムの手順に従って、サーバーは値が 401(Unauthorized、未承認)の ERROR-CODE 属性、サーバーが使用する認証レルムを指定する REALM 属性(ここでは、サーバーのドメイン「example.com」)、および NONCE 属性のノンス値を含めます。サーバーはまた、サーバーのソフトウェアに関する情報を提供する SOFTWARE 属性を含めます。

401 エラーを受信すると、クライアントは Allocate リクエストを再試行し、今回は認証属性を含めます。クライアントは新しいトランザクション ID を選択し、以前と同じ属性で新しい Allocate リクエストを埋めます。クライアントは USERNAME 属性を含めます。サーバーから受信したレルム値を使用して、使用する値を決定するのに役立ちます。ここで、クライアントはレルム「example.com」にユーザー名「George」を使用するように構成されています。クライアントは、401 エラーレスポンスからコピーした REALM および NONCE 属性を含めます。最後に、クライアントはメッセージの最後の属性として MESSAGE-INTEGRITY 属性を含めます。この属性の値は、メッセージ内容に対する HMAC-SHA1 ハッシュです(上記では単に「...」として表示)。この HMAC-SHA1 計算にはパスワード値が含まれます。したがって、攻撃者は秘密のパスワードを知らなければ、メッセージ完全性値を計算できません。

認証された Allocate リクエストを受信すると、サーバーはすべてが正常であることを確認し、アロケーションを作成します。サーバーは Allocate 成功レスポンスで応答します。サーバーは、アロケーションの有効期間を示す LIFETIME 属性を含めます。ここで、サーバーはクライアントが要求した 1 時間の有効期間を 20 分のみに短縮しました。この特定のサーバーは 20 分を超える有効期間を許可しないためです。サーバーは、値がアロケーションのリレーされたトランスポートアドレスである XOR-RELAYED-ADDRESS 属性を含めます。サーバーは、値がクライアントのサーバー反射アドレスである XOR-MAPPED-ADDRESS 属性を含めます。この値は TURN の他の場所では使用されませんが、クライアントへの便宜として返されます。サーバーは、レスポンスを認証し、その完全性を保証するために MESSAGE-INTEGRITY 属性を含めます。レスポンスには USERNAME、REALM、および NONCE 属性が含まれていないことに注意してください。サーバーはまた、SOFTWARE 属性を含めます。

 TURN                                 TURN           Peer          Peer
client server A B
|--- CreatePermission request ------>| | |
| Transaction-Id=0xE5913A8F460956CA277D3319 | |
| XOR-PEER-ADDRESS=192.0.2.150:0 | | |
| USERNAME="George" | | |
| REALM="example.com" | | |
| NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | |
| MESSAGE-INTEGRITY=... | | |
| | | |
|<-- CreatePermission success resp.--| | |
| Transaction-Id=0xE5913A8F460956CA277D3319 | |
| MESSAGE-INTEGRITY=... | | |

次に、クライアントは、いくつかのアプリケーションデータを送信する準備として、ピア A の権限を作成します。これは CreatePermission リクエストを通じて行われます。XOR-PEER-ADDRESS 属性には、権限が確立される IP アドレス(ピア A の IP アドレス)が含まれます。CreatePermission リクエストで使用される場合、属性のポート番号は無視されることに注意してください。ここでは、ゼロに設定されています。また、クライアントがピア A の(プライベート)ホストアドレスではなく、サーバー反射 IP アドレスを使用する方法にも注意してください。クライアントは、アロケーション上の最後のリクエストからユーザー名、レルム、およびノンス値を再利用します。これは許可されていますが、クライアントはこのリクエストに SOFTWARE 属性を含めないことを選択しました。

サーバーは CreatePermission リクエストを受信し、対応する権限を作成し、CreatePermission 成功レスポンスで応答します。クライアントと同様に、サーバーは応答に SOFTWARE 属性を含めないことを選択しました。成功レスポンスに MESSAGE-INTEGRITY 属性が含まれている(サーバーが長期認証情報メカニズムを使用していると仮定)が、USERNAME、REALM、および NONCE 属性は含まれていないことに再度注意してください。

 TURN                                 TURN           Peer          Peer
client server A B
|--- Send indication --------------->| | |
| Transaction-Id=0x1278E9ACA2711637EF7D3328 | |
| XOR-PEER-ADDRESS=192.0.2.150:32102 | |
| DONT-FRAGMENT | | |
| DATA=... | | |
| |-- UDP dgm ->| |
| | data=... | |
| | | |
| |<- UDP dgm --| |
| | data=... | |
|<-- Data indication ----------------| | |
| Transaction-Id=0x8231AE8F9242DA9FF287FEFF | |
| XOR-PEER-ADDRESS=192.0.2.150:32102 | |
| DATA=... | | |

クライアントは現在、Send インディケーションを使用してピア A にいくつかのアプリケーションデータを送信します。ピア A のサーバー反射トランスポートアドレスは XOR-PEER-ADDRESS 属性で指定され、アプリケーションデータは DATA 属性で指定されます(上記では単に「...」として表示)。クライアントはアプリケーション層で何らかの形式のパス MTU 発見を行っているため、(DONT-FRAGMENT 属性を含めることによって)サーバーがピアに送信する UDP データグラムで DF ビットを設定するように指定します。STUN の長期認証情報メカニズムを使用してインディケーションを認証することはできないため、メッセージに MESSAGE-INTEGRITY 属性はありません。データが改ざんされたりスプーフィングされたりしていないことを確認したいアプリケーションは、アプリケーションレベルでデータの完全性を保護する必要があります。

Send インディケーションを受信すると、サーバーはアプリケーションデータを抽出し、UDP データグラムでピア A に送信します。リレーされたトランスポートアドレスをデータグラムのソースとして使用し、要求どおりに DF ビットを設定します。クライアントが以前にピア A のサーバー反射 IP アドレスの権限を確立していなかった場合、サーバーは Send インディケーションを静かに破棄していたことに注意してください。

次に、ピア A はアプリケーションデータを含む独自の UDP データグラムで応答します。データグラムは、サーバー上のリレーされたトランスポートアドレスに送信されます。これが到着すると、サーバーは Data インディケーションを作成し、XOR-PEER-ADDRESS 属性に UDP データグラムのソースを、DATA 属性に UDP データグラムのデータを含めます。次に、生成された Data インディケーションがクライアントに送信されます。

 TURN                                 TURN           Peer          Peer
client server A B
|--- ChannelBind request ----------->| | |
| Transaction-Id=0x6490D3BC175AFF3D84513212 | |
| CHANNEL-NUMBER=0x4000 | | |
| XOR-PEER-ADDRESS=192.0.2.210:49191 | |
| USERNAME="George" | | |
| REALM="example.com" | | |
| NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | |
| MESSAGE-INTEGRITY=... | | |
| | | |
|<-- ChannelBind success response ---| | |
| Transaction-Id=0x6490D3BC175AFF3D84513212 | |
| MESSAGE-INTEGRITY=... | | |

クライアントは現在、ピア B にチャネルをバインドし、CHANNEL-NUMBER 属性で未使用のチャネル番号(0x4000)を指定し、XOR-PEER-ADDRESS 属性でピア B のトランスポートアドレスを指定します。前と同様に、クライアントは最後のリクエストからユーザー名、レルム、およびノンスを再利用します。

リクエストを受信すると、サーバーはチャネル番号をピアにバインドし、ピア B の IP アドレスの権限をインストールし、ChannelBind 成功レスポンスで応答します。

 TURN                                 TURN           Peer          Peer
client server A B
|--- ChannelData ------------------->| | |
| Channel-number=0x4000 |--- UDP datagram --------->|
| Data=... | Data=... |
| | | |
| |<-- UDP datagram ----------|
| | Data=... | |
|<-- ChannelData --------------------| | |
| Channel-number=0x4000 | | |
| Data=... | | |

クライアントは現在、ピア B 宛のデータを含む ChannelData メッセージをサーバーに送信します。ChannelData メッセージは STUN メッセージではないため、トランザクション ID はありません。代わりに、チャネル番号、データ、およびデータ長の 3 つのフィールドのみがあります。ここで、チャネル番号フィールドは 0x4000(クライアントがピア B にバインドしたばかりのチャネル)です。サーバーが ChannelData メッセージを受信すると、チャネルが現在バインドされているかどうかを確認し(バインドされています)、リレーされたトランスポートアドレスをソーストランスポートアドレスとして使用し、192.0.2.210:49191(ChannelBind リクエストの XOR-PEER-ADDRESS 属性の値)を宛先トランスポートアドレスとして使用して、UDP データグラムでデータをピア B に転送します。

後で、ピア B はリレーされたトランスポートアドレスに UDP データグラムを送信します。これにより、サーバーは UDP データグラムからのデータを含む ChannelData メッセージをクライアントに送信します。サーバーは、UDP データグラムが送信されたリレーされたトランスポートアドレスのため、どのクライアントに ChannelData メッセージを送信するかを知っており、192.0.2.210:49191 にバインドされているチャネルであるため、チャネル 0x4000 を使用することを知っています。そのアドレスにバインドされたチャネル番号がない場合、サーバーは Data インディケーションを使用していたことに注意してください。

 TURN                                 TURN           Peer          Peer
client server A B
|--- Refresh request --------------->| | |
| Transaction-Id=0x0864B3C27ADE9354B4312414 | |
| SOFTWARE="Example client 1.03" | | |
| USERNAME="George" | | |
| REALM="example.com" | | |
| NONCE="adl7W7PeDU4hKE72jdaQvbAMcr6h39sm" | |
| MESSAGE-INTEGRITY=... | | |
| | | |
|<-- Refresh error response ---------| | |
| Transaction-Id=0x0864B3C27ADE9354B4312414 | |
| SOFTWARE="Example server, version 1.17" | |
| ERROR-CODE=438 (Stale Nonce) | | |
| REALM="example.com" | | |
| NONCE="npSw1Xw239bBwGYhjNWgz2yH47sxB2j" | |
| | | |
|--- Refresh request --------------->| | |
| Transaction-Id=0x427BD3E625A85FC731DC4191 | |
| SOFTWARE="Example client 1.03" | | |
| USERNAME="George" | | |
| REALM="example.com" | | |
| NONCE="npSw1Xw239bBwGYhjNWgz2yH47sxB2j" | |
| MESSAGE-INTEGRITY=... | | |
| | | |
|<-- Refresh success response -------| | |
| Transaction-Id=0x427BD3E625A85FC731DC4191 | |
| SOFTWARE="Example server, version 1.17" | |
| LIFETIME=600 (10 minutes) | | |

20 分の有効期間が切れる前のいつか、クライアントはアロケーションをリフレッシュします。これは Refresh リクエストを使用して行われます。前と同様に、クライアントはリクエストに最新のユーザー名、レルム、およびノンス値を含めます。クライアントはまた、Allocate および Refresh メッセージにこの属性を常に含めるという推奨に従って、SOFTWARE 属性を含めます。サーバーが Refresh リクエストを受信すると、ノンスが古くなっていることに気付き、438(Stale Nonce、古いノンス)エラーで応答し、新しいノンス値を提供します。次に、クライアントは、今回は新しいノンス値を使用してリクエストを再試行します。この 2 回目の試行は受け入れられ、サーバーは成功レスポンスで応答します。クライアントがリクエストに LIFETIME 属性を含めなかったため、サーバーはデフォルトの有効期間である 10 分間アロケーションをリフレッシュしたことに注意してください(成功レスポンスの LIFETIME 属性に示されています)。