Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
WebRTC スタックコトハジメ

WebRTC スタックコトハジメ

WebRTC スタックについて

作:@voluntas
バージョン:0.0.3
url:https://voluntas.github.io/

2015 年 3 月 11 日に行われる WebRTC Meetup Tokyo #7 : ATND 向けの発表資料です。

注意

High Performance Browser Networking

ここを読めば一通り学べます。

O'Reilly Japan - ハイパフォーマンス ブラウザネットワーキング

日本語もあるので是非、まずはこちらを読みましょう。とても良い本です。むしろ読め。

概要

WebRTC はブラウザに実装されている技術ですが、それだけでは色々やりたいことができません。

ブラウザ以外で WebRTC の技術がどう使われて、どう使っていけるのかという話をしていきます。

データチャネルのスタックはあまり個人的に興味が持てないので、メディアチャネルだけに焦点を当てます。

ただ、自分も全部は理解出来ていないのでまずは WebRTC における DTLS と SRTP についてまとめてみることにしました。

覚えておくと良いプロトコル一覧

内部なので本来は気にすることの無いプロトコル達

  • SDP
  • STUN
  • TURN
  • ICE
  • DTLS
  • SRTP
  • RTP
  • RTCP
  • SCTP

オススメ参考資料

WebRTC スタック

WebRTC で使われるプロトコルはかなりの量があります。今回ははしょりつつもざっくり見ていきます。

二つのチャネル

WebRTC ではメディアチャネルとデータチャネルの二種類の通信方式があります。

メディアチャネルは音声や動画を、データチャネルはバイナリを送受信する仕組みです。

それぞれの通信は UDP で行われるという点以外はまったく別物です。

P2P 確立

WebRTC ではシグナリング、と呼ばれている部分です。クライアント同士、またはシグナリングサーバを介して通信のやりとりを行います。

やりとりされる内部情報は SDP というプロトコルが使われます。読みづらいと有名なプロトコルです。

P2P を確立するための仕組みです。

データチャネル

データチャネルは SCTP というプロトコルが前提になっています。SCTP は簡単に言えば TCP と UDP のいいとこ取りをしたプロトコルです。 ただまったく一般的ではありません。さらに通信経路的にはうまく動作してくれない可能性があります。

そのため UDP 上に無理矢理載せて使用するという方式をとっています。

データチャネルは単純にバイナリデータを送る仕組みです。

UDP で送られるので、リアルタイム系に向いているかも知れません。といってもチャットとかだったら WebSocket で十分です。

メディアチャネル

メディアチャネルは SRTP つまり暗号化された RTP を使用しています。RTP は昔から使われているプロトコルで、 SIP ではべったりです。

DTLS

WebRTC で逃げられないのがこれです。全てのデータを暗号化している聞き慣れないヤツ。 TLS なら聞いたことが

通信自体を暗号化する仕組みですが、ベースの通信方式が UDP のため WebRTC では DTLS が採用されています。

DTLS はデータグラム (UDP や SCTP など) 向けの暗号化方式です。TLS をベースにいくつかの拡張を行っています。 TLS は主に TCP 前提の実装でした、そのため分割のための仕組みが入っています。

DTLS には 1.0 と 1.2 があります。1.0 は TLS 1.0 互換で、 1.2 は TLS 1.2 互換です。 pcap でパケットを見る限り DTLS 1.0 が使用されています。

データチャネルの暗号化

データチャネルでは UDP の上に DTLS を載せて、その ApplicationData の上に SCTP を実現しています

メディアチャンネルの暗号化

メディアチャネルでは UDP の上に DTLS を載せて、そこの ClientHello 拡張で use_srtp を仕様し、 ApplicationData の代わりに SRTP を使用しています

メディアチャネルで DTLS が一部だけに適用されている図を見たことがある人がいるかもしれません。 DTLS はあくまで鍵交換のために使っており、DTLS が用意したトンネル自体は使われていません。

DTLS が用意するトンネル用の暗号方式と SRTP で暗号方式が違います。 DTLS の暗号方式は CipherSuite で確定しますが、SRTP の暗号方式は AES 128 CM と決められています。暗号鍵の生成は MasterSecret から生成します。

WebRTC スタックの必要性

WebRTC は P2P をブラウザで使える用にした技術です。ただ転用はできます。

