ぼちぼち日記

おそらくプロトコルネタを書いていることが多いんじゃないかと思います。

Googleの新プロトコルQUICを試す

1.QUIC仕様の公開

以前、「Googleが仕掛ける新プロトコルQUICとは何か」のブログエントリーを書いたのが2月末の事でした。それから4か月経ち、今朝Googleが初めてQUICの公表(Chromium Blog: Experimenting with QUIC)を行いました。 IE11のSPDY/3対応が判明した直後でした。なんというタイミングでしょうか。

また、近いうち(来週?)には HTTP/2.0 の Implementation Draft が公開される予定です。8月上旬には、GoogleMicrosoft等が集まって初めての HTTP/2.0 の相互接続試験を行う予定です。ただ今HTTP関連のプロトコルが急激に進化する真っ最中です。目が離せません。

2. で、QUICとは何なのか?

先のChromium BlogのエントリーでQUICは、
「Quick UDP Internet Connections」
の略語であると説明されています。

さらに、このブログの著者欄で "RTT Reduction Ranger" (ラウンドトリップ時間を削減するレンジャー部隊)とのタイトルがついているよう、とにかくインターネット接続上で短時間素早くデータを送受信することがQUICの大きな目標です。

公開されたQUIC仕様は量が多いため(暗号化、ワイヤ仕様等が別にある)、まだ十分読み込んでいませんが、ざっと見たところ4か月前の私のブログに書いた、

「QUICは UDPを改良するものではなく、既存のUDP上でTCP+TLS相当の機能を実現する新プロトコルスタックである。」

は間違っていなかったと思います。以前公開した以下の図の通りでした。

ただし、当時の解析漏れやその後の開発等により、細かいところで異なっていたり、説明が大きく不足している部分もあります(QUICフレームフォーマットも順番が変わっていたり、フラグの追加変更されているところが数多く存在します)。これはおいおい修正していく予定です。

また、先のGoogleによるQUICのアナウンスでは、QUIC の特徴として以下の7つの機能が挙げられています。

  1. TLSによく似た高セキュリティ
  2. TCP Fast Open と TLS Snapstart を組み合わせたような(だいたい 0-RTTの)素早い接続
  3. パケットロスを低減するパケット速度調整
  4. 再送頻度を低減するパケットのエラー補正
  5. TCP のHead-of-Lineブロッキング(先頭詰り)を回避するUDPトランスポート
  6. モバイルクライアントのために再接続を削減する接続ID
  7. 取り替え可能(pluggable)な輻輳制御メカニズム

これを4か月前の私のブログエントリーに記載している、

各機能の実現方法をまとめると、
・GUIDベースのストリームのFRAME形式を使いセッション確立 (STREAM_FRAME,RST_FRAME,CONNECTION_CLOSE_FRAME)
・ACK_FRAME, CONGESTION_FEEDBACK_FRAMEを使ってフロー制御や輻輳制御
・FECを使ってエラー訂正
・CRYPTO_FRAMEを使って暗号化・認証情報のハンドシェイク
となります。

の内容とかなりかぶっているのがわかります。

3. 早速QUICを試す

既に Google のサービスでフィールド試験が始まっているとのことですので、早速試してみます。
私の手元では、 Chrome Dev (29.0.1547.0 dev-m) と Chrome Canary(30.0.1549.0 canary) で動作が確認できました。
幾つかのGoogleサイト宛に試したところ本日午後では、 http://www.google.com/, http://www.youtube.com, http://maps.google.com 等が QUIC 対応していました。残念ながら GMail はまだみたいです。

3.1 準備

先ずは、いつもの通り about://flags で下図の通り QUIC の機能を有効にします。

次に、本来ですと QUIC対応サーバはHTTPでアクセスすると Alternate-Protocol ヘッダで QUIC接続への切り替えを行います。Googleはまだプライベートのフィールドテストをしていると思いますのでこの切り替えヘッダを一般向けに提供していません。そこで、特定のサーバ向けにQUICを指定するようにします。
このやり方を一般に公表して実サービスへのQUIC接続が増えるともしかするとGoogleさんにご迷惑をかける可能性があるので、ここで記述するのは止めておきます。Chromium のソースを読むとそのやり方がわかります。

最後にネットワーク環境の準備です。QUIC は UDP のポート80番に接続に行きます。FireWall等で 80番ポートへのUDP接続は止められている場合も多いかと思います。QUIC接続するには、UDP 80番への接続ができるネットワーク環境を用意します。

3.2 http://www.google.com/ へ QUIC接続

準備が整ったらブラウザを立ち上げ、http://www.google.com/ を閲覧します。 chrome://net-internals/#quic を見てみるとサーバへQUICで接続しているのがわかります。

それではQUICセッションの中身はなんでしょうか? 中身を見てみます。

QUICセッションのフレームをサーバとやり取りしているのがわかります。代表的な2つのストリームを取り出してみます。

t=1372402166319 [st= 1] QUIC_SESSION_PACKET_SENT
--> encryption_level = 0
--> packet_sequence_number = "1"
--> size = 564

最初の暗号・認証ハンドシェイクを行うストリームです。暗号化レベルが0なのでこのストリームでは暗号化を行わないようです。
次はブラウザーからのリクエストのストリーム

t=1372402166489 [st=171] QUIC_HTTP_STREAM_SEND_REQUEST_HEADERS
--> :host: www.google.com
:method: GET
:path: /
:scheme: http
:version: HTTP/1.1
accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
accept-encoding: gzip,deflate,sdch
accept-language: en-US,en;q=0.8,ja;q=0.6
cookie: [767 bytes were stripped]
user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/29.0.1547.0 Safari/537.36
x-chrome-variations: CLe1yQEIlLbJAQiqtskBCJSEygEIloTKAQi3hcoBCNaFygEIn4bKAQ==

SPDYと同じくヘッダ+値の組をサーバに送信しているのがわかります。(上位レイヤーはSPDYを利用している)

残念ながらすぐ https://www.google.co.jp/ にリダイレクションしてしまうため、現状継続してQUICを使い続けることは難しいようです。でも実際にサービス上で動作するサーバとQUICでつながることは感動ものです。

今回のアナウンスで、テスト用のQUICサーバがChromiumのソース中に用意されているのがわかりました。今後、仕様書と Chromium のコードを良く読み合わせてさらにQUICの解析を続けたいと思います。