鈴木うどんの横須賀おもしろ生活

撮った写真や思ったことや技術ネタなど。出来るだけ大きなディスプレイで見ると良いと思う。ここでの発言は個人の見解であり、所属する組織の公式見解ではありません。

WebRTCにおけるNAT越えの課題へのアプローチ

インターネットのエンドユーザが用いるホストのほとんどが何らかのNATデバイスの配下に設置されている。この事実はWebに携わる技術者の間では広く知られているだろう。全世界に広がった広大なインターネットの世界に対応するために、新たなインターネットプロトコルであるIPv6が発案されて少なからず時間が経過した。それにもかかわらず、インターネットプロバイダやその配下のホストの全てが未だ対応している訳ではないのが現状だ。残念ながら、古いインターネットプロトコルであるIPv4がまだまだ一般的に用いられている。しかも、そのアドレスは既にとっくに枯渇し始めている。NATの技術はIPv4アドレスを節約するために用いられている。NATは単一のIPアドレス複数のホストで共有することを可能とする。

インターネット上でのピア間通信においてNAT越え(またはNATトラバーサルとも呼ばれる)の技術は重要な関心事項だ。NATは、サーバクライアント型のサービスを用いる場合でさしたる問題とならないが、ホスト間で相互に通信しようとするとほとんどの場合で問題となる。なぜならば、NATデバイスの外側から、その配下のホストに対して直接パケットを送信する手段は存在していないからだ。この問題に対して、NAT超えと呼ばれる技術のいずれかが用いられる。

WebRTCでは、STUNとICEを用いることによって、NAT越えのためにNATデバイスへのホールパンチ(穴あけ)を試みる。ホールパンチのテクニックはP2P通信が必要なインターネットゲーマーたちによって開拓され、現在ではIETFで標準化された技術となり、その仕様はRFCとして公開されている。この技術は、一部のNATデバイスの特性を用いている。サーバクライアント型のサービス利用時の動作を想定すると理解が早い。NAT配下のホストが外部のサーバへパケットを送信すると、NATデバイスはその応答を送信元に転送することを許容する。つまり、NATの外側から見た(すなわちサーバ側から見た)送信元IPアドレスとポートのペアを知ることが可能となれば、そこに穴を開けられる可能性があるということだ。このアドレスは、「鏡写し」の意味から、リフレクシブトランスポートアドレス(Reflexive Transport Address)と呼ばれる。

STUNクライアントは、STUNサーバからの応答によってリフレクシブトランスポートアドレスを知ることができる。ここで得られたアドレスとポートの組を用いて、ピア間で互いにパケットを送信しあってホールパンチを成功させようと試みる。RFC3489で規定された旧来のSTUNではリフレクシブトランスポートアドレスをMAPPED-ADDRESSとして平文でやりとりしていた。しかし、一部のアプリケーションレベルゲートウェイエンタープライズ向けのファイアウォールでは、通信の内容を解析してIPアドレスらしき情報を動的に書き換えてしまう場合がある。それに対処するために、WebRTCではRFC5389で規定された最新のSTUNの仕様に基いて、排他的論理和を施した情報をXOR-MAPPED-ADDRESSとしてやりとりしている。

ホールパンチに用いるための「ピア間で利用できる可能性のある」アドレスのペアを収集するためにはICEが用いられ、ここで得られた情報を候補(candidate)と呼ぶ。候補は多くの場合で複数存在し、ICEエージェントが「一番良い」ペアの選定のに役立てる。極端な例では、IPv4IPv6のアドレスの双方を持つクライアント同士が通信しあう場合、シグナリングは双方にIPv4を用いるが、メディアトランスポートにはIPv6を用いるということもあり得る。現状のWebRTCの実装はそこまで高機能ではないが、ICEはホールパンチを行う上で不可欠な技術だ。

WebRTCでは、STUNクライアントとICEエージェントはブラウザ内に含まれ、アプリケーションはJavaScriptピアコネクションAPI越しに制御することができる。新たなRTCPeerconnectionオブジェクトを生成して通信を確立しようとすると、ホールパンチが完了するまでの処理は自動的に進行する。ICEエージェントはSTUNによって得られた候補をシグナリングチャネル上で相手のピアと交換し、次々にホールパンチを試みる。

NAT越えには大きく2つの課題が存在しており、1つは全く接続不可であるケースを低減させることで、 もう1つはオファーを送信してからセッション開始までの時間のNAT超えによる追加を短縮することだ。 もし、企業の中から外のホストと通信しようとした場合エンタプライズ向けのFWやNATは堅牢なセキュリティのために、信頼されたとされる通信以外の全てを遮断するかもしれない。WebRTCではそのような場合に、中継サーバを用いたメディアリレーのアプローチを採る。そして、電話のようなアプリケーションで、ダイヤルしてからリングバックトーンが開始するまで数十秒もの間待たされるというのは、 いくらNAT配下にホストがあるとしても、それが「壊れている」とされても文句のつけようが無いだろう。これに対するアプローチの一つとして、WebRTCでは通信の多重化のアプローチを採っている。

