このページの目次

UDP と QUIC 転送層

UDP は単なる「ポート番号付きの IP」に過ぎませんが、QUIC はその上で UDP を用いた完全な信頼性のある転送をカプセル化します: 0-RTT ハンドシェイク、ストリーム多重化によるヘッド・オブ・ライン・ブロッキングの回避、接続の移行——TCP が 30 年かけて学んだことを、QUIC は一度で正しく実装しました。

概要

UDP は最もシンプルな転送層プロトコルです——8 バイトのヘッダ、コネクションレス、再送なし、フロー制御なし。その「簡素さ」こそが利点です: DNS クエリ(1 ラウンドトリップ)、リアルタイム音声・映像(フレームの欠落が体験に影響しない)、VPN(WireGuard)などは UDP を選択します。QUIC は UDP 上に完全な現代の転送層を実装し、TCP のフロー制御/輻輳制御と TLS 1.3 の暗号化を単一のプロトコルに統合し、TCP のヘッド・オブ・ライン・ブロッキングと接続の移行の問題を解決しました。HTTP/3 は QUIC 上で動作します。

UDP

UDP ヘッダ (固定 8 バイト):

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|          ソースポート         |       デスティネーションポート  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|            長さ              |           チェックサム          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

長さ: UDP ヘッダ + ペイロードの合計長 (最小 8 = ヘッダのみ, 最大 65535)
チェックサム: IPv4 ではオプション (0=チェックサムなし), IPv6 では必須 — 擬似ヘッダ (src/dst IP +
          プロトコル + 長さ) + UDP ヘッダ + ペイロードをカバー

UDP は「ポート + 長さ + オプションのチェックサム」以外は何もしません——コネクションレス、再送なし、フロー制御なし、輻輳制御なし。アプリケーション層で信頼性が必要な場合は、自前で実装する必要があります。QUIC はまさに「アプリケーション層が転送層を自前で実装する」ケースです。

QUIC 転送層

QUIC は「UDP + 信頼性包装」ではありません——UDP 上に実装された全く新しい転送層であり、TCP のフロー制御/輻輳制御と TLS の暗号化認証を 1 つのプロトコルに統合しています。

QUIC パケット構造

QUIC ロングヘッダ (Initial/Handshake/0-RTT パケット):

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|1|   タイプ  |     バージョン (32 ビット)                        |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| DCID 長さ |  デスティネーション接続 ID (0-20 バイト)          ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SCID 長さ |  ソース接続 ID (0-20 バイト)                    ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

QUIC ショートヘッダ (1-RTT データパケット):

+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0|1|S|R|R|R|        デスティネーション接続 ID (...)           ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

ヘッダ形式 (ビット 0): 1=ロング, 0=ショート
固定ビット (ビット 1): 常に 1 — バージョンネゴシエーションの検出用 (ミドルボックスはこのビットを設定できない)
スピンビット (ショートヘッダのビット 2): 各 RTT で 1 回反転 — 観測者が RTT を測定可能
予約ビット: 0, ミドルボックスがこれらのビットを変更 → GREASE により検出 → 接続クローズ

QUIC 接続: 接続 ID

TCP 接続 = 5 タプル (src_ip, dst_ip, src_port, dst_port)。IP が変わると → 接続が切断されます。

QUIC 接続 = デスティネーション接続 ID + ソース接続 ID。エンドポイントはいつでも接続 ID を変更できます (NEW_CONNECTION_ID フレーム経由) → IP/ポートは完全に可変です。

接続の移行:

QUIC 接続移行: Connection ID は不変、IP が変わっても接続は維持 クライアント · WiFi IP 192.168.1.x · QUIC フローは CID_A → CID_B で接続を識別 4G に切り替え (ネットワーク切替) クライアント · 4G IP 10.10.10.x · PATH_CHALLENGE を送信 (新しい IP、同じ CID_A → CID_B) サーバー応答 PATH_RESPONSE 新しいパスの到達可能性を検証 → 移行確認 接続はシームレスに移行! アプリケーション層は何の中断も認識しません—— QUIC 接続は Connection ID (IP/ポートではなく) で識別され、ネットワーク変更でも接続は維持されます。

ストリーム多重化

1 つの QUIC 接続には複数のストリームがあります:

ストリーム ID (62 ビット、可変長エンコーディング):
  ビット 0: 0=クライアント開始, 1=サーバー開始
  ビット 1: 0=双方向, 1=単方向
  ビット 2-61: ストリーム番号 (0, 1, 4, 8, 12, ... — クライアントは 0 から開始、サーバーは 1 から開始、
             双方向のみ: 偶数がクライアント、奇数がサーバー)

各ストリームは独立:
  - 独立したフロー制御 (MAX_STREAM_DATA / STREAM_DATA_BLOCKED) を持つ
  - ストリーム 1 でパケットロス → ストリーム 1 のデータのみがブロックされ、ストリーム 3 は継続して配信
  - TCP のヘッド・オブ・ライン・ブロッキングを解決: TCP ではすべてのストリームのバイトが同じバイトストリーム内にあるため、1 つのロスですべてがブロックされる

接続レベルのフロー制御: MAX_DATA / DATA_BLOCKED — すべてのストリームの合計受信量を制限

0-RTT

初回接続:
  1-RTT: ClientHello → ServerHello → EncryptedExtensions → Finished → (データ)

以降の接続 (PSK モード):
  クライアント: 最後のセッションチケット (PSK + 転送パラメータ + サーバーアドレスを含む) をキャッシュ
  0-RTT: ClientHello + PSK + early data — ServerHello の受信前にデータ送信を開始
  サーバー: PSK を検証 → early data を受け入れ → 直接処理

0-RTT のセキュリティリスク — リプレイ:
  攻撃者が 0-RTT パケットをリプレイ → サーバーが重複処理 → 重複した副作用 (例: 2 回の課金)

QUIC の緩和策:
  - アプリケーション層: 0-RTT では冪等操作 (GET, HEAD, OPTIONS) のみを許可
  - 転送層: サーバーは REJECTED フレームを送信可能 → クライアントは 0-RTT データを再送信する必要あり
  - AEAD リミット: 同じキーで多数の 0-RTT パケットを使用することはできない → リプレイウィンドウを制限

QUIC 損失検出

QUIC の損失検出は TCP よりも正確です:

TCP: 重複 ACK 3 回 → 再送 (ただし SACK では、再順序化と損失を区別)

QUIC: 
  - 各パケットに独立したパケット番号 (単調増加、再送パケットでも新しい番号を使用)
  - 受信側 ACK フレーム: 最大受信番号 + 欠落範囲 → どのパケットが損失したかを正確に把握
  - 損失検出:
    1. 時間閾値: kTimeThreshold (9/8) × 最新の RTT を超える → 損失
    2. パケット閾値: kPacketThreshold (3) 以上のより大きなパケットが ACK された → 損失

QUIC の応用

HTTP/3: QUIC の最大のユーザー (RFC 9114)
DNS/DoQ: DNS over QUIC (RFC 9250) — 0-RTT クエリ
SMB over QUIC: Windows Server 2022
RDP over QUIC: リモートデスクトップの耐パケットロス

参考

  • RFC: 768, 8999-9002, 9000 付録 A (設計思想), 9250
  • 実装⁠: quiche (Cloudflare), lsquic (LiteSpeed), quinn (Rust), ngtcp2 (C)
  • LWN: "QUIC and HTTP/3"

キーワード: UDP, QUIC, 接続の移行, 0-RTT, ストリーム多重化, ヘッド・オブ・ライン・ブロッキング, スピンビット, GREASE