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

17. Example (例)

この例は、図 8 の簡略化されたトポロジに基づいています。

                          +-----+
| |
|STUN |
| Srvr|
+-----+
|
+---------------------+
| |
| Internet |
| |
| |
+---------------------+
| |
| |
+---------+ |
| NAT | |
+---------+ |
| |
| |
| |
+-----+ +-----+
| | | |
| L | | R |
| | | |
+-----+ +-----+

Figure 8: Example Topology

2 つのエージェント L と R が ICE を使用しています。どちらもフルモードの ICE 実装であり、制御しているときに積極的な指名(aggressive nomination)を使用します。両方のエージェントには、単一の IPv4 アドレスがあります。エージェント L の場合、それはプライベートアドレス空間 [RFC1918] の 10.0.1.1 であり、エージェント R の場合、パブリックインターネット上の 192.0.2.1 です。どちらも同じ STUN サーバー(実際には、エージェントが同じ STUN サーバーを使用する必要はありませんが、この例では簡単にするために示されています)で構成されており、IP アドレス 192.0.2.2 およびポート 3478 で STUN Binding 要求をリッスンしています。この例では TURN サーバーは使用されません。エージェント L は NAT の背後にあり、エージェント R はパブリックインターネット上にあります。NAT には、エンドポイントに依存しないマッピングプロパティと、アドレスに依存するフィルタリングプロパティがあります。NAT のパブリック側の IP アドレスは 192.0.2.3 です。

理解を容易にするために、トランスポートアドレスは、ニーモニック名を持つ変数を使用してリストされています。名前の形式は entity-type-seqno です。ここで、entity はトランスポートアドレスがあるエンティティの IP アドレスを指し、「L」、「R」、「STUN」、または「NAT」のいずれかです。Type は、パブリックなトランスポートアドレスの場合は「PUB」、プライベートなトランスポートアドレスの場合は「PRIV」です。最後に、seq-no は、特定のエンティティ上の同じタイプの各トランスポートアドレスに対して異なるシーケンス番号です。各変数には、それぞれ varname.IP と varname.PORT で示される IP アドレスとポートがあります。ここで、varname は変数の名前です。

STUN サーバーは、トランスポートアドレス STUN-PUB-1(192.0.2.2:3478)を通知しました。

コールフロー自体では、STUN メッセージにいくつかの属性で注釈が付けられています。「S=」属性は、メッセージの送信元トランスポートアドレスを示します。「D=」属性は、メッセージの宛先トランスポートアドレスを示します。「MA=」属性は、STUN Binding 応答メッセージで使用され、マップされたアドレスを指します。「USE-CAND」は、USE-CANDIDATE 属性の存在を意味します。

コールフローの例では、STUN 認証操作と RTCP が省略されており、2 つの完全な実装間の単一のメディアストリームの RTP に焦点が当てられています。

          L             NAT           STUN             R
