2022/01/04追記: この記事はすでに古いです。WebTransport over QUICは標準化せずに、WebTransport over HTTP/3を標準化する方向です。Chromeの実装もそちらに移っています。
"WebTransport over QUIC"の標準化及び、Chromiumでの実装が進んでいます。
今回はクライントを書いて、Chromiumに同梱されているquic_transport_simple_serverと通信してみました。環境は Ubuntu 18.04です。
WebTransport over QUICについては以前書いたブログを参照してください
asnokaze.hatenablog.com
quic_transport_simple_server のビルド
Chromiumのビルド手順通り勧めます (Google社員向けはスルーしましょう)
https://chromium.googlesource.com/chromium/src/+/master/docs/linux/build_instructions.md
- Install
- Get the code
- Install additional build dependencies
- Run the hooks
- Setting up the build
フェッチに時間がかかります。
最後にビルドする際に、chromeのビルドではなく、サンプルサーバのみをビルドします
autoninja -C out/Default chrome #この部分を
ninja -C out/Default quic_transport_simple_server #こうする
証明書・鍵の作成
サーバを起動するのにPKCS#8形式の鍵が必要です
openssl req -new -key server.key > server.csr openssl req -new -key server.key > server.csr openssl x509 -days 3650 -req -signkey server.key < server.csr > server.crt openssl pkcs8 -topk8 -inform PEM -outform DER -nocrypt -in server.key -out server.p8
起動
ビルドができていれば、実行ファイルがありますので実行します
~/chromium/src/out/Default$ ./quic_transport_simple_server \ --accepted_origins="" \ --key_file="/path_to/server.p8" \ --certificate_file="/path_to//server.crt" \ --allow_unknown_root_cert --port="10000"
- --accepted_origins: client indicationで受け付けるオリジン名(空を指定)
- --key_file: 鍵
- --certificate_file: 証明書
- --port: ポート
クライアントサイド
WebTransport over QUICでは、QUIC DATAGRAMフレームのサポートが必須です。実際にはトランスポートパラメータでmax_datagram_frame_sizeを指定する必要があります。
今回はDATAGRAMフレームをサポートしてる、PythonのQUICライブラリ「aioquic」を利用します。
(exampleとして、DATAGRAM検証用プロトコル"siduck"実装が含まれてるのも選んだ理由です)
インストール方法は「aioquicのgithubリポジトリ」を参照。
./examples/siduck_client.py を雑にいじって、WebTransport over QUIC クライアントを作成します。
ソースはこちら https://gist.github.com/flano-yuki/3ab550393138066b19d2ff4d44e0cb47
~/work/aioquic$ python3 examples/quic_transport.py localhost 10000 -k -q out -l ./ssllog 2020-01-13 21:04:51,881 INFO quic [229cca53a4662860] ALPN negotiated protocol wq-vvv-01 2020-01-13 21:04:51,882 INFO client Sent Client Indication 2020-01-13 21:04:51,883 INFO client Say Hello 2020-01-13 21:04:51,885 INFO client Echo is received: 2020-01-13 21:04:51,885 INFO client b'hello world'
(-k はデバックログをファイルに出力、-lは復号用の鍵ファイルをファイルに出力)
quic_transport_simple_serverにデータを送って、Echoを受信することに成功しました。
修正ポイント
ポイントは
- ALPNとして"wq-vvv-01"を指定する
- Client Indicationを送信する(OriginとPATHをそれぞれ指定)
- PATHとして/echoを指定すると、サーバはechoモードで動作します (ソース)
b = b'\x00\x00' + b'\x00\x17' + b'https://example.com:443' b += b'\x00\x01' + b'\x00\x05' + b'/echo' self._quic.send_stream_data(2, b, True)
- クライアントからデータが送れるストリームでデータを送り、Echoされたデータを受信する
- (いくつか試したが、DATAGARAMフレームにはEchoを返してくれない...? ソース的には未実装?)
終わりに
とりあえず、通信できるところまでうまく行ったので、ちゃんとクライアントを実装したい。quic-go もDATAGARAMフレーム実装が進んでるので、そっちでも試したい (サーバ・クライアント両方)