WebRTCでは、クライアントがホールパンチに失敗してピア間で直接通信することが不可能な場合、メディアリレーを実現するTURNの技術を用いる。ホールパンチは全てのネットワークで成功する訳ではない。たとえば、Symmetric NATは全てのNAT越えを許容しない。また、STUNはその特性から最も外側のリフレクシブトランスポートアドレスしか知り得ないので、多段NATにも対応できない。それらのような場合、インターネット上のTURNサーバがピア感のパケットを中継することによってピア間の通信を実現する。TURNはSTUNを拡張した技術であり、ICEエージェントはメディアリレーアドレスとしてTURNサーバを候補に追加する。TURNは通信確立の最後の砦と成り得るが、未だ全てのネットワークでのリレーに対応している訳ではない。現在も新たな拡張に向けた議論が進行している。それは、主にTURN Revised and Modernized (tram)WGで進んでおり、そこでのインターネットドラフトは最新動向の観測に役立つだろう。

WebRTCでは、NAT越えを用いた場合のセッション開始までの時間短縮へのアプローチのひとつとしてRFC5761に規定されるRTP多重を用いている。なぜ多重化がこのケースで有効に働くのであろうか。まずは、RTP多重を用いないシーケンスについて考えてみよう。通常では、通信の多重化はトランスポート層が担うこととなっている。RTPのトランスポートにUDPを用いる場合、ストリームごとに異なるポートを用いることによって通信を多重化する。双方向の通話を行う場合では、相互のRTPセッションとそれぞれに対応するRTCPセッションの合計4つものUDPポートが必要となる。ここでホールパンチを試みる場合、4つのポート全てに対して処理しなければならない。セッション確立のためには、全てのホールパンチ完了を待つ必要がある。一方でWebRTCは迅速にセッションを開始するために、ただ「1つ」のポートだけを用いる。その結果、ホールパンチたった1度だけで済み、複数のストリームを扱うことが可能だ。このようなWebRTCでのRTPの利用方はdraft-ietf-rtcweb-rtp-usageで議論されており、そこでは他にセッション情報の交換や送受信双方での品質制御や輻輳通知のためのRTCP利用方法も規定しようとしている。

WebRTCはメディア以外にデータの通信のためのデータチャネルをもサポートしており、そのプロトコルにSCTPを用いることとし、多重化もSCTPの機能を用いることとしている。SCTPの多重化機能はSCTPアソシエーションと呼ばれており、複数のストリームを同時に扱うことができる。ここに至った経緯は少々複雑で、データ通信に「より良いプロトコル」を用いようとした背景がある。この議論はdraft-ietf-rtcweb-data-channelで進行中である。SCTPはSS7のために規定されたトランスポート層プロトコルであり、信頼性(reliability)の柔軟な設定や、パケットの順序性の保証の可否の設定、そしてメッセージ送信機能などの便利な機能を提供する。機能性の観点からSCTPは、現在主流なトランスポート層であるTCPUDPの双方を置き換えることが可能であるが、世に普及しているNATデバイスのほとんどは、TCPUDP以外のパケットを破棄してしまうため、通信キャリア内部以外でほとんど使われることがなかった。ところが、WebRTCではDTLS-SRTP上にSCTPを通すことで、すなわちトランスポートにUDPを用いるSCTPを実装することによって、既存のインターネットの世界でSCTPを用いることを可能としてしまった。RTPは通常であればトランスポート層の直上にあるはずであるから、SCTPは逆向きに積み上げられた形となる。RTP多重にせよDTLS-SRTP上のSCTPにせよ、実サービスでは必ずしもOSI参照モデルのように綺麗に階層構造を区切ることができないのかもしれない。これらの議論はdraft-ietf-rtcweb-data-protocolで行われており、他にSCTPアソシエーション上でデータチャネルの開始のためのシグナリングプロトコルであるDCEPや、WebRTC用の新たなPPID(Payload Protocol Identifier)(SCTPのメッセージのプロトコルの識別に用いられるID)の割付けの規定が進んでいる。

その他、セッション開始までの時間の短縮化のための取組みとして有名なものにTrickle ICEが存在している。通常のICEエージェントは全ての候補が揃うまでホールパンチを試みないが、Trickle ICEでは候補を収集しながら次々にホールパンチを試みる。滴(Trickle)がしたたることに掛けて名付けられている。ただし現状ではdraft-ietf-mmusic-trickle-ice-01は2014年8月11日に期限切れ(Expire)となってしまい、議論は停止している。

以上、インターネット上のピア間の通信でのNAT越えの課題と、WebRTCにおけるそのアプローチを解説した。NAT越えの課題に対する新たな取組みは現在進行形であり、様々な拡張が議論されている。ブラウザの実装も流動的でありメディアフローの挙動は流動的だ。WebRTCを用いるWeb開発者は、JavaScriptAPIを通常用いるので、このような通信の内容や設定の詳細に触れる必要はないかもしれない。しかし、トラブルシュートにおいて知識を持ちあわせておくことは役に立つだろう。また、Webが未来永劫テレフォニーの世界と無縁であるとも限らず、そのような時代が到来したならば、既存VoIP機器とWebRTCデバイスの差異に対する知識が、まず何をすべきかの判断に役立つと信じている。このWebRTCについての追加の知識が、誰かの何らかの参考になれば幸いだ。