|RTP STUN alloc. | |
|(1) STUN Req | | |
|S=$L-PRIV-1 | | |
|D=$STUN-PUB-1 | | |
|------------->| | |
| |(2) STUN Req | |
| |S=$NAT-PUB-1 | |
| |D=$STUN-PUB-1 | |
| |------------->| |
| |(3) STUN Res | |
| |S=$STUN-PUB-1 | |
| |D=$NAT-PUB-1 | |
| |MA=$NAT-PUB-1 | |
| |<-------------| |
|(4) STUN Res | | |
|S=$STUN-PUB-1 | | |
|D=$L-PRIV-1 | | |
|MA=$NAT-PUB-1 | | |
|<-------------| | |
|(5) Offer | | |
|------------------------------------------->|
| | | |RTP STUN
alloc.
| | |(6) STUN Req |
| | |S=$R-PUB-1 |
| | |D=$STUN-PUB-1 |
| | |<-------------|
| | |(7) STUN Res |
| | |S=$STUN-PUB-1 |
| | |D=$R-PUB-1 |
| |MA=$R-PUB-1 | |
| | |------------->|
|(8) answer | | |
|<-------------------------------------------|
| |(9) Bind Req | |Begin
| |S=$R-PUB-1 | |Connectivity
| |D=L-PRIV-1 | |Checks
| |<----------------------------|
| |Dropped | |
|(10) Bind Req | | |
|S=$L-PRIV-1 | | |
|D=$R-PUB-1 | | |
|USE-CAND | | |
|------------->| | |
| |(11) Bind Req | |
| |S=$NAT-PUB-1 | |
| |D=$R-PUB-1 | |
| |USE-CAND | |
| |---------------------------->|
| |(12) Bind Res | |
| |S=$R-PUB-1 | |
| |D=$NAT-PUB-1 | |
| |MA=$NAT-PUB-1 | |
| |<----------------------------|
|(13) Bind Res | | |
|S=$R-PUB-1 | | |
|D=$L-PRIV-1 | | |
|MA=$NAT-PUB-1 | | |
|<-------------| | |
|RTP flows | | |
| |(14) Bind Req | |
| |S=$R-PUB-1 | |
| |D=$NAT-PUB-1 | |
| |<----------------------------|
|(15) Bind Req | | |
|S=$R-PUB-1 | | |
|D=$L-PRIV-1 | | |
|<-------------| | |
|(16) Bind Res | | |
|S=$L-PRIV-1 | | |
|D=$R-PUB-1 | | |
|MA=$R-PUB-1 | | |
|------------->| | |
| |(17) Bind Res | |
| |S=$NAT-PUB-1 | |
| |D=$R-PUB-1 | |
| |MA=$R-PUB-1 | |
| |---------------------------->|
| | | |RTP flows

Figure 9: Example Flow

まず、エージェント L はローカル IP アドレス(図示せず)から host 候補を取得し、そこから STUN サーバーに STUN Binding 要求を送信して server reflexive 候補を取得します(メッセージ 1〜4)。NAT にはアドレスとポートに依存しないマッピングプロパティがあることを思い出してください。ここで、この UDP 要求に対して NAT-PUB-1 のバインディングを作成し、これが RTP の server reflexive 候補になります。

エージェント L は、host 候補にタイプ優先度 126 を設定し、server reflexive に 100 を設定します。ローカル優先度は 65535 です。これに基づくと、host 候補の優先度は 2130706431 であり、server reflexive 候補の優先度は 1694498815 です。host 候補には foundation 1 が割り当てられ、server reflexive には foundation 2 が割り当てられます。server reflexive 候補をデフォルト候補として選択し、m 行と c 行にエンコードします。結果のオファー(メッセージ 5)は次のようになります(明確にするために行が折り返されています)。

    v=0
o=jdoe 2890844526 2890842807 IN IP4 $L-PRIV-1.IP
s=
c=IN IP4 $NAT-PUB-1.IP
t=0 0
a=ice-pwd:asd88fgpdd777uzjYhagZg
a=ice-ufrag:8hhY
m=audio $NAT-PUB-1.PORT RTP/AVP 0
b=RS:0
b=RR:0
a=rtpmap:0 PCMU/8000
a=candidate:1 1 UDP 2130706431 $L-PRIV-1.IP $L-PRIV-1.PORT typ
host
a=candidate:2 1 UDP 1694498815 $NAT-PUB-1.IP $NAT-PUB-1.PORT typ
srflx raddr $L-PRIV-1.IP rport $L-PRIV-1.PORT

変数を値に置き換えたオファーは、次のようになります(明確にするために行が折り返されています)。

    v=0
o=jdoe 2890844526 2890842807 IN IP4 10.0.1.1
s=
c=IN IP4 192.0.2.3
t=0 0
a=ice-pwd:asd88fgpdd777uzjYhagZg
a=ice-ufrag:8hhY
m=audio 45664 RTP/AVP 0
b=RS:0
b=RR:0
a=rtpmap:0 PCMU/8000
a=candidate:1 1 UDP 2130706431 10.0.1.1 8998 typ host
a=candidate:2 1 UDP 1694498815 192.0.2.3 45664 typ srflx raddr
10.0.1.1 rport 8998

このオファーはエージェント R で受信されます。エージェント R は host 候補を取得し、そこから server reflexive 候補を取得します(メッセージ 6〜7)。R は NAT の背後にないため、この候補は host 候補と同一であり、同じベースを共有しています。したがって、この冗長な候補を破棄し、単一の host 候補になります。L と同じタイプおよびローカル優先度を持つため、この候補の優先度は 2130706431 です。単一の候補に対して foundation 1 を選択します。結果のアンサーは次のようになります。

    v=0