ブラウザという概念から、クライアントとサーバという概念にも置き換えることが可能です。

クライアント

ここに出したのはクライアント側でブラウザ以外に実装している例です。つまり WebRTC ブラウザ外でのプロトコルとして活用している例です。

まだ、監視カメラが多いですが、今後は何かしらこの WebRTC (メディアチャネル) を使った仕組みは増えていくと考えています。

ブラウザから気軽に自分の家のカメラを確認することができます。特に何も変換はいりません。うまくいけば P2P で見ることが可能かも知れません。グローバル IP を持つ必要はありません。

この組込用途としての WebRTC は良いです。いままで動画/音声の通信規格はたくさん出てきましたが。ただ、ここでブラウザという一般的なツールとの連携ができるプロトコルとしてでてきた WebRTC は今後も動画/音声を届ける仕組みとして活躍していくでしょう。

サーバ

サーバサイドの WebRTC はイメージしにくいかも知れませんが、基本的にはクライアント同士を接続する際に効率化を行ってくれる仕組みと考えて良いです。

P2P とどう違うのかというと、全ての処理をサーバ経由するという点で違います。また TURN とどう違うかというと、TURN は暗号化された通信をそのままリレーするだけですが、 WebRTC スタックをサーバサイドで持つと、暗号を解いてから別の相手に暗号を送る事ができるようになります。

Multipoint Control Unit (MCU)

全ての接続を 1 本に統合してくれる素敵な仕組みです。これを実現するには WebRTC スタックが必須です。

例えば 3 人と話をする場合 P2P の場合は外の二人に対してそれぞれ接続を行います。フルメッシュというやつですね。

ただ、MCU を使うと全てのユーザはこの MCU に繋ぐだけで良くなります。MCU 側が音声や動画の合成を行い 1 本に統一してくれます。

ただし、全ての暗号化を解き、動画や音声を合成し再配布する以上かなり CPU に優しくありません。ただし転送量にとても優しいです。

MCU はかなり限られた条件でないかぎり嬉しい場面がなさそうというのが個人的印象です。

Selective Forwarding Unit (SFU)

上りを 1 本に抑え、下りを複数本にする仕組みです。これを実現するにも WebRTC スタックが必須です。

Tokbox の Mantis がこれを実現しています。

簡単に説明すると、P2P の場合は全てのユーザに同一データを配布する必要があります。つまりクライアントの上り帯域を圧迫します。 SFU では下りだけを複数にし、上りを一本に絞ります。

SFU に対してクライアントは自分以外の会議参加者分だけ WebRTC のコネクションをはります。これは下り専用で、相手からのデータを受け取るためです。

また、クライアントは自分のデータを送るために WebRTC のコネクションを SFU に対してはります。これは自分の情報だけを送る上り専用の回線です。

SFU はクライアントから送られてきたデータを暗号化をひもとき、それぞれのクライアントに転送します。

つまり動作としては PubSub のような動作を実現する仕組みです。クライアント側が必要な分だけ接続をはり、サーバはそれに合わせてデータを配布するという仕組みです。

サーバ側はクライアントからの接続とユーザを紐付ける必要があります。

下りと上りの速度が 1/10 程度違うことや、サーバが合成を行わなくていいことを考えると SFU は会議システムに対してはかなり効果的な仕組みのように感じます。

MCU と SFU

WebRTC スタック以外の点で、実装の懸念点。

MCU

音声合成の時点でかなりだるいです、基本選択してはいけないと思っています。ビジネス的に必要になる可能性があるのであれば、がんばるしか無いです。

ただ接続数自体は抑えられます。ただ合成に伴う遅延が一番気になります。音声と動画の合成はかなりのコストでしょう。ここらへんをハードで解決する必要があるため、正直昔から会議システムを開発してきていないかぎりこの選択肢はないと考えています。

SFU

1 クライアントに対する接続管理がその会議に参加しているユーザ数 + 1 になります。そのため 10 ユーザであれば 10 x 10 の接続本数をサーバが支える必要があります。

さすがに 1 サーバ 100 という訳にいかないでしょうから、かなり接続されても大丈夫な仕組みが求められそうです。

ただ、合成がいらないことから大量接続数と WebRTC スタック、接続管理を実装すればいけます。ただ接続数管理を考えるとクライアントとの協調動作が必要になります。クライアントライブラリの開発が必須になるでしょう。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment