追記(2019/12/24)
最新版ですと、h3-23ではなくh3-24が必要ですー
「The latest Chrome Canary supports h3-24 instead of h3-23」
https://groups.google.com/a/chromium.org/forum/#!topic/proto-quic/trZsbXM_2CM
Chrome CanaryがHTTP/3のドラフト版に対応していたので、簡単に見てみる
(登場するバージョンについての説明は、後述する。)
動作確認
デフォルトでは喋ってくれない。chrome canaryの起動オプションに下記を追加する。
--enable-quic --quic-version=h3-23
(起動コマンドがわからない場合は、chrome://version/ を開くと確認できる)
HTTP/3 draft-23に対応しているページを開きます。
https:///quic.aiortc.org:4433
ページは正しく表示され、デベロッパーツール上はhttp/2+quic/99と表示されますが、HTTP/3 draft-23で通信は行われています。
Wireshark で、QUICトランスポートのバージョンを見てみるとちゃんとIETF QUICのバージョンを示す 0xFF00000017 (draft-23) で通信していることを確認できます。
バージョンについては、順に説明していく。
gQUIC, iQUICのバージョン
もともと、"QUIC"はGoogleが考案・実装していたプロトコルですが、標準化するに当たりIETFに持ち込まれました。そして、IETFではQUICはトランスポートプロトコルとして設計され、その上にHTTP/3がのっかる形となりました。(Google QUICはHTTPレイヤも含むプロトコルでした)
この過程で、もともとのGoogle QUICとIETF QUICは別物となり、それぞれ互換性の無いプロトコルとなりました。Google版のQUICをgQUIC, IETF版のQUICをiQUICと呼び分けることもあります。
もちろん、HTTP/3ではiQUICを前提にしているため、HTTP/3に対応するためにはiQUICに対応する必要があります。
Chromeでは標準仕様であるiQUICへの移行を段階的に進めており、HTTP/3 draft-23 が実験的に喋れる状況となっています。
識別子とalt-svc
iQUIC
HTTP/3では、サーバがHTTP/3に対応している旨、alt-svcレスポンスヘッダを用いて通知します。
下記例では、HTTP/3の仕様 draft-23バージョンを 4433ポートで提供していることを示しています。このレスポンスヘッダを受け取ったクライアントは、自身がそのバージョンに対応していれば、そこに繋がきに行きます。
alt-svc: h3-23=":4433"; ma=3600
IETF版、QUICではHTTP/3の識別子として、 h3-
(ここでは、HTTP/3のバージョンにのみ言及しており、トランスポートとしてのQUICについては別途コネクション時にネゴシエーションされる点に注意。QUICトランスポートのハンドシェイクでは draft版は 0xff0000
gQUIC
gQUICでも同様にalt-svcを使用しますが、バージョン体系が異なっています
Googleのサーバは下記のようなalt-svcを返します。gQUICは、HTTPレイヤも含むプロトコルですので識別子としてquicを使用しています。vという値を用いて、対応バージョンとして、46,43,39に対応していることを示しています。
alt-svc: quic=":443"; ma=2592000; v="46,43,39"
識別子も、バージョン体系もiQUICとgQUICは異なっています。
先述の通り、gQUICはiQUICへの移行を目指しております。GoogleのQUICライブラリに、その様子が伺えます
https://quiche.googlesource.com/quiche/+/refs/heads/master/quic/core/quic_versions.h
QUIC_VERSION_46 = 46, // Use IETF draft-17 header format with demultiplexing bit. QUIC_VERSION_47 = 47, // Allow variable-length QUIC connection IDs. QUIC_VERSION_48 = 48, // Use CRYPTO frames for the handshake. QUIC_VERSION_99 = 99, // Dumping ground for IETF QUIC changes which are not yet ready for production.
gQUICでも暗号経路を確立するために暗号ハンドシェイクを行いますが、iQUICと同様のTLS1.3を用いたハンドシェイクの場合は、iQUICのバージョン同様 0xff0000
https://quiche.googlesource.com/quiche.git/+/c8d9e40cd42e73b643e36300c807865b2ec8787d/quic/core/quic_versions.cc#115
case QUIC_VERSION_99: if (parsed_version.handshake_protocol == PROTOCOL_TLS1_3) { return MakeVersionLabel(0xff, 0x00, 0x00, kQuicIetfDraftVersion); } return MakeVersionLabel(proto, '0', '9', '9');
ということで、実装的にはIETF QUIC版も対応していそうということがわかります。