WebTransport over QUIC について

2020/03/11 追記
関連記事を書きました


目次

blink-devメーリングリストで、「Intent to Implement: QuicTransport」として、ChromeでのWebTransport over QUICの実装の機運が高まっている。

というか、GoogleのQUIC, HTTP/3実装ライブラリであるQUICHEにはすでにQuicTransportに関するコードが既にコミットされ始めている(URL)

WebTransportは、トランスポートプロトコルとしてHTTP/3やQUICを利用する双方向のメッセージプロトコルです。APIに関してはW3C側で、プロトコルとしてはIETFで議論が始まっています。仕様は以下の通り

来月行われるIETF106では、WebTransport WGを結成するためのBoFが提案されている。そのなかでも「Chromium is currently implementing a client Google QUIC library will support both client and server」と、クライアント・サーバともに実装している旨が書かれている。

仕様としては使用できるトランスポーはいくつかあるが、まずはover QUICから取り掛かるようだ

WebTransport over QUIC

一部本記事と重複するが、WebTransportの概要については下記の記事を参照
asnokaze.hatenablog.com

Googleさんが、WebTransport over QUICをまず進めていくようなので、WebTransport over QUICについて簡単に書く。なお、draftは著者様のgithub上ではすでに加筆されており、次のdraft-01で入る予定の機能についても触れる。

WebTransport over QUICは、WebTransportの特性のうち下記をサポート

  • Stream independence: Always supported
  • Partial reliability: Always supported
  • Pooling support: Not supported
  • Connection mobility: Implementation-dependent

また、QuicTransportでの0-RTTサポートは、QUICおよびTLS 1.3と同様にオプションです。

Stream independence

QUICレイヤのストリーム(単方向・双方向)を利用して、ヘッドオブラインブロッキングのない通信(パケットロスが発生しても他のストリームをブロックしない)となる。TCPとは異なり、アプリケーションはOSレイヤでのロスしたパケットの回復を待つことはなく、パケットから処理が可能となる。

Partial reliability

また、DATAGRAMフレームを利用し、パケットロスしたデータを回復しないことも選択できる。
asnokaze.hatenablog.com

Pooling support

WebTransport over QUICでは一つのQUICコネクションを利用してしまうので、同じ相手と通信していてもQUICコネクションを一つに束ねることはできない。その観点では、輻輳制御コントローラを共有するWebTransport over HTTP/3の方がメリットがあります。

Connection mobility

QUICはコネクションマイグレーションという機能がありますが、実装依存です。

asnokaze.hatenablog.com

URI Scheme

WebTransport over QUICでは、quic-transport用のURIが新しく定義されています。

通常のURL同様以下のような構造を持ちます。

quic-transport://host:port/path

クライアントは上記のURLに対して接続を開始します。host名はSNIとして送信され、pathは後述のClient Indicationを用いてサーバに伝えられます。

接続の開始

WebTransport over QUICでは、draft-00ではALPNとして"wq"を使っていましたが、draft-01からは、individual draft版を示す "wq-vvv-01"を使用します。クロスプロトコル攻撃もなくなります。

サーバからのTLS Finishedのメッセージが受信されると、WebTransport over QUICのコネクションが確立されます。

Client Indication

draft-01からClient Indicationという仕組みが導入される予定です。

これは、下記Issueでも述べられている通りに、どのWebページ(オリジン)によって開始されたWebTransport over QUICなのか識別できるようにするためのものです。
github.com

https://example.comからwq.example.com:4433に対して接続を開始した場合、接続を開始したオリジンとしてhttps://example.com:443がWebTransport over QUICサーバに通知されます。こすることで第三者のWebページにWebTransport over QUICサーバを勝手に利用されるということはなくなります。

Client Indication自体は、クライアントからサーバに対してメタ的な情報を通知する汎用的な仕組みです。クライアントは、コネクションが確立した直後に、ストリームID:2 (単方向ストリーム)で接続を開始したオリジンを通知するClient Indicationメッセージを投げます。サーバはこのメッセージが来るまで待ち状態となります(正確にはストリームID:2がクローズするまで待ち状態)。

Client Indicationメッセージは下記のフォーマットになります。可変長Valueを持つ、Key-Value型のメッセージ形式です。
f:id:ASnoKaze:20191010013538p:plain

このうち、Keyとして0x0000を持つのがOrigin通知用のClient Indicationで、valueとしてオリジンが入ります。Keyが0x0001のものはPathを送信するのに使用されます。

対応していないKey番号を持つClient Indicationは無視されます。

データのやり取り

コネクションが確立され、Client Indicationが完了したあと、各ストリーム上でクライアントとサーバでやりとりが開始されます。

Fallback

余談ですが、WebTransport over QUICのプロトコル自体にはコネクションの確立に失敗しても、WebTransport over TCPへのフォールバックの機能はありません。WebTransportのフレームワークが、WebSocketベースのポリフィルが提供されるらしいので、アプリケーションがそちらに切り替えを行う形になるのかとおもいます。