RustでQUICやHTTP/3を扱おうとすると、最初に決めなければならないのはライブラリの選定です。候補として挙がるのはCloudflareのquiche、コミュニティ開発のquinn、AWSのs2n-quicあたりですが、どのREADMEにも「IETF仕様のQUIC実装」と書かれており、そこから先の違いが見えてきません。
比較が難しいのには理由があります。いずれも継続的にメンテナンスされており、仕様への追従度も高く、機能一覧を並べるとほとんど同じ項目が並びます。QUICのバージョンネゴシエーション、0-RTT、コネクションマイグレーション、輻輳制御の切り替え——どれも「対応している」と書かれているため、機能の有無では決め手が出ません。
決め手になるのは機能差ではなく、設計思想の差です。具体的には「I/O(ソケット操作とイベントループ)をライブラリに任せるのか、自分のアプリケーション側で持つのか」という一点です。quicheはこの点で明確に後者を選んでおり、その選択が採用コストの正体にもなっています。
本記事では、quicheのsans-I/O設計、HTTP/3への対応、同一リポジトリに同居するtokio-quiche、そして類似実装との差分を、quiche のREADME・公式APIドキュメント・Cloudflareの公式ブログ・リポジトリ内のコードをもとに整理します。動作検証やインストールは行っておらず、記述はすべて公開ドキュメントとリポジトリの読解に基づくものです。数値は2026年9月27日時点の公開値です。
quicheとは何か|CloudflareのRust製QUIC・HTTP/3実装
quicheは、IETFが標準化したQUICトランスポートプロトコルとHTTP/3の実装です。READMEは自身の役割を「QUICパケットの処理とコネクション状態の管理のための低レベルAPIを提供する」と説明し、続けて「I/O(ソケット処理など)とタイマーをサポートするイベントループの提供はアプリケーションの責務である」と明記しています(README)。
つまりquicheは、QUICの状態機械とパケットの符号化・復号を担当し、ネットワークとの接点は一切持ちません。この線引きが、後述する採用判断のすべての起点になります。
リポジトリの基本情報とメンテナンス状況
まずメンテナンス状況の客観材料を並べます。
項目 | 値 |
|---|---|
リポジトリ | |
説明 | Savoury implementation of the QUIC transport protocol and HTTP/3 |
主要言語 | Rust |
スター数 | 12,633 |
フォーク数 | 1,149 |
ライセンス | BSD-2-Clause |
公開状態 | public(アーカイブされておらず、フォークでもありません) |
リポジトリ作成 | 2018年9月29日 |
最終push | 2026年9月25日 |
最新リリース | 0.30.0(2026年9月17日) |
オープンなissue | 370件 |
topics | http3 / network-programming / protocol / quic / rust |
2018年から継続しているプロジェクトで、直近も更新が入っています。リリース履歴を見ると0.28.0・0.29.0・0.29.1・0.29.2(いずれも2026年6月)、0.29.3(同年7月)、0.30.0(同年9月)と、2026年内に複数のマイナー・パッチリリースが出ています。ライセンスはBSD-2-Clauseが設定済みで、アーカイブ済みリポジトリやフォークではないため、必要に応じて自前でパッチを当てる選択肢も残ります。
一点、先に開示しておきたいのが言語構成です。GitHubが集計する言語バイト数はRustが約4.66MBで大半を占めますが、Cが約112KB含まれています。これは後述するC API(FFI)のヘッダやBoringSSL連携に関わる部分で、「純Rustのライブラリ」ではないという事実は選定時の材料になります。C依存を避けたい要件がある場合、この点は早い段階で確認しておく価値があります。
誰が本番で使っているか
READMEの「Who uses quiche?」には3つの採用先が挙げられています。
- Cloudflare: 同社エッジネットワークのHTTP/3サポートをquicheが支えていると記載されています(出典: HTTP/3: the past, present, and future)。動作確認用のサイトとして
cloudflare-quic.comが公開されています - Android: AndroidのDNSリゾルバが、DNS over HTTP/3の実装にquicheを使用していると記載されています(出典: DNS-over-HTTP/3 in Android)
- curl: HTTP/3サポートのためにcurlへ統合できると記載されています(出典: curl の HTTP3.md)
エッジプロキシ・OSのリゾルバ・CLIツールという性格の異なる3つに組み込まれている点は、sans-I/O設計が持つ移植性の裏付けとして読めます。
quicheのsans-I/O設計|ソケットに触らないQUIC実装の狙い
quicheを評価するうえで最も重要なのが、この設計方針です。Cloudflareの公式ブログ「Enjoy a slice of QUIC, and Rust!」は、設計の中核を「QUICの複雑さを最小かつ直感的なAPIで露出させ、アプリケーションについての前提を置かないこと」と説明しています。そしてquiche自身はソケットに一切触らず、I/Oとイベントループの実装方法はOSが提供する機能に応じてアプリケーション側が自由に決められる、という構造を取っています。
なぜそうしたのかという背景も同記事に書かれています。Cloudflareのエッジでリクエストを扱うスタックの多くは依然としてCで書かれており、Rustで実装したQUICをそこへ持ち込む必要がありました。結果として、同社独自のNGINXフォークへNGINX内部の大幅な改変なしに統合できたと述べられています。
この設計はトレードオフです。得られるのは移植性と統合の容易さで、支払うのはアプリケーション側の実装責務です。パケットの受信ループ、送信ループ、タイマー管理は、すべて自分で書くことになります。採用可否を分けるのは、この責務を引き受けられるかどうかです。
Configが握る設定と「既定値ゼロ」の落とし穴
コネクションを確立する最初のステップは Config の生成です。READMEは次のコードを示しています。
let mut config = quiche::Config::new(quiche::PROTOCOL_VERSION)?;
config.set_application_protos(&[b"example-proto"]);
// Additional configuration specific to application and use case...
出典: https://github.com/cloudflare/quiche/blob/master/README.md
Config はQUICバージョン、ALPN ID、フロー制御、輻輳制御、アイドルタイムアウトなどを制御し、複数のコネクション間で共有できます。TLS設定も Config が保持しており、with_boring_ssl_ctx_builder() を使えばTLSコンテキストを手動で構築することも可能です。
ここで注意が必要なのが既定値の扱いです。READMEは「QUICは汎用のトランスポートプロトコルであり、合理的な既定値が存在しない設定項目がいくつかある」と説明しています。たとえば同時に許可するストリーム数は、QUICの上で動くアプリケーションの性質に依存するため、ライブラリ側で決められません。quicheは複数のプロパティを0に既定しており、アプリケーションは以下を明示的に設定する必要があります。
set_initial_max_streams_bidi()set_initial_max_streams_uni()set_initial_max_data()set_initial_max_stream_data_bidi_local()set_initial_max_stream_data_bidi_remote()set_initial_max_stream_data_uni()
これらを設定せずにコネクションを張ろうとしても、データを載せる余地が0のまま通信が進まないことになります。フィーチャフラグや各メソッドの詳細は公式APIドキュメントに一覧されています。
パケット処理ループとタイマーはアプリ側で書く
コネクションの生成は、クライアント側が connect()、サーバー側が accept() です。
// Client connection.
let conn = quiche::connect(Some(&server_name), &scid, local, peer, &mut config)?;
// Server connection.
let conn = quiche::accept(&scid, None, local, peer, &mut config)?;
出典: https://github.com/cloudflare/quiche/blob/master/README.md
受信側は、ソケットから読んだバイト列と送信元・宛先の情報を RecvInfo に詰めて conn.recv() に渡します。送信側は conn.send() を呼び、返ってきたバッファをソケットに書き出すループを回します。READMEの送信ループは次の形です。
loop {
let (write, send_info) = match conn.send(&mut out) {
Ok(v) => v,
Err(quiche::Error::Done) => {
// Done writing.
break;
},
Err(e) => {
// An error occurred, handle it.
break;
},
};
socket.send_to(&out[..write], &send_info.to).unwrap();
}
出典: https://github.com/cloudflare/quiche/blob/master/README.md
書き出すべきパケットがなくなると quiche::Error::Done が返るため、これをループの終了条件として扱います。エラーを「例外」ではなく制御フローの一部として使う形で、sans-I/Oライブラリらしいインターフェースです。
さらに、パケット送信後は時間ベースのイベント(再送タイマーなど)に反応する責務がアプリケーション側にあります。期限は次のメソッドで取得します。
let timeout = conn.timeout();
出典: https://github.com/cloudflare/quiche/blob/master/README.md
READMEは「タイマーの実装はアプリケーションの責務であり、使用するOSやネットワーキングフレームワークに固有のものになりうる」と述べています。期限が切れたら conn.on_timeout() を呼び、そのあとで再度送信ループを回して必要なパケットを送り出します。ハンドシェイクが完了したあとのデータ送信は conn.stream_send()、読み取り可能なストリームの列挙は conn.readable()、読み取りそのものは conn.stream_recv() です。
ここまでが「アプリケーション側に降りてくる実装」の輪郭です。QUICの状態管理そのものはライブラリが持ちますが、ソケットとタイマーの配線は自分で設計することになります。
ペーシングとSendInfoのatフィールド
もう一つ、自前実装で見落としやすいのがペーシングです。READMEは、短期的な輻輳とパケットロスを引き起こすパケットバーストを避けるため、送信パケットのペーシングを推奨しています。
quicheは send() が返す SendInfo 構造体の at フィールドでペーシングのヒントを提供します。このフィールドは「特定のパケットをネットワークへ送出すべき時刻」を表します。アプリケーションはこのヒントを使い、Linuxのソケットオプションである SO_TXTIME のようなプラットフォーム固有の機構、あるいはユーザー空間のタイマーによって送信を意図的に遅延させます。READMEは参照先としてRFC 9002のセクション7.7を挙げています。
ライブラリが「いつ送るべきか」を計算して返し、「送出を遅延させる」のはアプリケーション側という責務分担になっています。
選択できる輻輳制御アルゴリズム
輻輳制御は set_cc_algorithm() または set_cc_algorithm_name() で切り替えられます。リポジトリ内の実装を読むと、列挙されているアルゴリズムは次の3種です。
pub enum CongestionControlAlgorithm {
/// Reno congestion control algorithm. `reno` in a string form.
Reno = 0,
/// CUBIC congestion control algorithm (default). `cubic` in a string form.
CUBIC = 1,
/// BBRv2 congestion control algorithm implementation from gcongestion
/// branch. `bbr2_gcongestion` in a string form.
Bbr2Gcongestion = 4,
}
出典: https://github.com/cloudflare/quiche/blob/master/quiche/src…
既定はCUBICです。文字列指定では reno / cubic / bbr / bbr2 / bbr2_gcongestion が受け付けられ、bbr と bbr2 はいずれも Bbr2Gcongestion に解決されます。実装は quiche/src/recovery/congestion/(cubic.rs、reno.rs、hystart.rs、prr.rs など)と quiche/src/recovery/gcongestion/(bbr.rs、bbr2.rs、pacer.rs など)に分かれて配置されています。
選定の観点では「主要なアルゴリズムが選択可能であり、既定値が明示されている」という事実の確認までが必要な情報です。どのアルゴリズムをどう調整するかは、対象ネットワークの特性に依存する運用側のテーマになります。
quicheでHTTP/3を扱う|h3モジュールとQPACKの位置づけ
quicheはQUICトランスポートだけでなく、その上のHTTP/3も同一クレート内で扱えます。公開モジュールの h3 が、HTTP/3のワイヤプロトコルとQPACKの実装を提供し、QUICの上でHTTPリクエストとレスポンスを扱う高レベルAPIとして位置づけられています(h3 モジュールの公式ドキュメント)。
つまりquicheは、QUICパケットを扱う低レベルAPIと、HTTPセマンティクスを扱う高レベルAPIの二層構造になっています。この構造は、あとで比較するquinnとの差として現れます。quinn本体はトランスポート層が中心で、HTTP/3を使うには別のクレートを組み合わせる構成が一般的です。HTTP/3までを1つのライブラリで完結させたい場合、quicheはその要件を単体で満たします。
関連する仕様の役割分担も整理しておきます。リポジトリに同居するh3iのREADMEは、HTTP/3(RFC 9114)をHTTPセマンティクス(RFC 9110)のワイヤ形式と位置づけ、QUIC(RFC 9000)のストリーム上でメッセージとQPACK(RFC 9204)のヘッダ圧縮命令をやりとりするものとして説明しています。HTTP/3を実装するライブラリを評価する際は、この4つの仕様のうちどこまでを引き受けてくれるのかを確認すると、担当範囲の違いが見えやすくなります。
なお、h3i自体はHTTP/3のデバッグ・テスト用のクレートです。RFCのルールを意図的に曲げてサーバーの挙動を試験できる対話的なクライアントとライブラリを提供しており、ストリームを任意のタイミングでopen・fin・stop・resetしたり、任意のストリームに任意の順序でHTTP/3フレームを送ったりできます。READMEには「本番のHTTP/3クライアントとして意図されておらず、本番化の計画もない」と明記されているため、用途を取り違えないよう注意が必要です。
tokio-quicheが埋めるsans-I/Oの実装コスト
sans-I/Oの弱点は、Cloudflare自身が公式ブログで認めています。「Async QUIC and HTTP/3 made easy — tokio-quiche is now open-…」では、quicheがユーザーのI/Oの実現方法を前提にせずにQUICの状態機械を実装している一方で、「sans-I/Oライブラリをアプリケーションに統合する作業はエラーが起きやすく時間がかかる」と述べられています。この参入障壁を下げる目的で、同じリポジトリに tokio-quiche クレートが用意されています。
tokio-quicheは、UDPソケットの操作と非同期タスクのスケジューリングを引き受け、quiche::Connection と quiche::h3::Connection をtokioのイベントループに接続します。ユーザーは独自の ApplicationOverQuic を実装するか、HTTP/3クライアント・サーバー向けの既成の H3Driver を使うかを選べます(tokio-quiche の README)。
先ほど見たsans-I/Oの実装責務が、ここで選択肢に変わります。自分でイベントループを設計する必要があるのは「そうしたい/そうせざるを得ない」場合に限られ、tokioを前提にできるなら実装の大半を引き受けてもらえます。
アクターモデルでsans-I/Oを非同期化する仕組み
公式ブログによれば、tokio-quicheはアクターモデルを採用しています。内部状態を持つ小さな非同期タスクが、チャネル経由のメッセージパッシングで外部と通信する構造で、sans-I/Oライブラリの非同期化にアクターモデルは相性が良いと説明されています。
主要なアクターは2つです。InboundPacketRouter は受信したデータグラムをコネクションIDでルーティングし、コネクションごとのチャネルへ渡します。IoWorker は個々のquicheコネクションを駆動する主I/Oループを担います。この構造により、quicheの呼び出しとアプリケーションプロトコルのメソッド呼び出しをインターリーブし、I/Oの前後でコネクションの状態を検査できるとされています。
ApplicationOverQuicとH3Driverの使い分け
ApplicationOverQuic は、QUICの上で異なるアプリケーションプロトコル(HTTP/3やDNS-over-QUICなど)を扱うための抽象トレイトです。HTTP/3を使う場合は、その実装として提供されている H3Driver を使えます。H3Driver には ServerH3Driver と ClientH3Driver のバリアントがあります。
READMEのサーバー起動例からは、UDPソケットで待ち受けてコネクションごとにtokioタスクを割り当てる流れが読み取れます(use文とハンドラ実装は省略し、起動部分のみを抜粋します)。
let socket = tokio::net::UdpSocket::bind("0.0.0.0:4043").await?;
let mut listeners = listen(
[socket],
ConnectionParams::new_server(
Default::default(),
tokio_quiche::settings::TlsCertificatePaths {
cert: "/path/to/cert.pem",
private_key: "/path/to/key.pem",
kind: tokio_quiche::settings::CertificateKind::X509,
},
Default::default(),
),
SimpleConnectionIdGenerator,
DefaultMetrics,
)?;
let accept_stream = &mut listeners[0];
while let Some(conn) = accept_stream.next().await {
let (driver, controller) = ServerH3Driver::new(Http3Settings::default());
conn?.start(driver);
tokio::spawn(handle_connection(controller));
}
出典: https://github.com/cloudflare/quiche/blob/master/tokio-quic…
listen() にソケットとサーバー用のコネクションパラメータ、コネクションID生成器、メトリクス実装を渡し、受け付けたコネクションに ServerH3Driver を割り当てて起動する形です。TLS証明書は TlsCertificatePaths にパスとして渡します。sans-I/Oのループを手書きする場合と比べ、アプリケーションが書くコードの層が明確に上がっています。
Cloudflare内部での採用先として、公式ブログはApple iCloud Private RelayのProxy B、次世代のOxyベースのプロキシ群、Cloudflare WARPのMASQUEクライアント、非同期版のh3iデバッグクライアントを挙げています。そして「毎秒数百万件のHTTP/3リクエストを低レイテンシ・高スループットで処理している」と述べています。この記述はtokio-quicheに関するCloudflareの説明であり、quiche単体のベンチマーク結果ではない点に注意してください。
モノレポに同居する周辺クレート
quicheのリポジトリはモノレポ構成で、Cargo.toml のworkspace membersにはapps、buffer-pool、datagram-socket、h3i、netlog、octets、qlog、qlog-dancer、quiche、task-killswitch、tokio-quicheが並びます。
クレート | 役割 | 本番利用の可否 |
|---|---|---|
| QUIC / HTTP/3 の低レベルsans-I/O実装本体 | ライブラリ本体 |
| quicheとtokioの橋渡し。 | ライブラリ |
| 低レベルHTTP/3のデバッグ・テスト用の対話CLIとライブラリ | 公式に本番用途は非対象と明記 |
| 動作確認用のコマンドラインツール | 公式に本番環境向けではないと明記 |
| qlogメインスキーマ・QUICイベント・HTTP3/QPACKイベント定義の実装。SerdeでJSON変換 | ライブラリ |
| Chrome netlog形式のデシリアライザ。QUICとHTTPのイベントに対応 | ライブラリ |
| バイト列操作、バッファプール、データグラムソケット抽象、タスク停止制御、qlog補助などの基盤 | 基盤クレート |
動作確認用のCLIはREADMEに実行例が掲載されています。
$ cargo run --bin quiche-client -- https://cloudflare-quic.com/
出典: https://github.com/cloudflare/quiche/blob/master/README.md
ただしREADMEのDisclaimers and Notesには、これらのツールについて「本番環境での使用を意図しておらず、性能・セキュリティ・信頼性のいずれも保証しない」と明記されています。同梱の証明書も自己署名で、本番利用は想定されていません。評価用の疎通確認に使うツールと、本番に載せるライブラリを明確に区別しておく必要があります。
quicheとquinn・s2n-quicの違い|QUIC実装の選定軸
ここまで整理したquicheの性格を、類似実装と並べて比較します。まずメタ情報です。数値はいずれも2026年9月時点でGitHub APIから取得した公開値です。
リポジトリ | 言語 | スター | ライセンス | 最終push | 開発主体 |
|---|---|---|---|---|---|
Rust | 12,633 | BSD-2-Clause | 2026-09-25 | Cloudflare | |
Rust | 5,271 | Apache-2.0 | 2026-09-23 | コミュニティ | |
C | 4,781 | MIT | 2026-09-26 | Microsoft | |
C | 1,876 | MIT | 2026-09-20 | LiteSpeed | |
C | 1,521 | MIT | 2026-09-26 | ngtcp2プロジェクト | |
Rust | 1,371 | Apache-2.0 | 2026-09-25 | AWS |
いずれも直近1週間以内に更新が入っており、メンテナンスの活発さでは差がつきません。判断材料になるのは次の設計軸です。
軸 | quiche | quinn | s2n-quic | msquic / ngtcp2 / lsquic |
|---|---|---|---|---|
I/Oモデル | sans-I/O。ソケットとイベントループはアプリの責務。非同期が必要なら同一リポジトリのtokio-quicheを重ねる | tokio前提の非同期API | 非同期実装。APIのシンプルさを優先 | Cライブラリとして各プロジェクトの方式でI/Oを統合 |
HTTP/3 | 本体に | 本体はトランスポート中心(HTTP/3は別クレートと組み合わせる構成が一般的) | トランスポート中心 | lsquicはHTTP/3を含む。msquic・ngtcp2はトランスポート中心(ngtcp2はnghttp3と組み合わせ) |
Cからの利用 |
| 純Rust。C APIは主眼ではない | 純Rust | C実装そのもの。C/C++からの利用が第一 |
TLSバックエンド | BoringSSL( | rustls(純Rustで外部C依存を避けやすい) | s2n-tls / rustls系 | OpenSSL系やBoringSSLなどを各々選択 |
本番運用の裏付け | Cloudflareのエッジ、Android、curlへの統合 | 各プロジェクトでの採用 | AWS | 各社・各プロジェクトでの採用 |
Rust製の3実装(quiche / quinn / s2n-quic)の設計思想の違い
Rust製の3つに絞ると、違いは2点に集約されます。
1つはI/Oの扱いです。quicheはsans-I/Oで、状態機械だけを提供します。quinnはtokioを前提とした非同期APIを提供し、tokioのTCP APIに近い感覚でQUICを扱えます。s2n-quicも非同期実装で、AWS公式ブログ「Introducing s2n-quic」はシンプルさの優先とRustによる性能・メモリ安全性を設計目標として挙げています。既存の独自イベントループに組み込む必要がないなら、非同期前提の実装のほうが立ち上がりは早くなります。
もう1つはTLSバックエンドです。quicheはBoringSSLを使うためCツールチェーン(cmake)がビルド時に必要になります。quinnはrustlsを採用しており、外部のC依存を避けやすい構成です。クロスコンパイルやビルド環境の制約が厳しいプロジェクトでは、この差がビルド環境を用意する手間として現れます。
C実装(msquic / ngtcp2 / lsquic)との住み分け
既存のスタックがC/C++で、Rustツールチェーンを持ち込みにくい場合は、C実装が素直な選択になります。msquicはC実装でC・C++・C#・Rustに公開されており、ngtcp2はトランスポートに専念してHTTP/3はnghttp3と組み合わせる構成、lsquicはHTTP/3まで含むライブラリです。
一方で、C/C++スタックにRust実装を組み込む道も残されています。quicheはRust APIの上に薄いC APIを公開しており、READMEは「C APIはC言語の制約の範囲でRust APIと同じ設計に従う」と説明しています。cargo build するとRustライブラリと並んで静的ライブラリ libquiche.a が生成され、完全にスタンドアロンでC/C++アプリケーションに直接リンクできます。ヘッダは quiche/include/quiche.h です。C/C++からの利用が設計目標に含まれている点は、Rust製の3実装のなかでquiche固有の特徴です。
比較で参考にしてよい情報とすべきでない情報
QUIC実装の比較では、性能の優劣を主張する第三者の記事が数多く見つかります。ただしそうした主張の多くは、測定に使ったバージョン、輻輳制御アルゴリズム、フロー制御の設定値、ネットワークのRTTとロス率、並行コネクション数といった条件が特定できません。QUICは輻輳制御とフロー制御の設定で挙動が大きく変わるため、条件が不明な数値は自分の環境への予測に使えません。
代わりに参照すべきは2種類の情報です。1つは各実装の公式ドキュメントや公式ブログが述べる設計目標で、これは「何を優先して作られたライブラリか」を示します。もう1つは自分のワークロードでの実測で、こちらが最終的な判断材料になります。比較テーブルは候補を絞るために使い、最後の詰めは自分の条件での計測に委ねる、という順序が現実的です。
quiche採用前に確認したい依存関係とバージョン運用
設計思想が自分の要件に合いそうだと判断できたら、次は実務的な前提条件の確認です。採用後につまずきやすい点を先に並べます。
確認項目 | 内容 |
|---|---|
Rustのバージョン | Rust 1.88以降が必要(READMEはrustupの利用を推奨) |
ビルドツール | BoringSSLが |
独自BoringSSL | 自前ビルドのBoringSSLを使う場合は |
FFI(C連携) |
|
バージョン系列 | 2026年9月時点の最新は0.30.0で、1.0未満。マイナー更新に破壊的変更が入る前提で運用する |
動作確認用ツール |
|
ビルドに必要な環境とBoringSSL依存
QUICのハンドシェイクはTLS 1.3を使うため、quicheはTLS実装としてBoringSSLをリンクします。Cloudflareの設計ブログは、BoringSSLのQUIC専用APIが統合しやすかったと述べています。現行のフィーチャ構成では boringssl-boring-crate が既定フィーチャで、公式APIドキュメントには他に pkg-config-meta、ffi、qlog、custom-client-dcid(ドキュメント上で「Dangerous」と注記)が列挙されています。
実務上の影響は明確です。Rustだけでビルドが完結せず、cmake(Windowsでは加えてNASM)を用意する必要があります。CIコンテナやクロスコンパイル環境を自前で組んでいる場合、ここは事前に確認しておくべき点です。純Rustのビルドチェーンを維持したい要件があるなら、rustlsベースの実装のほうが条件に合います。
0.x系のバージョン運用と破壊的変更の実例
quicheは0.x系であり、マイナー更新に破壊的変更が入ります。直近の0.30.0のリリースノートには、Breaking Changesとして次の2点が挙げられています(出典: 0.30.0 のリリースノート)。
1点目は PathEvent が #[non_exhaustive] になり PmtuUpdated バリアントが追加されたことです。Rust側でこの列挙型を網羅的にmatchしているアプリケーションは、ワイルドカードアームの追加が必要になります。C側ではPMTU discoveryを有効にしている場合に QUICHE_PATH_EVENT_PMTU_UPDATED のハンドリングが必要です。
2点目は依存する boring クレートの対応範囲が >=4.19,<6 に変わったことです。新規に解決すると5.x系が既定になります。ここには2つの副作用が記載されています。libquiche.a を静的リンクするCアプリケーションはC++リンカドライバ(またはC++ランタイムのリンク)が必要になること、そしてboring 5は既定でポスト量子鍵交換群が有効になるため、ClientHelloが複数のInitialパケットに分割されうることです。小さく決定的なClientHelloが必要な場合の対処として、Config::set_curves_list() および quiche_config_set_curves_list() の使用が案内されています。
同じリリースには改善も含まれています。コピーせずに連続読み取り可能なバイト数を取得する Connection::stream_readable_len() の追加、長時間のバルク転送が FLOW_CONTROL_ERROR で切断されうるコネクションレベルのフロー制御の二重計上バグの修正、0-RTTハンドシェイク中にearly dataが受理された際にハンドシェイクコールバックの設定が失われる不具合の修正、HTTP/3の未知・空の単方向ストリームのクリーンアップ修正などです。
読み取れるのは、活発に改善されている一方で、アップデート時にリリースノートを読む運用が必須だという点です。バージョンを固定して塩漬けにする運用は、修正されたバグを抱え続けることになります。採用するなら、定期的にリリースノートを確認して追従する体制を前提にしておくのが妥当です。
モバイル・C/C++統合で追加で必要になること
モバイル向けのビルド手順は公式に用意されています。Android向けはNDK 19以上(21推奨)、cargo-ndk v2.0以降、ANDROID_NDK_HOME の設定が必要で、対象APIレベルの最小は21です。READMEにはターゲットとAPIレベルを指定して --features ffi 付きでビルドする例が掲載されています。iOS向けはXcodeのコマンドラインツール、rustup target add によるターゲット追加、cargo-lipo を使う手順です。Dockerイメージも公開されており、cloudflare/quiche にはserverとclientが /usr/local/bin に配置されています。
AndroidのDNSリゾルバでの採用実績を踏まえると、モバイル環境への組み込みは実績のあるルートだと読めます。ただしいずれの場合も ffi フィーチャの明示的な有効化と、BoringSSLのビルドに必要なツールチェーンの用意が前提になる点は変わりません。
どんなプロジェクトでquicheを選ぶべきか
ここまでの材料を、採用判断の形に整理します。
前提条件 | 推奨 | 理由 |
|---|---|---|
既存のC/C++スタック、または独自のイベントループにQUIC/HTTP/3を組み込む | quiche | sans-I/O設計と |
HTTP/3までを1つのライブラリで完結させたい | quiche |
|
tokio前提で非同期のHTTP/3サーバーを組みたい | quiche + tokio-quiche | I/Oループの実装をtokio-quicheに委ね、 |
大規模な本番運用の裏付けを重視する | quiche | Cloudflareのエッジ、AndroidのDNSリゾルバ、curlへの統合が公式に示されています |
純RustのビルドでCツールチェーン依存を避けたい | quinn | rustlsを使うため |
APIのシンプルさと立ち上がりの速さを優先する | quinn / s2n-quic | 非同期前提のAPIで、I/Oループを自前で設計する必要がありません |
C/C++ネイティブのスタックでRustツールチェーンを持ち込めない | msquic / ngtcp2 / lsquic | C実装であり、C/C++からの利用が第一の設計目標です |
quicheが選ばれる理由を一文にすると、「QUICの状態機械だけを借りて、I/Oの設計は自分の手元に残したいプロジェクトに合う」ということです。これは強みと制約が同じ場所から出ている構造で、裏を返せば「I/Oまで任せたい」プロジェクトには向きません。その場合はquinnやs2n-quic、あるいは同一リポジトリのtokio-quicheを重ねる構成が選択肢になります。
判断を先に進めるなら、次の順序で確認するのが最短です。まず自分のスタックに独自のイベントループやC/C++コードがあるかを確認し、あるならquicheの適合度は高くなります。次にHTTP/3が必要かを確認し、必要なら h3 モジュールの同梱が効きます。最後にビルド環境で cmake(Windowsでは加えてNASM)を用意できるかを確認します。この3点が揃えば、公式APIドキュメントの Config と Connection のページを読み進める段階に入れます。
関連情報
QUICやHTTP/3を含む通信基盤の設計・実装、既存システムへのプロトコル導入をご検討中の場合は、お問い合わせフォーム からご相談いただけます。要件の整理段階からのご相談も承っています。
ネットワークやプロトコル領域のスキルを活かせる案件をお探しの方は、Workee(フリーランス向け) で案件情報をご確認いただけます。
参考リンク
- cloudflare/quiche(GitHub リポジトリ・README)
- quiche 公式APIドキュメント
- quiche h3 モジュールの公式ドキュメント
- Enjoy a slice of QUIC, and Rust!(Cloudflare 公式ブログ・設計思想)
- Async QUIC and HTTP/3 made easy — tokio-quiche is now open-…
- quiche 0.30.0 リリースノート
- tokio-quiche(サブクレート README)
- h3i(サブクレート README)
- quiche.h(C API ヘッダ)
- recovery/mod.rs(輻輳制御アルゴリズムの実装)
- RFC 9002 Section 7.7(ペーシング)