o=bob 2808844564 2808844564 IN IP4 $R-PUB-1.IP
s=
c=IN IP4 $R-PUB-1.IP
t=0 0
a=ice-pwd:YH75Fviy6338Vbrhrlp8Yh
a=ice-ufrag:9uB6
m=audio $R-PUB-1.PORT RTP/AVP 0
b=RS:0
b=RR:0
a=rtpmap:0 PCMU/8000
a=candidate:1 1 UDP 2130706431 $R-PUB-1.IP $R-PUB-1.PORT typ host

変数が入力された状態:

    v=0
o=bob 2808844564 2808844564 IN IP4 192.0.2.1
s=
c=IN IP4 192.0.2.1
t=0 0
a=ice-pwd:YH75Fviy6338Vbrhrlp8Yh
a=ice-ufrag:9uB6
m=audio 3478 RTP/AVP 0
b=RS:0
b=RR:0
a=rtpmap:0 PCMU/8000
a=candidate:1 1 UDP 2130706431 192.0.2.1 3478 typ host

どちらの側も lite であることを示していないため、ICE 処理を開始したオファーを送信したエージェント(エージェント L)が制御エージェントになります。

エージェント L と R は両方とも候補をペアにします。最初は両方とも 2 つのペアを持っています。ただし、エージェント L は server reflexive 候補を含むペアをプルーニングし、その結果 1 つだけになります。エージェント L では、このペアのローカル候補は $L_PRIV_1、リモート候補は $R_PUB_1 であり、候補ペアの優先順位は 4.57566E+18 です(実装では、精度を失わないようにこれを 64 ビット整数として表すことに注意してください)。エージェント R には 2 つのペアがあります。最も優先順位が高いペアのローカル候補は $R_PUB_1、リモート候補は $L_PRIV_1 で、優先順位は 4.57566E+18 です。2 番目のペアのローカル候補は $R_PUB_1、リモート候補は $NAT_PUB_1 で、優先順位は 3.63891E+18 です。

エージェント R は、最初のペア(2 つの host 候補間)の接続性チェックを開始します(メッセージ 9)。R はこのセッションの被制御エージェントであるため、チェックでは USE-CANDIDATE 属性が省略されます。エージェント L の host 候補はプライベートで NAT の背後にあるため、パケットを R から L にルーティングできないため、このチェックは成功しません。

エージェント L がアンサーを取得すると、唯一の接続性チェックを実行します(メッセージ 10〜13)。積極的な指名アルゴリズムを実装しているため、このチェックに USE-CANDIDATE 属性が含まれます。チェックが成功すると、エージェント L は新しいペアを作成します。そのローカル候補は Binding 応答内のマップされたアドレス(メッセージ 13 の NAT-PUB-1)からのものであり、そのリモート候補は要求の宛先(メッセージ 10 の R-PUB-1)です。これは Valid リストに追加されます。さらに、Binding 要求に USE-CANDIDATE 属性が含まれていたため、選択済み(selected)としてマークされます。このメディアストリームの 1 つのコンポーネントの Valid リストに選択された候補があるため、このストリームの ICE 処理は Completed 状態に移行します。エージェント L は、必要に応じてメディアを送信できるようになりました。

エージェント L からの STUN Binding 要求を受信した直後(メッセージ 11)、エージェント R はトリガーされたチェックを生成します。このチェックは、たまたまチェックリストの次のチェック(host 候補からエージェント L の server reflexive 候補へ)と一致します。このチェック(メッセージ 14〜17)は成功します。その結果、エージェント R は、応答からのマップされたアドレスをローカル候補(R-PUB-1)として、要求の宛先(NAT-PUB-1)をリモート候補として使用して、新しい候補ペアを構築します。このペアは、そのメディアストリームの Valid リストに追加されます。チェックは USE-CANDIDATE 属性を含むチェックの逆方向に生成されたため、候補ペアは選択済みとしてマークされます。その結果、このストリームの処理は Completed 状態に移行し、エージェント R もメディアを送信できます。