QUIC の内部構造(ストリーム多重化と0-RTT)
なぜHTTP/3は遅延に強いのか。QUICがUDP上でストリーム多重化やコネクション移行、0-RTT再開をどう実現するかを内部から理解できます。
- 1.QUIC は UDP 上に独自の信頼性・順序制御・輻輳制御を実装し、ストリームごとに独立した順序保証で TCP の HoL ブロッキングを解消する。
- 2.コネクションを IP/ポートではなく Connection ID で識別するため、経路が変わっても再接続なしで通信を継続できる。
- 3.TLS 1.3 を統合し、再訪時は事前共有鍵で 0-RTT 再開が可能。ただし再送攻撃の余地があり冪等な要求に限るべき。
なぜ UDP の上に作るのか
QUIC(RFC 9000)は TCP を置き換えるトランスポートですが、ネットワーク機器(NAT・ファイアウォール・ロードバランサ)の多くは TCP と UDP しか素通しせず、新しいプロトコル番号は途中で落とされます。そこで QUIC は UDP のペイロードとして自身のパケットを運び、信頼性・順序制御・輻輳制御・暗号化をすべてユーザー空間(アプリやライブラリ側)で再実装します。OS のカーネルに依存しないため、TCP では難しかった改良の即時展開も可能になりました。詳しくは /network/tcp-udp/ と /network/http-versions/ も参照してください。
パケットとフレームの二層構造
QUIC は「パケット」と「フレーム」を分けて考えます。
- パケット: UDP データグラムに入る暗号化の単位。一意なパケット番号を持ち、再送されても同じ番号は二度と使わない(TCP のシーケンス番号と異なる重要点)。
- フレーム: パケットの中身。
STREAM(データ本体)、ACK(受信確認)、CRYPTO(ハンドシェイク)、MAX_DATA(フロー制御)など型がある。1 パケットに複数フレームを詰められる。
パケット番号が単調増加するため、再送パケットの ACK と元パケットの ACK を取り違える再送アンビギュイティが原理的に起きません。これにより RTT 計測が正確になり、輻輳制御の精度が上がります。
UDP データグラム
└─ QUIC パケット(暗号化, パケット番号 = N)
├─ STREAM フレーム(stream_id=4, offset, data)
├─ STREAM フレーム(stream_id=8, offset, data)
└─ ACK フレーム(受信済みパケット番号の範囲)
ストリーム多重化と HoL ブロッキングの解消
QUIC は 1 コネクション内に多数のストリームを持ち、各ストリームは独立したバイト列です。ストリーム ID の下位 2 ビットで「開始側(クライアント/サーバー)」と「双方向/単方向」を区別します。
順序保証はストリームごとに閉じているのが核心です。あるパケットが失われても、影響を受けるのはそのパケットに含まれていたストリームだけで、他ストリームのデータは到着次第アプリへ引き渡せます。
HTTP/2 も多重化しますが土台が TCP のため、1 つのセグメント欠落で TCP が接続全体の引き渡しを止め、全ストリームが再送を待ちます(TCP 層の HoL ブロッキング)。QUIC は順序制御をストリーム単位に分解することで、この詰まりを根本から断ち切ります。
コネクション移行(Connection Migration)
TCP コネクションは「送信元IP・送信元ポート・宛先IP・宛先ポート」の 4 つ組で識別されます。スマートフォンが Wi-Fi からモバイル回線へ切り替わると送信元 IP が変わり、TCP では接続が切れて張り直しになります。
QUIC はコネクションを 4 つ組ではなく Connection ID(CID) で識別します。経路が変わって IP/ポートが変化しても、CID が一致すれば同じコネクションとして継続できます。
- 移行時は Path Validation(
PATH_CHALLENGE/PATH_RESPONSE)で新経路の到達性を確認してから本格利用する。 - 観測者による紐付けを防ぐため、CID は複数発行され経路変更に合わせて差し替えられる。
- 輻輳制御の状態は新経路では原則リセットし、未知の帯域に過大な送信をしない。
ハンドシェイクと 0-RTT
QUIC は /network/tls/ の TLS 1.3 を別レイヤとして上に載せるのではなく統合し、鍵交換を CRYPTO フレームでトランスポートと同じパケットに相乗りさせます。これにより、通常の TCP+TLS が要した「TCP の 3 ウェイ+TLS のやり取り」が 1-RTT に圧縮されます。
さらに、過去に通信した相手へは 0-RTT で再開できます。初回ハンドシェイク時にサーバーが渡した情報から事前共有鍵(PSK)を導出し、再訪時は最初のパケットに暗号化済みのアプリデータ(例: GET 要求)をいきなり載せて送ります。
| 方式 | 初回接続のRTT | 再訪時のRTT | 前提 |
|---|---|---|---|
| TCP + TLS 1.2 | 約3往復 | 約3往復 | 別レイヤで逐次 |
| TCP + TLS 1.3 | 約2往復 | 約1往復(セッション再開) | TLSのみ短縮 |
| QUIC 1-RTT | 1往復 | 1往復 | TLSを統合 |
| QUIC 0-RTT | 1往復 | 0往復(初手でデータ送出) | PSKを保持済み |
0-RTT データは過去の鍵材料に基づくため、攻撃者がパケットをコピーして再注入すると、サーバーが同じ要求を二重処理し得ます(リプレイ攻撃)。対策として、0-RTT は 冪等な要求(GET など副作用のないもの)に限定し、課金・購入・更新系は 1-RTT 確立後に回すのが原則です。
「QUIC が UDP 上で TCP の HoL を解消できる理由」は、ストリーム単位で順序保証を独立させたから。「0-RTT の危険性」はリプレイ攻撃で、冪等要求に限定する。この 2 点はほぼ必出です。
輻輳制御とフロー制御
QUIC は TCP と同様の輻輳制御(CUBIC / BBR 等)をプロトコルとは独立に差し替え可能な形で持ちます。フロー制御は二段構えで、コネクション全体の上限(MAX_DATA)とストリームごとの上限(MAX_STREAM_DATA)を別々に通知します。これにより、1 本の重いストリームがコネクション全体のバッファを食い尽くす事態を防ぎます。基礎となる輻輳・再送の考え方は /network/tcp-ip/ の TCP の挙動と対比すると理解が深まります。
まとめ
QUIC の本質は「TCP が担っていた信頼性・順序・暗号化を、UDP の上に再設計して統合した」点にあります。順序保証をストリーム単位に分解して HoL を断ち、CID で経路非依存の継続を実現し、TLS 1.3 統合で接続確立を 1-RTT・再訪を 0-RTT まで縮める。HTTP/3 が高遅延・不安定回線で強いのは、これらが積み重なった結果です。
ネットワーク Article
QUIC の内部構造(ストリーム多重化と0-RTT)を実務で読む
TL;DRは入口です。実際に選ぶ・使う段階では、何を解決するか、何と比較するか、導入後にどこで詰まるかまで見る必要があります。
解決すること
QUIC
比較で見る軸
難易度: advanced / カテゴリ: ネットワーク / タグ数: 5
導入後に効く点
コネクションを IP/ポートではなく Connection ID で識別するため、経路が変わっても再接続なしで通信を継続できる。
先に潰すリスク
用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。
- 難易度
- advanced
- カテゴリ
- ネットワーク
- タグ数
- 5
判断チェックリスト
- 自社の用途が「QUIC / HTTP/3」に近いか確認する。
- 強みである「QUIC は UDP 上に独自の信頼性・順序制御・輻輳制御を実装し、ストリームごとに独立した順序保証で TCP の HoL ブロッキングを解消する。」が本当に評価軸になるか確認する。
- 注意点の「用語だけ覚えても、設計・実装・運用でどこに効くかを確認しないと判断を誤る。」を運用で吸収できるか確認する。
- 公開値や仕様値は、対象プラン・対象機種・対象リージョンまで確認する。
- 既存システム、ID、ネットワーク、監視、バックアップとの接続方法を先に洗い出す。
- 小さく試してから、本番移行、権限設計、障害時手順、コスト監視を決める。