curlのHTTP/3実験実装を触ってみる

First HTTP/3 with curl | daniel.haxx.se」で書かれている通り、curlがHTTP/3の実験実装を公開したので試す。

ライブラリとしてngtcp2を使う方法と、cloudflareのquicheを使う方法があるが今回はquicheを使う。

基本的には、Documentにかかれている通り。

なお、環境はUbuntu18.04

ビルド

boringSSLのビルド

$ git clone --recursive https://github.com/cloudflare/quiche
$ mkdir -p quiche/deps/boringssl/build
$ cd quiche/deps/boringssl/build
$ cmake -DCMAKE_POSITION_INDEPENDENT_CODE=on ..
$ make -j`nproc`
$ cd ..
$ mkdir .openssl/lib -p
$ cp build/crypto/libcrypto.a build/ssl/libssl.a .openssl/lib
$ ln -s $PWD/include .openssl

quicheのビルド

$ curl https://sh.rustup.rs -sSf | sh
$ source $HOME/.cargo/env

$ cd ../..
$ QUICHE_BSSL_PATH=$PWD/deps/boringssl cargo build --release

curlのビルド
サーバがレスポンスヘッダでHTTP/3対応を示すのに使われるalt-svcも有効にするために、"--enable-alt-svc"をつけてconfigureする

$ cd ..
$ git clone https://github.com/curl/curl
$ ./buildconf
$ ./configure --with-ssl=$PWD/../quiche/deps/boringssl/.openssl --with-quiche=$PWD/../quiche --enable-debug --enable-alt-svc
$ make -j`nproc`

うまく行っていれば、configure時に下記の通り表示される

  Alt-svc:          enabled
...
  HTTP3:            enabled (quiche)

試す

上記の通り、alt-svcを使わずに直にHTTP/3で接続しに行く場合は --http3-direct をつけてアクセスする

$ src/curl --http3-direct https://www.facebook.com/  -v -s -o /dev/null
* STATE: INIT => CONNECT handle 0x563e1077b528; line 1362 (connection #-5000)
* Added connection 0. The cache now contains 1 members
* STATE: CONNECT => WAITRESOLVE handle 0x563e1077b528; line 1403 (connection #0)
*   Trying 31.13.82.36:443...
* Connecting socket 4 over QUIC
* Sent QUIC client Initial, ALPN: h3-22
* STATE: WAITRESOLVE => WAITCONNECT handle 0x563e1077b528; line 1482 (connection #0)
* Connected to www.facebook.com () port 443 (#0)
* STATE: WAITCONNECT => SENDPROTOCONNECT handle 0x563e1077b528; line 1538 (connection #0)
* Marked for [keep alive]: HTTP default
* STATE: SENDPROTOCONNECT => PROTOCONNECT handle 0x563e1077b528; line 1553 (connection #0)
* quiche established connection!
* STATE: PROTOCONNECT => DO handle 0x563e1077b528; line 1572 (connection #0)
* Using HTTP/3 Stream ID: 0 (easy handle 0x563e1077b528)
(略)

パケットキャプチャをすると、ちゃんとIETF QUIC draft-22バージョンで接続していることが確認できた
f:id:ASnoKaze:20190807031738p:plain