| RFC 9000 | QUICトランスポートプロトコル | 2021年5月 |
| Iyengar & Thomson | 標準化過程 | [ページ] |
本文書は、QUICトランスポートプロトコルの中核を定義する。QUICは、 構造化された通信のためのフロー制御されたストリーム、 低レイテンシの接続確立、およびネットワークパス移行をアプリケーションに提供する。QUICは、 さまざまな展開状況において、機密性、完全性、および可用性を確保する セキュリティ対策を含む。付随する文書では、鍵ネゴシエーション、 損失検出、および例示的な輻輳制御アルゴリズムのためのTLSの統合について説明する。¶
これはインターネット標準化過程の文書である。¶
本文書は、インターネット技術タスクフォース (IETF)の成果物である。これはIETFコミュニティのコンセンサスを表す。本文書は 公開レビューを受けており、インターネット技術運営グループ (IESG)により公開が承認されている。インターネット標準に関する 詳細情報は、RFC 7841の第2節で入手できる。¶
本文書の現在の状態、正誤表、および 本文書へのフィードバック提供方法に関する情報は、 https://www.rfc-editor.org/info/rfc9000で入手できる。¶
Copyright (c) 2021 IETF Trust and the persons identified as the document authors. All rights reserved.¶
This document is subject to BCP 78 and the IETF Trust's Legal Provisions Relating to IETF Documents (https://trustee.ietf.org/license-info) in effect on the date of publication of this document. Please review these documents carefully, as they describe your rights and restrictions with respect to this document. Code Components extracted from this document must include Simplified BSD License text as described in Section 4.e of the Trust Legal Provisions and are provided without warranty as described in the Simplified BSD License.¶
QUICは、安全な汎用トランスポートプロトコルである。本文書はQUICのバージョン1を定義し、 [QUIC-INVARIANTS]で定義されるQUICのバージョン非依存の 特性に適合する。¶
QUICは、クライアントとサーバーの間に状態を持つ相互作用を作成する コネクション指向プロトコルである。¶
QUICハンドシェイクは、暗号パラメーターおよびトランスポート パラメーターのネゴシエーションを組み合わせる。QUICはTLSハンドシェイク [TLS13]を統合するが、 パケットを保護するためにカスタマイズされたフレーミングを用いる。 TLSとQUICの統合については、[QUIC-TLS]で より詳細に説明される。ハンドシェイクは、アプリケーションデータを できるだけ早く交換できるように構成されている。これには、クライアントが 直ちにデータを送信するためのオプション(0-RTT)が含まれるが、これを有効にするには、 何らかの事前の通信または構成が必要である。¶
エンドポイントはQUICパケットを交換することでQUICにおいて通信する。 ほとんどのパケットにはフレームが含まれ、フレームはエンドポイント間で 制御情報およびアプリケーションデータを運ぶ。QUICは各パケット全体を認証し、 実用上可能な限り各パケットを暗号化する。QUICパケットは、既存のシステム およびネットワークでの展開をより容易にするため、UDPデータグラム [UDP]で運ばれる。¶
アプリケーションプロトコルは、順序付けられたバイト列であるストリームを介して、 QUIC接続上で情報を交換する。作成できるストリームには2種類ある。 すなわち、両方のエンドポイントがデータを送信できる双方向ストリームと、 単一のエンドポイントがデータを送信できる単方向ストリームである。 ストリームの作成を制限し、送信可能なデータ量を制限するために、 クレジットベースの方式が使用される。¶
QUICは、信頼性のある配信および輻輳制御を実装するために必要な フィードバックを提供する。データ損失を検出し、そこから回復するための アルゴリズムは、Section 6 of [QUIC-RECOVERY]で説明される。QUICは ネットワーク輻輳を回避するため、輻輳制御に依存する。例示的な輻輳制御 アルゴリズムは、Section 7 of [QUIC-RECOVERY]で説明される。¶
QUIC接続は、厳密には単一のネットワークパスに束縛されない。 接続移行は、接続識別子を用いて、接続を新しいネットワークパスへ 転送できるようにする。このバージョンのQUICでは、クライアントのみが移行できる。 この設計により、NAT再バインディングによって発生しうるものなど、 ネットワークトポロジーまたはアドレスマッピングの変更後も接続を継続できる。¶
確立後は、接続終了のために複数のオプションが提供される。 アプリケーションは正常なシャットダウンを管理でき、エンドポイントは タイムアウト期間をネゴシエーションでき、エラーは即時の接続破棄を引き起こすことができ、 またステートレスな仕組みによって、一方のエンドポイントが状態を失った後の 接続終了が可能になる。¶
本文書は中核となるQUICプロトコルを説明し、次のように構成されている。¶
ストリームは、QUICが提供する基本的なサービス抽象である。¶
接続は、QUICエンドポイントが通信する文脈である。¶
パケットおよびフレームは、QUICが通信に使用する基本単位である。¶
最後に、QUICプロトコル要素の符号化の詳細は、次で説明される。¶
付随する文書では、QUICの損失検出および輻輳制御 [QUIC-RECOVERY]、ならびにTLSおよび その他の暗号メカニズムの使用 [QUIC-TLS]について説明する。¶
本文書は、[QUIC-INVARIANTS]の プロトコル不変条件に適合するQUICバージョン1を定義する。¶
QUICバージョン1を参照するには、本文書を引用する。QUICの限定された バージョン非依存特性の集合への参照には、[QUIC-INVARIANTS]を引用できる。¶
本文書におけるキーワード「MUST」、「MUST NOT」、「REQUIRED」、「SHALL」、 「SHALL NOT」、「SHOULD」、 「SHOULD NOT」、「RECOMMENDED」、「NOT RECOMMENDED」、「MAY」、および「OPTIONAL」は、 ここに示すようにすべて大文字で現れる場合に限り、BCP 14 [RFC2119] [RFC8174]で説明されるとおりに解釈される。¶
本文書で一般に使用される用語を以下に説明する。¶
本文書で説明されるトランスポートプロトコル。QUICは名称であり、 頭字語ではない。¶
QUICパケットを生成、受信、および処理することにより、 QUIC接続に参加できるエンティティ。QUICにおけるエンドポイントの種類は、 クライアントとサーバーの2つのみである。¶
QUIC接続を開始するエンドポイント。¶
QUIC接続を受け入れるエンドポイント。¶
UDPデータグラムにカプセル化できる、完全に処理可能なQUICの単位。 1つ以上のQUICパケットを1つのUDPデータグラムにカプセル化できる。¶
ACK、PADDING、およびCONNECTION_CLOSE以外のフレームを含む QUICパケット。これらは受信者に確認応答を送信させる。 Section 13.2.1を参照。¶
構造化されたプロトコル情報の単位。複数のフレーム種別があり、 それぞれ異なる情報を運ぶ。フレームはQUICパケットに含まれる。¶
限定なしに用いられる場合、ネットワークパスの一端を表す IPバージョン、IPアドレス、およびUDPポート番号のタプル。¶
エンドポイントにおいてQUIC接続を識別するために使用される識別子。 各エンドポイントは、そのエンドポイントへ送信されるパケットにピアが含めるための 1つ以上の接続IDを選択する。この値はピアにとって不透明である。¶
QUIC接続内の、順序付けられたバイトの単方向または双方向チャネル。 QUIC接続は複数の同時ストリームを運ぶことができる。¶
QUICを用いてデータを送受信するエンティティ。¶
本文書では、「QUICパケット」、「UDPデータグラム」、および「IPパケット」 という用語を、それぞれのプロトコルの単位を指すために使用する。すなわち、 1つ以上のQUICパケットをUDPデータグラムにカプセル化でき、そのUDPデータグラムはさらに IPパケットにカプセル化される。¶
本文書のパケットおよびフレーム図は、独自の形式を使用する。 この形式の目的は、プロトコル要素を定義することではなく要約することである。 構造の完全な意味および詳細は本文で定義される。¶
複合フィールドには名前が付けられ、その後に対応する波括弧で囲まれた フィールドのリストが続く。このリスト内の各フィールドはコンマで区切られる。¶
個々のフィールドには、長さ情報に加えて、固定値、任意性、または繰り返しに関する 指示が含まれる。個々のフィールドは次の表記規約を使用し、すべての長さはビット単位である。¶
xがAビット長であることを示す¶
xがSection 16で 説明される可変長符号化を用いて整数値を保持することを示す¶
xがAからBまでの任意の長さを取りうることを示す。Aを省略すると 最小値が0ビットであることを示し、Bを省略すると上限が設定されないことを示す。 この形式の値は常にバイト境界で終わる¶
xが固定値Cを持つことを示す。xの長さは Lによって説明され、Lには上記の任意の長さ形式を使用できる¶
xがCからDまでの範囲の値を持つことを示す。両端を含み、 長さは上記と同様にLによって説明される¶
xが任意であり、長さLを持つことを示す¶
xが0回以上繰り返され、各インスタンスが 長さLを持つことを示す¶
本文書ではネットワークバイト順(すなわちビッグエンディアン)の値を使用する。 フィールドは各バイトの上位ビットから配置される。¶
慣例により、個々のフィールドは複合フィールドの名前を用いて その複合フィールドを参照する。¶
Example Structure {
One-bit Field (1),
7-bit Field with Fixed Value (7) = 61,
Field with Variable-Length Integer (i),
Arbitrary-Length Field (..),
Variable-Length Field (8..24),
Field With Minimum Length (16..),
Field With Maximum Length (..128),
[Optional Field (64)],
Repeated Field (8) ...,
}
本文で単一ビットのフィールドを参照する場合、そのフィールドを運ぶバイトの値を、 そのフィールドの値が設定された状態で用いることにより、フィールドの位置を明確にできる。 たとえば、0x80という値は、Figure 1のOne-bit Fieldのように、 バイトの最上位ビットにある単一ビットフィールドを参照するために使用できる。¶
QUICのストリームは、軽量で順序付けられたバイトストリーム抽象を アプリケーションに提供する。ストリームは単方向または双方向でありうる。¶
ストリームはデータを送信することによって作成できる。ストリーム管理に関連する その他の処理、すなわち終了、キャンセル、およびフロー制御の管理はすべて、 最小限のオーバーヘッドを課すように設計されている。たとえば、1つのSTREAMフレーム (Section 19.8)は、ストリームを開き、データを運び、 閉じることができる。ストリームは長寿命であることもでき、接続の全期間にわたって 存続することもできる。¶
ストリームはどちらのエンドポイントによっても作成でき、他のストリームと 交互に挟まれた形で同時にデータを送信でき、キャンセルすることもできる。QUICは、 異なるストリーム上のバイト間の順序を保証する手段を提供しない。¶
QUICは、フロー制御の制約およびストリーム上限に従う限り、 任意の数のストリームを同時に動作させ、任意の量のデータを任意のストリーム上で 送信することを許可する。Section 4を参照。¶
ストリームは単方向または双方向でありうる。単方向ストリームは、 ストリームの開始者からそのピアへ、一方向にデータを運ぶ。 双方向ストリームは、両方向にデータを送信できるようにする。¶
ストリームは、ストリームIDと呼ばれる数値によって接続内で識別される。 ストリームIDは62ビット整数(0から262-1)であり、 接続上のすべてのストリームに対して一意である。ストリームIDは 可変長整数として符号化される。Section 16を参照。 QUICエンドポイントは、接続内でストリームIDを再使用してはMUST NOTならない。¶
ストリームIDの最下位ビット(0x01)は、ストリームの開始者を識別する。 クライアント開始ストリームは偶数番号のストリームID(ビットが0に設定)を持ち、 サーバー開始ストリームは奇数番号のストリームID(ビットが1に設定)を持つ。¶
ストリームIDの下位から2番目のビット(0x02)は、 双方向ストリーム(ビットが0に設定)と単方向ストリーム(ビットが1に設定)を区別する。¶
したがって、ストリームIDの2つの最下位ビットは、Table 1に 要約される4種類のいずれかとしてストリームを識別する。¶
各種別のストリーム空間は、それぞれ最小値(0x00から0x03)から始まり、 各種別の後続のストリームは、数値的に増加するストリームIDで作成される。 順序を飛ばして使用されたストリームIDは、その種別のより小さい番号を持つ すべてのストリームも開かれたことを意味する。¶
STREAMフレーム(Section 19.8)は、 アプリケーションによって送信されるデータをカプセル化する。 エンドポイントは、STREAMフレーム内のStream IDおよびOffsetフィールドを使用して、 データを順序どおりに配置する。¶
エンドポイントは、ストリームデータを順序付けられた バイトストリームとしてアプリケーションに配信できなければMUSTならない。 順序付けられたバイトストリームを配信するには、エンドポイントが、通知された フロー制御上限まで、順序外で受信されたデータをバッファリングする必要がある。¶
QUICは、ストリームデータを順序外で配信するための特別な許容を 行わない。ただし、実装は、受信側アプリケーションに対してデータを 順序外で配信する機能を提供することを選択してもMAYよい。¶
エンドポイントは、同じストリームオフセットでストリームのデータを 複数回受信することがある。すでに受信されたデータは破棄できる。 指定されたオフセットのデータは、複数回送信されても変更されては MUST NOTならない。エンドポイントは、ストリーム内の同じオフセットで 異なるデータを受信したことを、PROTOCOL_VIOLATION型の接続エラーとして扱っても MAYよい。¶
ストリームは順序付けられたバイトストリーム抽象であり、QUICから見える その他の構造を持たない。STREAMフレームの境界は、データが送信されるとき、 パケット損失後に再送信されるとき、または受信側でアプリケーションに配信されるときに、 保持されることは期待されない。¶
エンドポイントは、ピアによって設定されたフロー制御上限内であることを 確認せずに、どのストリーム上でもデータを送信してはMUST NOTならない。 フロー制御はSection 4で詳細に説明される。¶
ストリーム多重化は、ストリームに割り当てられるリソースが 正しく優先度付けされる場合、アプリケーション性能に大きな影響を与える可能性がある。¶
QUICは、優先度付け情報を交換するための仕組みを提供しない。 代わりに、アプリケーションから優先度情報を受け取ることに依存する。¶
QUIC実装は、アプリケーションがストリームの相対的な優先度を 示すことができる手段を提供するべきSHOULDである。 実装は、アプリケーションによって提供された情報を用いて、アクティブなストリームに リソースをどのように割り当てるかを決定する。¶
本文書はQUICのAPIを定義しない。代わりに、アプリケーションプロトコルが 依存できるストリーム上の一連の機能を定義する。アプリケーションプロトコルは、 QUIC実装が本節で説明される操作を含むインターフェイスを提供すると仮定できる。 特定のアプリケーションプロトコルで使用するために設計された実装は、そのプロトコルが 使用する操作のみを提供してもよい。¶
ストリームの送信部分において、アプリケーションプロトコルは次を行うことができる。¶
ストリームの受信部分において、アプリケーションプロトコルは次を行うことができる。¶
アプリケーションプロトコルは、ピアがストリームを開いたまたはリセットしたとき、 ピアがストリーム上の読み取りを中止したとき、新しいデータが利用可能になったとき、 およびフロー制御によりストリームへデータを書き込めるまたは書き込めないときなど、 ストリーム上の状態変化について通知されるよう要求することもできる。¶
本節では、ストリームをその送信コンポーネントまたは受信コンポーネントの観点から説明する。 2つの状態機械を説明する。1つはエンドポイントがデータを送信するストリーム用 (Section 3.1)であり、もう1つは エンドポイントがデータを受信するストリーム用 (Section 3.2)である。¶
単方向ストリームは、ストリーム種別およびエンドポイントの役割に応じて、 送信または受信の状態機械のいずれかを使用する。双方向ストリームは、 両方のエンドポイントで両方の状態機械を使用する。ほとんどの場合、 これらの状態機械の使用方法は、ストリームが単方向であっても双方向であっても同じである。 双方向ストリームでは、送信側または受信側のいずれかを開くと、 ストリームが両方向で開かれるため、ストリームを開く条件がやや複雑になる。¶
本節で示す状態機械は、大部分が参考情報である。本文書では、 どの種類のフレームをいつどのように送信できるか、および異なる種類のフレームを 受信したときに期待される反応を説明するために、ストリーム状態を使用する。 これらの状態機械はQUICの実装に有用であることを意図しているが、 これらの状態が実装を制約することは意図していない。実装は、 これらの状態を実装した実装と整合するふるまいである限り、 異なる状態機械を定義できる。¶
Figure 2は、 ピアへデータを送信するストリーム部分の状態を示している。¶
o
| Create Stream (Sending)
| Peer Creates Bidirectional Stream
v
+-------+
| Ready | Send RESET_STREAM
| |-----------------------.
+-------+ |
| |
| Send STREAM / |
| STREAM_DATA_BLOCKED |
v |
+-------+ |
| Send | Send RESET_STREAM |
| |---------------------->|
+-------+ |
| |
| Send STREAM + FIN |
v v
+-------+ +-------+
| Data | Send RESET_STREAM | Reset |
| Sent |------------------>| Sent |
+-------+ +-------+
| |
| Recv All ACKs | Recv ACK
v v
+-------+ +-------+
| Data | | Reset |
| Recvd | | Recvd |
+-------+ +-------+
エンドポイントが開始するストリーム(クライアントでは種別0および2、 サーバーでは種別1および3)の送信部分は、アプリケーションによって開かれる。 "Ready"状態は、アプリケーションからデータを受け入れることができる新しく作成された ストリームを表す。この状態では、送信に備えてストリームデータがバッファされることがある。¶
最初のSTREAMフレームまたはSTREAM_DATA_BLOCKEDフレームを送信すると、 ストリームの送信部分は"Send"状態に入る。実装は、最初のSTREAMフレームを送信して この状態に入るまで、ストリームへのストリームIDの割り当てを遅延することを選択してもよい。 これにより、よりよいストリーム優先度付けが可能になることがある。¶
ピアによって開始された双方向ストリーム(サーバーでは種別0、 クライアントでは種別1)の送信部分は、受信部分が作成されたときに "Ready"状態から始まる。¶
"Send"状態では、エンドポイントはSTREAMフレームでストリームデータを送信し、 必要に応じて再送信する。エンドポイントはピアによって設定されたフロー制御上限を尊重し、 MAX_STREAM_DATAフレームを引き続き受け入れて処理する。"Send"状態にある エンドポイントは、ストリームフロー制御上限(Section 4.1)によって送信がブロックされている場合、 STREAM_DATA_BLOCKEDフレームを生成する。¶
アプリケーションがすべてのストリームデータの送信を示し、 FINビットを含むSTREAMフレームが送信されると、ストリームの送信部分は "Data Sent"状態に入る。この状態から、エンドポイントは必要に応じて ストリームデータを再送信するだけである。この状態のストリームについて、 エンドポイントはフロー制御上限を確認する必要がなく、STREAM_DATA_BLOCKEDフレームを 送信する必要もない。MAX_STREAM_DATAフレームは、ピアが最終ストリームオフセットを 受信するまで受信される可能性がある。エンドポイントは、この状態のストリームについて ピアから受信したMAX_STREAM_DATAフレームを安全に無視できる。¶
すべてのストリームデータが正常に確認応答されると、ストリームの送信部分は 終端状態である"Data Recvd"状態に入る。¶
"Ready"、"Send"、または"Data Sent"のいずれかの状態から、 アプリケーションはストリームデータの送信を放棄したいことを通知できる。 あるいは、エンドポイントがピアからSTOP_SENDINGフレームを受信することもある。 いずれの場合も、エンドポイントはRESET_STREAMフレームを送信し、これにより ストリームは"Reset Sent"状態に入る。¶
エンドポイントは、ストリームに言及する最初のフレームとして RESET_STREAMを送信してもよい(MAY)。 これにより、そのストリームの送信部分が開かれ、直ちに "Reset Sent"状態へ遷移する。¶
RESET_STREAMを含むパケットが確認応答されると、ストリームの送信部分は 終端状態である"Reset Recvd"状態に入る。¶
Figure 3は、 ピアからデータを受信するストリーム部分の状態を示している。 ストリームの受信部分の状態は、ピアにおけるストリームの送信部分の状態の一部のみを 反映する。ストリームの受信部分は、"Ready"状態など、観測できない送信部分の状態を 追跡しない。その代わり、ストリームの受信部分は、アプリケーションへの データ配信を追跡する。その一部は送信者から観測できない。¶
o
| Recv STREAM / STREAM_DATA_BLOCKED / RESET_STREAM
| Create Bidirectional Stream (Sending)
| Recv MAX_STREAM_DATA / STOP_SENDING (Bidirectional)
| Create Higher-Numbered Stream
v
+-------+
| Recv | Recv RESET_STREAM
| |-----------------------.
+-------+ |
| |
| Recv STREAM + FIN |
v |
+-------+ |
| Size | Recv RESET_STREAM |
| Known |---------------------->|
+-------+ |
| |
| Recv All Data |
v v
+-------+ Recv RESET_STREAM +-------+
| Data |--- (optional) --->| Reset |
| Recvd | Recv All Data | Recvd |
+-------+<-- (optional) ----+-------+
| |
| App Read All Data | App Read Reset
v v
+-------+ +-------+
| Data | | Reset |
| Read | | Read |
+-------+ +-------+
ピアによって開始されたストリーム(クライアントでは種別1および3、 サーバーでは種別0および2)の受信部分は、そのストリームについて最初の STREAM、STREAM_DATA_BLOCKED、またはRESET_STREAMフレームが受信されたときに作成される。 ピアによって開始された双方向ストリームでは、そのストリームの送信部分に対する MAX_STREAM_DATAまたはSTOP_SENDINGフレームの受信も受信部分を作成する。 ストリームの受信部分の初期状態は"Recv"である。¶
双方向ストリームでは、エンドポイントによって開始された送信部分 (クライアントでは種別0、サーバーでは種別1)が"Ready"状態に入ると、 受信部分は"Recv"状態に入る。¶
エンドポイントは、そのストリームについてピアからMAX_STREAM_DATAまたは STOP_SENDINGフレームを受信したとき、双方向ストリームを開く。 未開のストリームに対するMAX_STREAM_DATAフレームの受信は、リモートピアが ストリームを開き、フロー制御クレジットを提供していることを示す。 未開のストリームに対するSTOP_SENDINGフレームの受信は、リモートピアが そのストリーム上でデータを受信することをもはや望んでいないことを示す。 パケットが失われる、または並べ替えられる場合、いずれのフレームも STREAMまたはSTREAM_DATA_BLOCKEDフレームより前に到着する可能性がある。¶
ストリームが作成される前に、同じ種別でより小さい番号のストリームIDを持つ すべてのストリームが作成されなければならない(MUST)。 これにより、ストリームの作成順序が両方のエンドポイントで一貫することが保証される。¶
"Recv"状態では、エンドポイントはSTREAMフレームおよび STREAM_DATA_BLOCKEDフレームを受信する。到着したデータはバッファされ、 アプリケーションへ配信するために正しい順序へ再構成できる。アプリケーションが データを消費し、バッファ空間が利用可能になると、エンドポイントは ピアがより多くのデータを送信できるようにMAX_STREAM_DATAフレームを送信する。¶
FINビットを持つSTREAMフレームを受信すると、ストリームの最終サイズが 判明する。Section 4.5を参照。 その後、ストリームの受信部分は"Size Known"状態に入る。この状態では、 エンドポイントはMAX_STREAM_DATAフレームを送信する必要がなくなり、 ストリームデータの再送信だけを受信する。¶
ストリームのすべてのデータが受信されると、受信部分は"Data Recvd"状態に入る。 これは、"Size Known"への遷移を引き起こす同じSTREAMフレームの受信の結果として 発生することもある。すべてのデータが受信された後、そのストリームの STREAMフレームまたはSTREAM_DATA_BLOCKEDフレームは破棄できる。¶
"Data Recvd"状態は、ストリームデータがアプリケーションへ配信されるまで 継続する。ストリームデータが配信されると、ストリームは終端状態である "Data Read"状態に入る。¶
"Recv"または"Size Known"状態でRESET_STREAMフレームを受信すると、 ストリームは"Reset Recvd"状態に入る。これにより、アプリケーションへの ストリームデータの配信が中断されることがある。¶
RESET_STREAMが受信された時点で、すべてのストリームデータがすでに 受信されている可能性がある(すなわち、"Data Recvd"状態)。 同様に、RESET_STREAMフレームを受信した後("Reset Recvd"状態)に、 残りのストリームデータが到着する可能性もある。実装は、この状況を 任意の方法で管理してよい。¶
RESET_STREAMを送信することは、エンドポイントがストリームデータの配信を 保証できないことを意味する。ただし、RESET_STREAMを受信した場合に ストリームデータを配信してはならないという要件はない。実装は、 ストリームデータの配信を中断し、消費されなかったデータを破棄し、 RESET_STREAMの受信を通知してもよい(MAY)。 ストリームデータが完全に受信され、アプリケーションによって読み取られるよう バッファされている場合、RESET_STREAM信号は抑制または保留されることがある。 RESET_STREAMが抑制された場合、ストリームの受信部分は"Data Recvd"に留まる。¶
ストリームがリセットされたことを示す信号をアプリケーションが受信すると、 ストリームの受信部分は終端状態である"Reset Read"状態へ遷移する。¶
ストリームの送信者は、送信者または受信者のいずれかで ストリームの状態に影響する3種類のフレームのみを送信する。STREAM (Section 19.8)、 STREAM_DATA_BLOCKED(Section 19.13)、 およびRESET_STREAM (Section 19.4)である。¶
送信者は、終端状態("Data Recvd"または"Reset Recvd")から これらのフレームを送信してはならない(MUST NOT)。 送信者は、RESET_STREAMフレームを送信した後、すなわち"Reset Sent"状態または 任意の終端状態にあるストリームについて、STREAMフレームまたは STREAM_DATA_BLOCKEDフレームを送信してはならない(MUST NOT)。 受信者は、これらを運ぶパケットの遅延配信の可能性があるため、 任意の状態でこれら3種類のフレームのいずれも受信する可能性がある。¶
ストリームの受信者は、MAX_STREAM_DATAフレーム (Section 19.10)およびSTOP_SENDINGフレーム (Section 19.5)を送信する。¶
受信者は"Recv"状態でのみMAX_STREAM_DATAフレームを送信する。 受信者は、RESET_STREAMフレームを受信していない任意の状態、すなわち "Reset Recvd"または"Reset Read"以外の状態で、STOP_SENDINGフレームを 送信してもよい(MAY)。ただし、"Data Recvd"状態では すべてのストリームデータが受信されているため、STOP_SENDINGフレームを送信する 価値はほとんどない。送信者は、パケットの遅延配信の結果として、 これら2種類のフレームのいずれも任意の状態で受信する可能性がある。¶
双方向ストリームは、送信部分と受信部分で構成される。 実装は、双方向ストリームの状態を、送信ストリーム状態と受信ストリーム状態の 合成として表現できる。最も単純なモデルでは、送信部分または受信部分の いずれかが非終端状態にあるときにストリームを"open"と表し、 送信ストリームと受信ストリームの両方が終端状態にあるときに "closed"と表す。¶
Table 2は、 HTTP/2 [HTTP2]で定義される ストリーム状態に概ね対応する、より複雑な双方向ストリーム状態の対応付けを示している。 これは、ストリームの送信部分または受信部分の複数の状態が、同じ合成状態へ 対応付けられることを示している。これはそのような対応付けの1つの可能性にすぎないことに 注意すること。この対応付けでは、"closed"または"half-closed"状態への遷移前に データが確認応答されることが要求される。¶
| 送信部分 | 受信部分 | 合成状態 |
|---|---|---|
| No Stream / Ready | No Stream / Recv (*1) | idle |
| Ready / Send / Data Sent | Recv / Size Known | open |
| Ready / Send / Data Sent | Data Recvd / Data Read | half-closed (remote) |
| Ready / Send / Data Sent | Reset Recvd / Reset Read | half-closed (remote) |
| Data Recvd | Recv / Size Known | half-closed (local) |
| Reset Sent / Reset Recvd | Recv / Size Known | half-closed (local) |
| Reset Sent / Reset Recvd | Data Recvd / Data Read | closed |
| Reset Sent / Reset Recvd | Reset Recvd / Reset Read | closed |
| Data Recvd | Data Recvd / Data Read | closed |
| Data Recvd | Reset Recvd / Reset Read | closed |
アプリケーションがストリーム上で受信しているデータにもはや関心がない場合、 ストリームの読み取りを中止し、アプリケーションエラーコードを指定できる。¶
ストリームが"Recv"または"Size Known"状態にある場合、トランスポートは STOP_SENDINGフレームを送信して、反対方向のストリームのクローズを促すことで、 これを通知するべきである(SHOULD)。 これは通常、受信側アプリケーションがそのストリームから受信するデータを もはや読み取っていないことを示すが、到着するデータが無視されることを保証するものではない。¶
STOP_SENDINGフレームを送信した後に受信されたSTREAMフレームは、 受信時に破棄できるにもかかわらず、接続およびストリームのフロー制御に 引き続き計上される。¶
STOP_SENDINGフレームは、受信側エンドポイントにRESET_STREAMフレームの 送信を要求する。STOP_SENDINGフレームを受信したエンドポイントは、ストリームが "Ready"または"Send"状態にある場合、RESET_STREAMフレームを送信しなければならない (MUST)。ストリームが"Data Sent"状態にある場合、 エンドポイントは、未処理データを含むパケットが確認応答されるか損失と宣言されるまで、 RESET_STREAMフレームの送信を遅延してもよい(MAY)。 未処理データのいずれかが損失と宣言された場合、エンドポイントはデータを再送信する代わりに RESET_STREAMフレームを送信するべきである(SHOULD)。¶
エンドポイントは、STOP_SENDINGフレームからエラーコードをコピーして、 送信するRESET_STREAMフレームに設定するべきである(SHOULD)が、 任意のアプリケーションエラーコードを使用できる。STOP_SENDINGフレームを送信した エンドポイントは、そのストリームについて後続で受信したRESET_STREAMフレーム内の エラーコードを無視してもよい(MAY)。¶
STOP_SENDINGは、ピアによってリセットされていないストリームに対してのみ 送信されるべきである(SHOULD)。 STOP_SENDINGは、"Recv"または"Size Known"状態のストリームに対して最も有用である。¶
以前のSTOP_SENDINGを含むパケットが失われた場合、エンドポイントは 別のSTOP_SENDINGフレームを送信することが期待される。ただし、そのストリームについて すべてのストリームデータまたはRESET_STREAMフレームのいずれかを受信した後、 すなわちストリームが"Recv"または"Size Known"以外の任意の状態にある場合、 STOP_SENDINGフレームの送信は不要である。¶
双方向ストリームの両方向を終了したいエンドポイントは、 RESET_STREAMフレームを送信して一方向を終了し、STOP_SENDINGフレームを送信して 反対方向の迅速な終了を促すことができる。¶
受信者は、高速な送信者に圧倒されたり、悪意ある送信者によって 大量のメモリを消費されたりすることを防ぐため、バッファを要求されるデータ量を 制限する必要がある。受信者が接続のメモリコミットメントを制限できるようにするため、 ストリームは個別にも接続全体にわたってもフロー制御される。 QUIC受信者は、Sections 4.1および4.2で説明されるように、送信者がストリーム上で送信できる 最大データ量と、任意の時点で全ストリームにわたって送信できる最大データ量を制御する。¶
同様に、接続内の並行性を制限するため、QUICエンドポイントは ピアが開始できるストリームの累積最大数を制御する。 Section 4.6で説明する。¶
CRYPTOフレームで送信されるデータは、ストリームデータと同じ方法では フロー制御されない。QUICは、データの過剰なバッファリングを避けるために 暗号プロトコル実装に依存する。[QUIC-TLS]を参照。 複数の層での過剰なバッファリングを避けるため、QUIC実装は、暗号プロトコル実装が そのバッファリング上限を通知するためのインターフェイスを提供するべきである (SHOULD)。¶
QUICは、受信者が特定のストリームまたは接続全体で受信する準備がある 総バイト数の上限を通知する、上限ベースのフロー制御方式を採用する。 これにより、QUICでは2段階のデータフロー制御が行われる。¶
送信者は、いずれの上限も超えてデータを送信してはならない (MUST NOT)。¶
受信者は、ハンドシェイク中にトランスポートパラメーター (Section 7.4)を通じて、 すべてのストリームに初期上限を設定する。その後、受信者はより大きな上限を通知するために、 MAX_STREAM_DATAフレーム(Section 19.10) またはMAX_DATAフレーム (Section 19.9)を送信者へ送信する。¶
受信者は、対応するストリームIDを持つMAX_STREAM_DATAフレームを送信することで、 ストリームのより大きな上限を通知できる。MAX_STREAM_DATAフレームは、 ストリームの最大絶対バイトオフセットを示す。受信者は、そのストリームで消費された データの現在のオフセットに基づいて、通知すべきフロー制御オフセットを 決定することができる。¶
受信者は、すべてのストリームの絶対バイトオフセットの合計の最大値を示す MAX_DATAフレームを送信することで、接続のより大きな上限を通知できる。 受信者は、すべてのストリームで受信したバイトの累積合計を維持し、 これを使用して、通知済みの接続またはストリームデータ上限への違反を確認する。 受信者は、すべてのストリームで消費されたバイトの合計に基づいて、 通知すべき最大データ上限を決定することができる。¶
受信者が接続またはストリームの上限を通知した後、 より小さい上限を通知してもエラーではないが、そのより小さい上限は効果を持たない。¶
送信者が通知済みの接続またはストリームデータ上限に違反した場合、 受信者はFLOW_CONTROL_ERROR型のエラーで接続を閉じなければならない (MUST)。エラー処理の詳細については Section 11を参照。¶
送信者は、フロー制御上限を増加させないMAX_STREAM_DATAまたは MAX_DATAフレームを無視しなければならない(MUST)。¶
送信者が上限までデータを送信した場合、新しいデータを送信できず、 ブロックされていると見なされる。送信者は、書き込むデータはあるが フロー制御上限によってブロックされていることを受信者に示すため、 STREAM_DATA_BLOCKEDまたはDATA_BLOCKEDフレームを送信するべきである (SHOULD)。送信者がアイドルタイムアウト (Section 10.1)より長い期間ブロックされると、 送信可能なデータが送信者にある場合でも、受信者は接続を閉じる可能性がある。 接続が閉じられないようにするため、フロー制御によって制限されている送信者は、 飛行中のACKを誘発するパケットがない場合、STREAM_DATA_BLOCKEDまたは DATA_BLOCKEDフレームを定期的に送信するべきである(SHOULD)。¶
実装は、MAX_STREAM_DATAフレームおよびMAX_DATAフレームで いつ、どれだけのクレジットを通知するかを決定するが、本節ではいくつかの考慮事項を示す。¶
送信者のブロックを避けるため、受信者は、1往復時間内に MAX_STREAM_DATAまたはMAX_DATAフレームを複数回送信してもよく (MAY)、またはそのフレームの損失とその後の回復に時間を 許すため、十分早く送信してもよい。¶
制御フレームは接続のオーバーヘッドに寄与する。したがって、 小さな変更でMAX_STREAM_DATAおよびMAX_DATAフレームを頻繁に送信することは望ましくない。 一方、更新頻度が低い場合、送信者のブロックを避けるために上限をより大きく増加させる 必要があり、受信者でより大きなリソースコミットメントが必要になる。 通知される上限の大きさを決定する際には、リソースコミットメントとオーバーヘッドの 間にトレードオフがある。¶
受信者は、自動調整機構を使用して、往復時間の推定値と 受信側アプリケーションがデータを消費する速度に基づき、通知する追加クレジットの 頻度と量を調整できる。これは一般的なTCP実装と同様である。 最適化として、エンドポイントは、送信する他のフレームがある場合にのみ フロー制御に関連するフレームを送信し、フロー制御が余分なパケットを 送信させないようにすることができる。¶
ブロックされた送信者は、STREAM_DATA_BLOCKEDまたはDATA_BLOCKEDフレームを 送信することを要求されない。したがって、受信者は、MAX_STREAM_DATAまたは MAX_DATAフレームを送信する前に、STREAM_DATA_BLOCKEDまたはDATA_BLOCKEDフレームを 待ってはならない(MUST NOT)。そうすると、 送信者が接続の残りの期間ブロックされる可能性がある。送信者がこれらのフレームを 送信したとしても、それらを待つと、送信者は少なくとも1往復時間全体にわたって ブロックされることになる。¶
送信者がブロックされた後にクレジットを受け取ると、 応答として大量のデータを送信できる可能性があり、短期的な輻輳を引き起こす。 送信者がこの輻輳をどのように回避できるかについては、 Section 7.7 of [QUIC-RECOVERY]を参照。¶
エンドポイントが、この接続でピアの帯域幅遅延積を超える利用可能な フロー制御クレジットをピアが常に持つことを保証できない場合、 その受信スループットはフロー制御によって制限される。¶
パケット損失は受信バッファに欠損を生じさせ、アプリケーションがデータを 消費して受信バッファ空間を解放することを妨げる可能性がある。¶
フロー制御上限を適時に更新して送信することは、性能を向上させる可能性がある。 フロー制御更新を提供するためだけにパケットを送信すると、ネットワーク負荷が増加し、 性能に悪影響を及ぼす可能性がある。ACKフレームなど他のフレームとともに フロー制御更新を送信すると、それらの更新のコストが低減される。¶
エンドポイントは、接続レベルのフロー制御ですべてのバイトを 計上できるようにするため、各ストリームで消費されたフロー制御クレジットの量について 最終的に合意する必要がある。¶
RESET_STREAMフレームを受信すると、エンドポイントは対応するストリームの 状態を破棄し、そのストリームに到着する以後のデータを無視する。¶
RESET_STREAMは、ストリームの一方向を突然終了する。双方向ストリームでは、 RESET_STREAMは反対方向のデータフローに影響を与えない。両方のエンドポイントは、 終了していない方向が終端状態に入るまで、その方向のストリームのフロー制御状態を 維持しなければならない(MUST)。¶
最終サイズとは、ストリームによって消費されるフロー制御クレジットの量である。 ストリーム上のすべての連続したバイトが一度だけ送信されたと仮定すると、 最終サイズは送信されたバイト数である。より一般には、これはストリーム上で送信された 最大オフセットを持つバイトのオフセットに1を加えた値、またはバイトが送信されていない場合は 0である。¶
送信者は、ストリームがどのように終了しても、ストリームの最終サイズを 受信者に確実に伝達する。最終サイズは、FINフラグを持つSTREAMフレームの OffsetフィールドとLengthフィールドの合計である。ただし、これらのフィールドは暗黙である 場合がある。あるいは、RESET_STREAMフレームのFinal Sizeフィールドがこの値を運ぶ。 これにより、そのストリームで送信者によって消費されたフロー制御クレジット量について、 両方のエンドポイントが合意することが保証される。¶
ストリームの受信部分が"Size Known"または"Reset Recvd"状態 (Section 3)に入ると、 エンドポイントはそのストリームの最終サイズを知る。受信者は、接続レベルの フロー制御機構で、そのストリーム上で送信されたすべてのバイトを計上するために、 ストリームの最終サイズを使用しなければならない(MUST)。¶
エンドポイントは、最終サイズ以降の位置でストリームにデータを送信してはならない (MUST NOT)。¶
ストリームの最終サイズが判明すると、それを変更することはできない。 ストリームの最終サイズの変更を示すRESET_STREAMまたはSTREAMフレームを受信した場合、 エンドポイントはFINAL_SIZE_ERROR型のエラーで応答するべきである (SHOULD)。エラー処理の詳細については Section 11を参照。受信者は、ストリームが閉じられた後であっても、 最終サイズ以降のデータの受信をFINAL_SIZE_ERROR型のエラーとして扱うべきである (SHOULD)。これらのエラーの生成は必須ではない。 なぜなら、エンドポイントにこれらのエラーの生成を要求することは、 閉じられたストリームについて最終サイズの状態を維持する必要があることも意味し、 それは大きな状態コミットメントになりうるためである。¶
エンドポイントは、ピアが開くことができる受信ストリームの累積数を制限する。
(max_streams * 4 +
first_stream_id_of_type)未満のストリームIDを持つストリームのみを開くことができる。
Table 1を参照。初期上限は
トランスポートパラメーターで設定される。
Section 18.2を参照。
後続の上限はMAX_STREAMSフレームを用いて通知される。
Section 19.11を参照。
単方向ストリームと双方向ストリームには別々の上限が適用される。¶
max_streamsトランスポートパラメーターまたはMAX_STREAMSフレームが 260より大きい値で受信された場合、可変長整数として表現できない 最大ストリームIDを許可することになる。Section 16を参照。いずれかが受信された場合、問題の値が トランスポートパラメーターで受信されたならTRANSPORT_PARAMETER_ERROR型の接続エラーで、 フレームで受信されたならFRAME_ENCODING_ERROR型の接続エラーで、 接続は直ちに閉じられなければならない(MUST)。 Section 10.2を参照。¶
エンドポイントは、ピアによって設定された上限を超えてはならない (MUST NOT)。送信した上限を超えるストリームIDを持つフレームを 受信したエンドポイントは、これをSTREAM_LIMIT_ERROR型の接続エラーとして扱わなければならない (MUST)。エラー処理の詳細については Section 11を参照。¶
受信者がMAX_STREAMSフレームを用いてストリーム上限を通知した後、 より小さい上限を通知しても効果はない。ストリーム上限を増加させない MAX_STREAMSフレームは無視されなければならない(MUST)。¶
ストリームおよび接続のフロー制御と同様に、本文書は、 MAX_STREAMSを通じていつ、いくつのストリームをピアへ通知するかを 実装の判断に委ねる。実装は、ピアに利用可能なストリーム数をおおむね一定に保つため、 ストリームが閉じられるにつれて上限を増加させることを選択してもよい。¶
ピアの上限のために新しいストリームを開くことができないエンドポイントは、 STREAMS_BLOCKEDフレーム(Section 19.14)を 送信するべきである(SHOULD)。この信号はデバッグに有用と見なされる。 エンドポイントは、追加クレジットを通知する前にこの信号の受信を待ってはならない (MUST NOT)。そうすると、ピアが少なくとも1往復時間全体にわたって ブロックされ、さらにピアがSTREAMS_BLOCKEDフレームを送信しないことを選択した場合には、 無期限にブロックされる可能性がある。¶
QUIC接続は、クライアントとサーバーの間で共有される状態である。¶
各接続はハンドシェイク段階で開始される。この段階で、2つのエンドポイントは 暗号ハンドシェイクプロトコル [QUIC-TLS]を用いて共有秘密を確立し、 アプリケーションプロトコルをネゴシエーションする。ハンドシェイク (Section 7)は、両方のエンドポイントが通信する意思があること (Section 8.1)を確認し、接続のパラメーター (Section 7.4)を確立する。¶
アプリケーションプロトコルは、いくつかの制限付きでハンドシェイク段階中に 接続を使用できる。0-RTTにより、クライアントはサーバーから応答を受信する前に アプリケーションデータを送信できる。ただし、0-RTTはリプレイ攻撃に対する保護を提供しない。 Section 9.2 of [QUIC-TLS]を参照。 サーバーは、クライアントの身元と生存性を確認できる最終的な暗号ハンドシェイクメッセージを 受信する前に、アプリケーションデータをクライアントへ送信することもできる。 これらの機能により、アプリケーションプロトコルは、セキュリティ保証の一部と レイテンシ削減を交換するオプションを提供できる。¶
接続ID(Section 5.1)の使用により、 エンドポイントの直接的な選択としても、ミドルボックスの変更によって強制される場合にも、 接続を新しいネットワークパスへ移行できる。Section 9では、 移行に関連するセキュリティおよびプライバシー上の問題に対する軽減策を説明する。¶
もはや必要でない、または望まれない接続については、 Section 10で説明されるように、 クライアントとサーバーが接続を終了する方法が複数ある。¶
各接続は、接続を識別できる接続識別子、すなわち接続IDの集合を持つ。 接続IDはエンドポイントによって独立に選択される。各エンドポイントは、 そのピアが使用する接続IDを選択する。¶
接続IDの主な機能は、下位プロトコル層(UDP、IP)でのアドレス指定の変更によって、 QUIC接続のパケットが誤ったエンドポイントへ配信されないようにすることである。 各エンドポイントは、実装固有(場合によっては展開固有)の方法を用いて 接続IDを選択する。この方法により、その接続IDを持つパケットがエンドポイントへ 経路付けされ、受信時にエンドポイントによって識別される。¶
複数の接続IDが使用されるのは、エンドポイントの協力なしに、 オブザーバーが同じ接続のパケットであると識別できないようにするためである。 Section 9.5を参照。¶
接続IDは、外部のオブザーバー(すなわち発行者と協力しない者)が、 同じ接続の他の接続IDと相関付けるために使用できる情報を含んではならない (MUST NOT)。単純な例として、これは同じ接続IDを 同じ接続上で複数回発行してはならない(MUST NOT)ことを意味する。¶
ロングヘッダーを持つパケットには、Source Connection IDフィールドおよび Destination Connection IDフィールドが含まれる。これらのフィールドは、 新しい接続の接続IDを設定するために使用される。詳細は Section 7.2を参照。¶
ショートヘッダーを持つパケット(Section 17.3)は、Destination Connection IDのみを含み、明示的な長さを省略する。 Destination Connection IDフィールドの長さは、エンドポイントに既知であることが期待される。 接続IDに基づいて経路付けするロードバランサーを使用するエンドポイントは、 接続IDの固定長についてロードバランサーと合意するか、符号化方式について合意できる。 固定部分が明示的な長さを符号化してもよく、これにより接続ID全体が長さを変えながらも ロードバランサーによって使用できる。¶
Version Negotiation(Section 17.2.1)パケットは、クライアントによって選択された接続IDをエコーする。 これは、クライアントへの正しい経路付けを保証し、そのパケットがクライアントによって 送信されたパケットへの応答であることを示すためである。¶
正しいエンドポイントへ経路付けするために接続IDが不要な場合、 長さ0の接続IDを使用できる。ただし、長さ0の接続IDを使用しながら同じローカルIPアドレスと ポートで接続を多重化すると、ピア接続移行、NAT再バインディング、および クライアントポート再使用が存在する場合に失敗を引き起こす。エンドポイントは、 これらのプロトコル機能が使用されていないことが確実でない限り、 長さ0の接続IDを持つ複数の同時接続に対して同じIPアドレスとポートを 使用してはならない(MUST NOT)。¶
エンドポイントが非ゼロ長の接続IDを使用する場合、エンドポイントへ送信される パケットについて、ピアが選択できる接続IDの供給を持つことを保証する必要がある。 これらの接続IDは、NEW_CONNECTION_IDフレーム (Section 19.15)を用いて エンドポイントによって提供される。¶
各接続IDには、NEW_CONNECTION_IDまたはRETIRE_CONNECTION_IDフレームが 同じ値を参照しているかを検出するのに役立つ関連シーケンス番号がある。 エンドポイントによって発行される初期接続IDは、ハンドシェイク中に ロングパケットヘッダー(Section 17.2)の Source Connection IDフィールドで送信される。初期接続IDのシーケンス番号は0である。 preferred_addressトランスポートパラメーターが送信される場合、 提供される接続IDのシーケンス番号は1である。¶
追加の接続IDは、NEW_CONNECTION_IDフレーム (Section 19.15)を用いて ピアへ通知される。新しく発行される各接続IDのシーケンス番号は 1ずつ増加しなければならない(MUST)。 クライアントが最初に送信するDestination Connection IDフィールドのために 選択する接続ID、およびRetryパケットによって提供される接続IDには、 シーケンス番号は割り当てられない。¶
エンドポイントが接続IDを発行した場合、その接続IDを運ぶパケットを、 接続の期間中、またはピアがRETIRE_CONNECTION_IDフレーム (Section 19.16)によって その接続IDを無効化するまで、受け入れなければならない(MUST)。発行され、廃止されていない接続IDは アクティブと見なされる。任意のアクティブな接続IDは、現在の接続で任意の時点、 任意のパケット種別において使用できる。これには、preferred_address トランスポートパラメーターを介してサーバーによって発行される接続IDも含まれる。¶
エンドポイントは、そのピアが利用可能で未使用の接続IDを十分な数だけ 持つことを保証するべきである(SHOULD)。 エンドポイントは、active_connection_id_limitトランスポートパラメーターを用いて、 維持する意思のあるアクティブな接続IDの数を通知する。エンドポイントは、 ピアの上限を超える数の接続IDを提供してはならない(MUST NOT)。 NEW_CONNECTION_IDフレームがRetire Prior Toフィールドに十分大きな値を含めることによって 超過分の廃止も要求する場合、エンドポイントはピアの上限を一時的に超える 接続IDを送信してもよい(MAY)。¶
NEW_CONNECTION_IDフレームにより、エンドポイントはRetire Prior Toフィールドの 値に基づいて、一部のアクティブな接続IDを追加し、他を廃止することがある。 NEW_CONNECTION_IDフレームを処理し、アクティブな接続IDの追加と廃止を行った後、 アクティブな接続IDの数がactive_connection_id_limitトランスポートパラメーターで 通知した値を超える場合、エンドポイントはCONNECTION_ID_LIMIT_ERROR型のエラーで 接続を閉じなければならない(MUST)。¶
エンドポイントは、ピアが接続IDを廃止したとき、新しい接続IDを 提供するべきである(SHOULD)。エンドポイントが ピアのactive_connection_id_limitより少ない接続IDを提供していた場合、 以前に使用されていない接続IDを持つパケットを受信したときに、新しい接続IDを 提供してもよい(MAY)。エンドポイントは、接続IDが枯渇する リスクを避けるため、各接続に対して発行される接続IDの総数を制限してもよい (MAY)。Section 10.3.2を参照。また、ピアが発行された接続IDの数だけ多くの パスで相互作用する可能性があるため、パス検証状態など、維持するパスごとの状態量を 減らすために、接続IDの発行を制限してもよい(MAY)。¶
移行を開始し、非ゼロ長の接続IDを必要とするエンドポイントは、 ピアに利用可能な接続IDのプールにより、移行時にピアが新しい接続IDを 使用できることを保証するべきである(SHOULD)。 プールが枯渇している場合、ピアは応答できないためである。¶
ハンドシェイク中に長さ0の接続IDを選択したエンドポイントは、 新しい接続IDを発行できない。そのようなエンドポイントへ任意のネットワークパス上で 送信されるすべてのパケットでは、長さ0のDestination Connection IDフィールドが使用される。¶
エンドポイントは、接続中の任意の時点で、ピアに対して使用する接続IDを 別の利用可能な接続IDへ変更できる。エンドポイントは、移行するピアに応答して 接続IDを使用する。詳細はSection 9.5を参照。¶
エンドポイントは、ピアから受信した接続IDの集合を維持し、 パケット送信時にそのいずれかを使用できる。エンドポイントが接続IDを 使用から除外したい場合、RETIRE_CONNECTION_IDフレームをピアへ送信する。 RETIRE_CONNECTION_IDフレームの送信は、その接続IDが再び使用されないことを示し、 NEW_CONNECTION_IDフレームを用いて新しい接続IDに置き換えるようピアへ要求する。¶
Section 9.5で説明されるように、エンドポイントは 接続IDの使用を、単一のローカルアドレスから単一の宛先アドレスへ送信される パケットに制限する。エンドポイントは、接続IDが使用されたローカルアドレスまたは 宛先アドレスのいずれかをもはや積極的に使用していない場合、 接続IDを廃止するべきである(SHOULD)。¶
エンドポイントは、特定の状況で、以前に発行した接続IDの受け入れを 停止する必要があるかもしれない。そのようなエンドポイントは、Retire Prior Toフィールドを 増加させたNEW_CONNECTION_IDフレームを送信することで、ピアに接続IDを 廃止させることができる。エンドポイントは、以前に発行した接続IDがピアによって 廃止されるまで、それらを引き続き受け入れるべきである (SHOULD)。エンドポイントが示された接続IDをもはや 処理できない場合、接続を閉じてもよい(MAY)。¶
増加したRetire Prior Toフィールドを受信したピアは、 対応する接続IDの使用を停止し、提供された新しい接続IDをアクティブな 接続IDの集合に追加する前に、RETIRE_CONNECTION_IDフレームでそれらを廃止しなければならない (MUST)。この順序により、エンドポイントは、ピアが利用可能な 接続IDを持たなくなる可能性や、ピアがactive_connection_id_limit トランスポートパラメーターで設定した上限を超える可能性なしに、すべての アクティブな接続IDを置き換えることができる。 Section 18.2を参照。 要求されたときに接続IDの使用を停止しないと、発行側エンドポイントが アクティブな接続で接続IDを引き続き使用できなくなる可能性があるため、 接続失敗につながることがある。¶
エンドポイントは、ローカルで廃止したがRETIRE_CONNECTION_IDフレームが まだ確認応答されていない接続IDの数を制限するべきである (SHOULD)。エンドポイントは、 active_connection_id_limitトランスポートパラメーターの値の少なくとも2倍の数の RETIRE_CONNECTION_IDフレームを送信し追跡できるようにするべきである (SHOULD)。エンドポイントは、接続IDを廃止せずに 忘れてはならない(MUST NOT)が、 この上限を超える廃止が必要な接続IDを持つことを CONNECTION_ID_LIMIT_ERROR型の接続エラーとして扱うことを選択してもよい (MAY)。¶
エンドポイントは、以前のRetire Prior To値によって示された すべての接続IDを廃止するRETIRE_CONNECTION_IDフレームを受信する前に、 Retire Prior Toフィールドの更新を発行するべきではない (SHOULD NOT)。¶
到着パケットは受信時に分類される。パケットは既存の接続に関連付けられるか、 サーバーの場合は新しい接続を作成する可能性がある。¶
エンドポイントは、パケットを既存の接続に関連付けようとする。 パケットが既存の接続に対応する非ゼロ長のDestination Connection IDを持つ場合、 QUICはそのパケットを適切に処理する。複数の接続IDを1つの接続に関連付けられることに 注意すること。Section 5.1を参照。¶
Destination Connection IDが長さ0であり、パケット内のアドレス指定情報が、 長さ0の接続IDを持つ接続を識別するためにエンドポイントが使用するアドレス指定情報と 一致する場合、QUICはそのパケットをその接続の一部として処理する。 エンドポイントは識別に宛先IPとポートだけを使用することも、送信元と宛先の 両方のアドレスを使用することもできるが、これはSection 5.1で 説明されるように接続を脆弱にする。¶
エンドポイントは、既存の接続に帰属できない任意のパケットに対して Stateless Reset(Section 10.3)を送信できる。 Stateless Resetにより、ピアは接続が使用不能になったことをより迅速に識別できる。¶
既存の接続に対応付けられたパケットは、その接続の状態と整合しない場合、 破棄される。たとえば、パケットが接続のプロトコルバージョンと異なる プロトコルバージョンを示している場合、または期待される鍵が利用可能になった後で パケット保護の除去に失敗した場合、パケットは破棄される。¶
Initial、Retry、またはVersion Negotiationなど、強力な完全性保護を欠く 無効なパケットは破棄してもよい(MAY)。 エンドポイントは、エラーを発見する前にこれらのパケットの内容を処理した場合、 接続エラーを生成するか、その処理中に行われた変更を完全に元に戻さなければならない (MUST)。¶
クライアントへ送信される有効なパケットは、常にクライアントが選択した値に 一致するDestination Connection IDを含む。長さ0の接続IDを受信することを 選択したクライアントは、ローカルアドレスとポートを使用して接続を識別できる。 Destination Connection ID、またはこの値が長さ0の場合はローカルIPアドレスと ポートに基づいて既存の接続に一致しないパケットは破棄される。¶
パケットの並べ替えまたは損失により、クライアントは、 まだ計算していない鍵で暗号化された接続用のパケットを受信することがある。 クライアントはこれらのパケットを破棄してもよく(MAY)、または後続のパケットによってその鍵を 計算できるようになることを見越してバッファしてもよい(MAY)。¶
クライアントが最初に選択したものと異なるバージョンを使用するパケットを 受信した場合、そのパケットを破棄しなければならない(MUST)。¶
サーバーがサポートされていないバージョンを示すパケットを受信し、 そのパケットが任意のサポート済みバージョンで新しい接続を開始するのに十分な大きさである場合、 サーバーはSection 6.1で説明されるように Version Negotiationパケットを送信するべきである(SHOULD)。 サーバーは、Version Negotiationパケットで応答するパケット数を制限してもよい (MAY)。サーバーは、サポートされていない バージョンを指定するより小さいパケットを破棄しなければならない (MUST)。¶
サポートされていないバージョンの最初のパケットは、 任意のバージョン固有フィールドについて異なる意味および符号化を使用できる。 特に、異なるバージョンでは異なるパケット保護鍵が使用される可能性がある。 特定のバージョンをサポートしないサーバーは、そのパケットのペイロードを復号したり、 結果を正しく解釈したりできない可能性が高い。データグラムが十分に長い場合、 サーバーはVersion Negotiationパケットで応答するべきである (SHOULD)。¶
サポート済みバージョンを持つパケット、またはVersionフィールドを持たない パケットは、接続IDを用いて、あるいは長さ0の接続IDを持つパケットでは ローカルアドレスとポートを用いて、接続に対応付けられる。 これらのパケットは選択された接続を用いて処理される。それ以外の場合、 サーバーは以下で説明されるように続行する。¶
パケットが仕様に完全に適合するInitialパケットである場合、 サーバーはハンドシェイク(Section 7)を 進める。これにより、サーバーはクライアントが選択したバージョンにコミットする。¶
サーバーが新しい接続の受け入れを拒否する場合、 エラーコードCONNECTION_REFUSEDを持つCONNECTION_CLOSEフレームを含む Initialパケットを送信するべきである(SHOULD)。¶
パケットが0-RTTパケットである場合、サーバーは、遅れて到着する Initialパケットを見越して、これらのパケットの限られた数をバッファしてもよい (MAY)。クライアントはサーバー応答を受信する前に Handshakeパケットを送信できないため、サーバーはそのようなパケットを無視するべきである (SHOULD)。¶
サーバーは、その他すべての状況で到着パケットを破棄しなければならない (MUST)。¶
サーバー展開では、送信元および宛先のIPアドレスとポートのみを使用して サーバー間でロードバランスを行うことがある。クライアントのIPアドレスまたはポートの 変更により、パケットが誤ったサーバーへ転送される可能性がある。そのようなサーバー展開では、 クライアントのアドレスが変更されたときの接続継続性のために、次の方法のいずれかを 使用できる。¶
クライアントアドレスが変更されたときに接続継続性を維持する解決策を 実装していない展開のサーバーは、disable_active_migrationトランスポートパラメーターを 使用して、移行がサポートされていないことを示すべきである (SHOULD)。disable_active_migrationトランスポートパラメーターは、 クライアントがpreferred_addressトランスポートパラメーターに基づいて動作した後の 接続移行を禁止しない。¶
この単純な形式のロードバランシングを使用するサーバー展開は、 ステートレスリセットオラクルの作成を避けなければならない (MUST)。Section 21.11を参照。¶
本文書はQUICのAPIを定義しない。代わりに、アプリケーションプロトコルが 依存できるQUIC接続の一連の機能を定義する。アプリケーションプロトコルは、 QUICの実装が本節で説明される操作を含むインターフェイスを提供すると仮定できる。 特定のアプリケーションプロトコルで使用するために設計された実装は、そのプロトコルが 使用する操作のみを提供してもよい。¶
クライアントの役割を実装する場合、アプリケーションプロトコルは次を行うことができる。¶
サーバーの役割を実装する場合、アプリケーションプロトコルは次を行うことができる。¶
いずれの役割でも、アプリケーションプロトコルは次を行うことができる。¶
バージョンネゴシエーションにより、サーバーはクライアントが使用した バージョンをサポートしていないことを示せる。サーバーは、新しい接続を開始する可能性がある 各パケットに応答してVersion Negotiationパケットを送信する。詳細は Section 5.2を参照。¶
クライアントが送信する最初のパケットのサイズは、サーバーが Version Negotiationパケットを送信するかどうかを決定する。複数のQUICバージョンを サポートするクライアントは、必要に応じてPADDINGフレーム (Section 19.1)を使用し、 送信する最初のUDPデータグラムを、サポートするすべてのバージョンの 最小データグラムサイズのうち最大のものに合わせたサイズにするべきである (SHOULD)。これにより、相互にサポートされるバージョンがある場合に サーバーが応答することが保証される。サーバーは、受信したデータグラムが 別のバージョンで規定された最小サイズより小さい場合、Version Negotiation パケットを送信しないことがある。Section 14.1を参照。¶
クライアントが選択したバージョンをサーバーが受け入れられない場合、 サーバーはVersion Negotiationパケットで応答する。Section 17.2.1を参照。これには、サーバーが受け入れる バージョンのリストが含まれる。エンドポイントは、Version Negotiationパケットの受信に応答して Version Negotiationパケットを送信してはならない (MUST NOT)。¶
この仕組みにより、サーバーは状態を保持せずに、サポートされていない バージョンのパケットを処理できる。Initialパケットまたはそれに応答して送信される Version Negotiationパケットのいずれかが失われることはあるが、クライアントは 応答を正常に受信するか接続試行を放棄するまで、新しいパケットを送信する。¶
サーバーは、送信するVersion Negotiationパケットの数を制限してもよい (MAY)。たとえば、パケットを0-RTTとして認識できるサーバーは、 いずれInitialパケットを受信することを期待して、0-RTTパケットに応答して Version Negotiationパケットを送信しないことを選択してもよい。¶
Version Negotiationパケットは、接続で使用するQUICのバージョンを QUICがネゴシエーションできるようにする将来の機能を定義できるよう設計されている。 将来の標準化過程の仕様は、このバージョンを使用して接続を確立しようとしたことへの 応答として受信したVersion Negotiationパケットに対し、複数のQUICバージョンを サポートする実装がどのように反応するかを変更する可能性がある。¶
このQUICバージョンのみをサポートするクライアントは、 Version Negotiationパケットを受信した場合、次の2つの例外を除き、 現在の接続試行を放棄しなければならない(MUST)。クライアントは、以前のVersion Negotiationパケットを含む 他の任意のパケットを受信して正常に処理している場合、Version Negotiationパケットを 破棄しなければならない(MUST)。クライアントは、クライアントが 選択したQUICバージョンを列挙しているVersion Negotiationパケットを 破棄しなければならない(MUST)。¶
バージョンネゴシエーションをどのように実行するかは、 将来の標準化過程の仕様で定義される今後の作業に委ねられている。 特に、その今後の作業ではバージョンダウングレード攻撃に対する堅牢性を保証する。 Section 21.12を参照。¶
サーバーが将来新しいバージョンを使用するには、クライアントが サポートされていないバージョンを正しく処理する必要がある。一部のバージョン番号 (Section 15で定義される0x?a?a?a?a)は、 バージョン番号を含むフィールドへ含めるために予約されている。¶
エンドポイントは、未知またはサポートされていないバージョンが 無視される任意のフィールドに予約済みバージョンを追加して、ピアがその値を 正しく無視することをテストしてもよい(MAY)。 たとえば、エンドポイントはVersion Negotiationパケットに予約済みバージョンを 含めることができる。Section 17.2.1を参照。 エンドポイントは、ピアがパケットを正しく破棄することをテストするために、 予約済みバージョンを持つパケットを送信してもよい(MAY)。¶
QUICは、接続確立のレイテンシを最小化するため、暗号とトランスポートを 組み合わせたハンドシェイクに依存する。QUICは、暗号ハンドシェイクを転送するために CRYPTOフレーム(Section 19.6)を使用する。本文書で定義される QUICのバージョンは0x00000001として識別され、[QUIC-TLS]で説明されるTLSを使用する。 別のQUICバージョンは、別の暗号ハンドシェイクプロトコルが使用中であることを 示すことができる。¶
QUICは、暗号ハンドシェイクデータの信頼性のある順序付き配信を提供する。 QUICのパケット保護は、ハンドシェイクプロトコルのできる限り多くを暗号化するために 使用される。暗号ハンドシェイクは、次の特性を提供しなければならない (MUST)。¶
認証された鍵交換。ここで、¶
CRYPTOフレームは、異なるパケット番号空間 (Section 12.3)で送信できる。 暗号ハンドシェイクデータの順序付き配信を保証するためにCRYPTOフレームで使用される オフセットは、各パケット番号空間で0から始まる。¶
Figure 4は、簡略化されたハンドシェイクと、 ハンドシェイクを進めるために使用されるパケットおよびフレームの交換を示す。 ハンドシェイク中のアプリケーションデータの交換は、可能な場合に有効化され、 アスタリスク("*")で示される。ハンドシェイクが完了すると、エンドポイントは アプリケーションデータを自由に交換できる。¶
Client Server
Initial (CRYPTO)
0-RTT (*) ---------->
Initial (CRYPTO)
Handshake (CRYPTO)
<---------- 1-RTT (*)
Handshake (CRYPTO)
1-RTT (*) ---------->
<---------- 1-RTT (HANDSHAKE_DONE)
1-RTT <=========> 1-RTT
エンドポイントは、ハンドシェイク中に送信されるパケットを使用して Explicit Congestion Notification(ECN)のサポートをテストできる。 Section 13.4を参照。エンドポイントは、 Section 13.4.2で説明されるように、送信した最初のパケットを確認応答するACKフレームが ECNカウントを運ぶかどうかを観測することにより、ECNのサポートを検証する。¶
エンドポイントは、アプリケーションプロトコルを明示的にネゴシエーションしなければならない (MUST)。これにより、使用中のプロトコルについて 不一致が生じる状況を回避できる。¶
TLSがQUICとどのように統合されるかの詳細は[QUIC-TLS]で提供されるが、 ここではいくつかの例を示す。クライアントアドレス検証をサポートするための この交換の拡張は、Section 8.1.2に示される。¶
アドレス検証の交換が完了すると、暗号ハンドシェイクを使用して 暗号鍵について合意する。暗号ハンドシェイクはInitial (Section 17.2.2)およびHandshake (Section 17.2.4)パケットで運ばれる。¶
Figure 5は、 1-RTTハンドシェイクの概要を示す。各行はQUICパケットを示し、 最初にパケット種別とパケット番号が示され、その後にそれらのパケットに通常含まれる フレームが続く。たとえば、最初のパケットは種別Initial、パケット番号0であり、 ClientHelloを運ぶCRYPTOフレームを含む。¶
複数のQUICパケットは、たとえ異なるパケット種別であっても、 単一のUDPデータグラムに結合できる。Section 12.2を参照。 その結果、このハンドシェイクは最少で4つのUDPデータグラムから構成される場合もあれば、 それ以上の任意の数になる場合もある(輻輳制御や増幅防止など、プロトコルに固有の 制限に従う)。たとえば、サーバーの最初のフライトには、Initialパケット、 Handshakeパケット、および1-RTTパケット内の"0.5-RTTデータ"が含まれる。¶
Client Server
Initial[0]: CRYPTO[CH] ->
Initial[0]: CRYPTO[SH] ACK[0]
Handshake[0]: CRYPTO[EE, CERT, CV, FIN]
<- 1-RTT[0]: STREAM[1, "..."]
Initial[1]: ACK[0]
Handshake[0]: CRYPTO[FIN], ACK[0]
1-RTT[0]: STREAM[0, "..."], ACK[0] ->
Handshake[1]: ACK[0]
<- 1-RTT[1]: HANDSHAKE_DONE, STREAM[3, "..."], ACK[0]
Figure 6は、 0-RTTハンドシェイクと0-RTTデータの単一パケットを持つ接続の例を示す。 Section 12.3で説明されるように、 サーバーは1-RTTパケットで0-RTTデータを確認応答し、クライアントは 同じパケット番号空間で1-RTTパケットを送信することに注意すること。¶
Client Server
Initial[0]: CRYPTO[CH]
0-RTT[0]: STREAM[0, "..."] ->
Initial[0]: CRYPTO[SH] ACK[0]
Handshake[0] CRYPTO[EE, FIN]
<- 1-RTT[0]: STREAM[1, "..."] ACK[0]
Initial[1]: ACK[0]
Handshake[0]: CRYPTO[FIN], ACK[0]
1-RTT[1]: STREAM[0, "..."] ACK[0] ->
Handshake[1]: ACK[0]
<- 1-RTT[1]: HANDSHAKE_DONE, STREAM[3, "..."], ACK[1]
接続IDは、Section 5.1で説明されるように、 パケットの一貫した経路付けを保証するために使用される。ロングヘッダーには 2つの接続IDが含まれる。Destination Connection IDはパケットの受信者によって選択され、 一貫した経路付けを提供するために使用される。Source Connection IDは、ピアが使用する Destination Connection IDを設定するために使用される。¶
ハンドシェイク中、ロングヘッダー(Section 17.2)を持つパケットは、 両方のエンドポイントが使用する接続IDを確立するために使用される。各エンドポイントは、 Source Connection IDフィールドを使用して、そのエンドポイントへ送信されるパケットの Destination Connection IDフィールドで使用される接続IDを指定する。 最初のInitialパケットを処理した後、各エンドポイントは、以後に送信するパケットの Destination Connection IDフィールドを、受信したSource Connection IDフィールドの値に設定する。¶
サーバーからInitialまたはRetryパケットを以前に受信していないクライアントが Initialパケットを送信する場合、クライアントはDestination Connection IDフィールドに 予測困難な値を設定する。このDestination Connection IDは、少なくとも8バイト長でなければならない (MUST)。サーバーからパケットを受信するまで、クライアントは この接続内のすべてのパケットで同じDestination Connection ID値を使用しなければならない (MUST)。¶
クライアントが送信する最初のInitialパケットのDestination Connection IDフィールドは、 Initialパケットのパケット保護鍵を決定するために使用される。これらの鍵は Retryパケットの受信後に変更される。Section 5.2 of [QUIC-TLS]を参照。¶
クライアントは、Source Connection IDフィールドに自ら選択した値を設定し、 Source Connection ID Lengthフィールドを設定してその長さを示す。¶
最初のフライトの0-RTTパケットは、クライアントの最初のInitialパケットと 同じDestination Connection IDおよびSource Connection ID値を使用する。¶
サーバーからInitialまたはRetryパケットを最初に受信したとき、 クライアントは、サーバーによって提供されたSource Connection IDを、以後のパケット (任意の0-RTTパケットを含む)のDestination Connection IDとして使用する。 これは、クライアントが接続確立中に、Destination Connection IDフィールドに設定する 接続IDを2回変更しなければならない可能性があることを意味する。1回はRetryパケットへの応答として、 もう1回はサーバーからのInitialパケットへの応答としてである。クライアントがサーバーから 有効なInitialパケットを受信した後、その接続で異なるSource Connection IDを持つ 後続パケットを受信した場合、クライアントはそれを破棄しなければならない (MUST)。¶
クライアントは、最初に受信したInitialまたはRetryパケットに応答する場合に限り、 パケット送信に使用するDestination Connection IDを変更しなければならない (MUST)。サーバーは、最初に受信したInitialパケットに基づいて、 パケット送信に使用するDestination Connection IDを設定しなければならない (MUST)。Destination Connection IDへの追加変更は、 その値がNEW_CONNECTION_IDフレームから取得された場合にのみ許可される。 後続のInitialパケットが異なるSource Connection IDを含む場合、それらは 破棄されなければならない(MUST)。 これにより、異なるSource Connection IDを持つ複数のInitialパケットの ステートレス処理から生じうる予測不能な結果を回避する。¶
エンドポイントが送信するDestination Connection IDは、 接続の存続期間中、特に接続移行 (Section 9)への応答として変更される可能性がある。 詳細はSection 5.1.1を参照。¶
ハンドシェイク中に各エンドポイントが行う接続IDに関する選択は、 すべての値をトランスポートパラメーターに含めることで認証される。 Section 7.4を参照。 これにより、ハンドシェイクに使用されるすべての接続IDが、暗号ハンドシェイクによっても 認証されることが保証される。¶
各エンドポイントは、自身が送信した最初のInitialパケットの Source Connection IDフィールドの値を、initial_source_connection_id トランスポートパラメーターに含める。Section 18.2を参照。 サーバーは、クライアントから受信した最初のInitialパケットの Destination Connection IDフィールドを、original_destination_connection_id トランスポートパラメーターに含める。サーバーがRetryパケットを送信した場合、 これはRetryパケット送信前に受信した最初のInitialパケットを指す。 Retryパケットを送信する場合、サーバーはRetryパケットのSource Connection IDフィールドも retry_source_connection_idトランスポートパラメーターに含める。¶
これらのトランスポートパラメーターについてピアが提供する値は、 エンドポイントが送信した(サーバーの場合は受信もした)Initialパケットの DestinationおよびSource Connection IDフィールドで使用した値と一致しなければならない (MUST)。エンドポイントは、受信したトランスポートパラメーターが 受信した接続ID値と一致することを検証しなければならない (MUST)。接続ID値をトランスポートパラメーターに含めて 検証することで、攻撃者がハンドシェイク中に攻撃者の選んだ接続IDを運ぶパケットを 注入して、成功する接続の接続IDの選択に影響を与えられないことが保証される。¶
エンドポイントは、いずれかのエンドポイントから initial_source_connection_idトランスポートパラメーターが欠落していること、 またはサーバーからoriginal_destination_connection_idトランスポートパラメーターが 欠落していることを、TRANSPORT_PARAMETER_ERROR型の接続エラーとして扱わなければならない (MUST)。¶
エンドポイントは、次をTRANSPORT_PARAMETER_ERRORまたは PROTOCOL_VIOLATION型の接続エラーとして扱わなければならない (MUST)。¶
長さ0の接続IDが選択された場合、対応するトランスポートパラメーターは 長さ0の値で含められる。¶
Figure 7は、 完全なハンドシェイクで使用される接続ID(DCID=Destination Connection ID、 SCID=Source Connection ID)を示す。Initialパケットの交換に加え、 ハンドシェイク中に確立された接続IDを含む、後続の1-RTTパケットの交換も示される。¶
Client Server
Initial: DCID=S1, SCID=C1 ->
<- Initial: DCID=C1, SCID=S3
...
1-RTT: DCID=S3 ->
<- 1-RTT: DCID=C1
Figure 8は、 Retryパケットを含む同様のハンドシェイクを示す。¶
Client Server
Initial: DCID=S1, SCID=C1 ->
<- Retry: DCID=C1, SCID=S2
Initial: DCID=S2, SCID=C1 ->
<- Initial: DCID=C1, SCID=S3
...
1-RTT: DCID=S3 ->
<- 1-RTT: DCID=C1
どちらの場合(Figures 7および8)でも、
クライアントはinitial_source_connection_idトランスポートパラメーターの値を
C1に設定する。¶
ハンドシェイクにRetryが含まれない場合
(Figure 7)、サーバーは
original_destination_connection_idをS1(この値はクライアントによって
選択されたものであることに注意)に設定し、initial_source_connection_idを
S3に設定する。この場合、サーバーはretry_source_connection_id
トランスポートパラメーターを含めない。¶
ハンドシェイクにRetryが含まれる場合
(Figure 8)、サーバーは
original_destination_connection_idをS1に、retry_source_connection_idを
S2に、
initial_source_connection_idをS3に設定する。¶
接続確立中、両方のエンドポイントは、自身のトランスポートパラメーターについて 認証された宣言を行う。エンドポイントは、各パラメーターが定義する制限に 従うことを要求される。各パラメーターの説明には、その処理に関する規則が含まれる。¶
トランスポートパラメーターは、各エンドポイントによって一方的に行われる 宣言である。各エンドポイントは、ピアが選択した値とは独立して、 トランスポートパラメーターの値を選択できる。¶
トランスポートパラメーターの符号化は、 Section 18で詳述される。¶
QUICは、符号化されたトランスポートパラメーターを暗号ハンドシェイクに 含める。ハンドシェイクが完了すると、ピアによって宣言されたトランスポートパラメーターが 利用可能になる。各エンドポイントは、ピアによって提供された値を検証する。¶
定義済みの各トランスポートパラメーターの定義は、 Section 18.2に含まれる。¶
エンドポイントは、無効な値を持つトランスポートパラメーターの受信を、 TRANSPORT_PARAMETER_ERROR型の接続エラーとして扱わなければならない (MUST)。¶
エンドポイントは、特定のtransport parameters拡張内で同じパラメーターを 複数回送信してはならない(MUST NOT)。 エンドポイントは、重複したトランスポートパラメーターの受信を、 TRANSPORT_PARAMETER_ERROR型の接続エラーとして扱うべきである (SHOULD)。¶
エンドポイントは、ハンドシェイク中の接続IDネゴシエーションを 認証するためにトランスポートパラメーターを使用する。 Section 7.3を参照。¶
ALPN([ALPN]を参照)により、 クライアントは接続確立中に複数のアプリケーションプロトコルを提示できる。 ハンドシェイク中にクライアントが含めるトランスポートパラメーターは、 クライアントが提示するすべてのアプリケーションプロトコルに適用される。 アプリケーションプロトコルは、初期フロー制御上限など、トランスポートパラメーターの値を 推奨できる。ただし、トランスポートパラメーターの値に制約を設定する アプリケーションプロトコルは、それらの制約が競合する場合、クライアントが 複数のアプリケーションプロトコルを提示することを不可能にする可能性がある。¶
0-RTTの使用は、クライアントとサーバーの両方が以前の接続で ネゴシエーションされたプロトコルパラメーターを使用することに依存する。 0-RTTを有効にするため、エンドポイントは、その接続で受信した任意の セッションチケットとともに、サーバーのトランスポートパラメーターの値を保存する。 エンドポイントは、アプリケーションプロトコルまたは暗号ハンドシェイクに必要な 任意の情報も保存する。Section 4.6 of [QUIC-TLS]を参照。 保存されたトランスポートパラメーターの値は、セッションチケットを用いて 0-RTTを試みるときに使用される。¶
記憶されたトランスポートパラメーターは、ハンドシェイクが完了し、 クライアントが1-RTTパケットの送信を開始するまで、新しい接続に適用される。 ハンドシェイクが完了すると、クライアントはハンドシェイクで確立された トランスポートパラメーターを使用する。すべてのトランスポートパラメーターが 記憶されるわけではない。将来の接続に適用されないものや、 0-RTTの使用に影響しないものがあるためである。¶
新しいトランスポートパラメーターの定義 (Section 7.4.2)は、 0-RTTのためにそのトランスポートパラメーターを保存することが必須、任意、 または禁止のいずれであるかを規定しなければならない (MUST)。クライアントは、処理できない トランスポートパラメーターを保存する必要はない。¶
クライアントは、次のパラメーターについて記憶された値を使用してはならない (MUST NOT)。 ack_delay_exponent、max_ack_delay、initial_source_connection_id、 original_destination_connection_id、preferred_address、 retry_source_connection_id、およびstateless_reset_token。クライアントは、 代わりにハンドシェイクにおけるサーバーの新しい値を使用しなければならない (MUST)。サーバーが新しい値を提供しない場合は、 デフォルト値が使用される。¶
0-RTTデータの送信を試みるクライアントは、処理可能な、 サーバーによって使用されたその他すべてのトランスポートパラメーターを 記憶しなければならない(MUST)。サーバーは、これらのトランスポートパラメーターを 記憶することも、値の完全性保護されたコピーをチケットに保存し、 0-RTTデータを受け入れるときにその情報を復元することもできる。 サーバーは、0-RTTデータを受け入れるかどうかを判断する際に トランスポートパラメーターを使用する。¶
0-RTTデータがサーバーによって受け入れられる場合、サーバーは、 クライアントの0-RTTデータによって違反されうる任意の上限を減少させたり、 任意の値を変更したりしてはならない(MUST NOT)。特に、0-RTTデータを受け入れるサーバーは、 次のパラメーター(Section 18.2)について、記憶されたパラメーター値より 小さい値を設定してはならない(MUST NOT)。¶
特定のトランスポートパラメーターを省略する、または0値に設定すると、 0-RTTデータは有効になるが使用できない結果となる可能性がある。 アプリケーションデータの送信を許可するトランスポートパラメーターの該当する部分集合は、 0-RTTのために非ゼロ値に設定されるべきである(SHOULD)。 これには、initial_max_data、および(1)initial_max_streams_bidiと initial_max_stream_data_bidi_remote、または(2)initial_max_streams_uniと initial_max_stream_data_uniが含まれる。¶
サーバーは、0-RTTを送信する際にクライアントが適用する記憶値よりも 大きい、ストリームの初期ストリームフロー制御上限を提供することがある。 ハンドシェイクが完了すると、クライアントはinitial_max_stream_data_bidi_remote およびinitial_max_stream_data_uniの更新された値を使用して、すべての送信ストリームの フロー制御上限を更新する。¶
サーバーは、以前に送信したmax_idle_timeout、 max_udp_payload_size、およびdisable_active_migrationパラメーターの値を 保存して復元し、より小さい値を選択する場合に0-RTTを拒否してもよい (MAY)。0-RTTデータを受け入れながらこれらの パラメーターの値を下げると、接続の性能が低下する可能性がある。 特に、max_udp_payload_sizeを下げると、パケットが破棄され、 0-RTTデータを最初から拒否する場合と比べて性能が悪化する可能性がある。¶
サーバーは、復元されたトランスポートパラメーターの値を サポートできない場合、0-RTTデータを拒否しなければならない (MUST)。¶
0-RTTパケットでフレームを送信する場合、クライアントは 記憶されたトランスポートパラメーターのみを使用しなければならない (MUST)。重要なことに、サーバーの更新された トランスポートパラメーター、または1-RTTパケットで受信したフレームから知った 更新値を使用してはならない(MUST NOT)。 ハンドシェイクから得られる更新済みトランスポートパラメーターの値は、 1-RTTパケットにのみ適用される。たとえば、記憶されたトランスポートパラメーターの フロー制御上限は、ハンドシェイクまたは1-RTTパケットで送信されるフレームにより それらの値が増加した場合でも、すべての0-RTTパケットに適用される。 サーバーは、0-RTTで更新されたトランスポートパラメーターを使用することを、 PROTOCOL_VIOLATION型の接続エラーとして扱ってもよい(MAY)。¶
新しいトランスポートパラメーターは、新しいプロトコルのふるまいを ネゴシエーションするために使用できる。エンドポイントは、サポートしない トランスポートパラメーターを無視しなければならない(MUST)。 したがって、トランスポートパラメーターが存在しないことは、そのパラメーターを用いて ネゴシエーションされる任意のプロトコル機能を無効にする。 Section 18.1で説明されるように、 この要件を行使するため、一部の識別子は予約されている。¶
トランスポートパラメーターを理解しないクライアントは、 それを破棄し、後続の接続で0-RTTを試みることができる。ただし、クライアントが 破棄したトランスポートパラメーターのサポートを追加した場合、0-RTTを試みると、 そのトランスポートパラメーターが確立する制約に違反するリスクがある。 新しいトランスポートパラメーターは、最も保守的な値をデフォルトに設定することで、 この問題を回避できる。クライアントは、現在サポートしていないものも含め、 すべてのパラメーターを記憶することでこの問題を回避できる。¶
新しいトランスポートパラメーターは、 Section 22.3の規則に従って 登録できる。¶
実装は、順序外で受信したCRYPTOデータのバッファを維持する必要がある。 CRYPTOフレームにはフロー制御がないため、エンドポイントは潜在的に、 ピアに無制限の量のデータをバッファさせる可能性がある。¶
実装は、順序外のCRYPTOフレームで受信された少なくとも4096バイトの データのバッファリングをサポートしなければならない(MUST)。 エンドポイントは、ハンドシェイク中により多くのデータをバッファできるように 選択してもよい(MAY)。ハンドシェイク中の上限が大きいと、 より大きな鍵または資格情報の交換が可能になることがある。エンドポイントの バッファサイズは、接続の存続期間中一定である必要はない。¶
ハンドシェイク中にCRYPTOフレームをバッファできないと、 接続失敗につながる可能性がある。ハンドシェイク中にエンドポイントのバッファを 超過した場合、ハンドシェイクを完了するために一時的にバッファを拡張できる。 エンドポイントがバッファを拡張しない場合、CRYPTO_BUFFER_EXCEEDEDエラーコードで 接続を閉じなければならない(MUST)。¶
ハンドシェイクが完了した後、エンドポイントがCRYPTOフレーム内の すべてのデータをバッファできない場合、そのCRYPTOフレームおよび将来受信する すべてのCRYPTOフレームを破棄してもよく(MAY)、 またはCRYPTO_BUFFER_EXCEEDEDエラーコードで接続を閉じてもよい (MAY)。破棄されたCRYPTOフレームを含むパケットは、 CRYPTOフレームが破棄されたとしても、そのパケットはトランスポートによって 受信および処理されているため、確認応答されなければならない (MUST)。¶
アドレス検証は、エンドポイントがトラフィック増幅攻撃に使用されないことを 保証する。このような攻撃では、被害者を識別する偽装された送信元アドレス情報を 持つパケットがサーバーへ送信される。サーバーがそのパケットに応答して、より多くの、 またはより大きなパケットを生成する場合、攻撃者はサーバーを使用して、自身だけで 送信できる量より多くのデータを被害者へ送信できる。¶
増幅攻撃に対する主な防御は、ピアが主張するトランスポートアドレスで パケットを受信できることを検証することである。したがって、まだ検証されていない アドレスからパケットを受信した後、エンドポイントは、その未検証アドレスへ送信する データ量を、そのアドレスから受信したデータ量の3倍に制限しなければならない (MUST)。この応答サイズの制限は、増幅防止上限として知られる。¶
アドレス検証は、接続確立中(Section 8.1を参照)と 接続移行中(Section 8.2を参照)の両方で実行される。¶
接続確立は、両方のエンドポイントに対して暗黙にアドレス検証を提供する。 特に、Handshake鍵で保護されたパケットを受信することは、ピアがInitialパケットを 正常に処理したことを確認する。エンドポイントがピアからのHandshakeパケットを 正常に処理すると、そのピアアドレスは検証済みと見なすことができる。¶
さらに、ピアがエンドポイントによって選択された接続IDを使用し、 その接続IDが少なくとも64ビットのエントロピーを含む場合、エンドポイントは ピアアドレスを検証済みと見なしてもよい(MAY)。¶
クライアントの場合、最初のInitialパケット内のDestination Connection ID フィールドの値により、任意のパケットを正常に処理する一部としてサーバーアドレスを 検証できる。サーバーからのInitialパケットは、この値から導出された鍵で保護される (Section 5.2 of [QUIC-TLS]を参照)。あるいは、この値は Version Negotiationパケット(Section 6)でサーバーにより エコーされるか、RetryパケットのIntegrity Tag (Section 5.8 of [QUIC-TLS])に含められる。¶
クライアントアドレスを検証する前に、サーバーは受信したバイト数の3倍を 超えるバイト数を送信してはならない(MUST NOT)。 これは、偽装された送信元アドレスを用いて実行できる増幅攻撃の規模を制限する。 アドレス検証前の増幅を避ける目的で、サーバーは、単一の接続に一意に帰属する データグラムで受信したすべてのペイロードバイトを数えなければならない (MUST)。これには、正常に処理されたパケットを含む データグラムと、すべて破棄されたパケットを含むデータグラムが含まれる。¶
クライアントは、Initialパケットを含むUDPデータグラムが少なくとも 1200バイトのUDPペイロードを持つことを保証し、必要に応じてPADDINGフレームを 追加しなければならない(MUST)。 パディングされたデータグラムを送信するクライアントは、サーバーがアドレス検証を 完了する前により多くのデータを送信できるようにする。¶
サーバーからのInitialまたはHandshakeパケットの損失は、クライアントが 追加のInitialまたはHandshakeパケットを送信しない場合、デッドロックを引き起こす可能性がある。 デッドロックは、サーバーが増幅防止上限に達し、クライアントが送信したすべてのデータに 対する確認応答を受信した場合に発生しうる。この場合、クライアントに追加のパケットを 送信する理由がないと、サーバーはクライアントのアドレスを検証していないため、 それ以上のデータを送信できない。このデッドロックを防ぐため、クライアントは Probe Timeout(PTO)時にパケットを送信しなければならない(MUST)。 Section 6.2 of [QUIC-RECOVERY]を参照。 具体的には、クライアントはHandshake鍵を持たない場合、少なくとも1200バイトを 含むUDPデータグラム内でInitialパケットを送信しなければならず(MUST)、 それ以外の場合はHandshakeパケットを送信しなければならない。¶
サーバーは、暗号ハンドシェイクを開始する前にクライアントアドレスを 検証したい場合がある。QUICは、ハンドシェイク完了前のアドレス検証を提供するため、 Initialパケット内のトークンを使用する。このトークンは、接続確立中にRetryパケット (Section 8.1.2を参照)でクライアントへ配信されるか、 以前の接続においてNEW_TOKENフレーム (Section 8.1.3を参照)を用いて配信される。¶
アドレス検証前に課される送信上限に加え、サーバーは輻輳制御器によって 設定される上限によっても送信できる内容が制約される。クライアントは輻輳制御器にのみ 制約される。¶
NEW_TOKENフレームまたはRetryパケットで送信されるトークンは、 それがどのようにクライアントへ提供されたかをサーバーが識別できる方法で 構築されなければならない(MUST)。これらの トークンは同じフィールドで運ばれるが、サーバーでは異なる処理を必要とする。¶
クライアントのInitialパケットを受信したとき、サーバーはトークンを 含むRetryパケット(Section 17.2.5)を送信してアドレス検証を要求できる。このトークンは、 Retryパケットを受信した後、その接続のためにクライアントが送信するすべての Initialパケットで繰り返されなければならない(MUST)。¶
Retryパケットで提供されたトークンを含むInitialパケットを処理したことへの 応答として、サーバーは別のRetryパケットを送信できない。サーバーは接続を拒否するか、 進行を許可することだけができる。¶
攻撃者が自分のアドレスに対する有効なトークンを生成できず (Section 8.1.4を参照)、 クライアントがそのトークンを返せる限り、それはクライアントがトークンを 受信したことをサーバーに証明する。¶
サーバーはまた、Retryパケットを使用して、接続確立の状態および処理コストを 遅延させることができる。サーバーに異なる接続IDを提供させ、 Section 18.2で定義されるoriginal_destination_connection_idトランスポートパラメーターと ともに使用することで、サーバー、またはサーバーと協調するエンティティが、 クライアントからの元のInitialパケットを受信したことを示すよう強制する。 異なる接続IDを提供することは、後続のパケットがどのように経路付けされるかについて、 サーバーにある程度の制御も与える。これは、接続を別のサーバーインスタンスへ 誘導するために使用できる。¶
サーバーが、無効なRetryトークンを含むがそれ以外は有効な クライアントInitialを受信した場合、クライアントが別のRetryトークンを 受け入れないことが分かる。サーバーはそのようなパケットを破棄し、 クライアントがタイムアウトによってハンドシェイク失敗を検出できるようにしてもよいが、 それはクライアントに大きなレイテンシペナルティを課す可能性がある。代わりに、 サーバーはINVALID_TOKENエラーで接続を直ちに閉じるべきである (SHOULD)(Section 10.2)。 この時点ではサーバーが接続の状態を確立していないため、クローズ期間に入らないことに 注意すること。¶
Retryパケットの使用を示すフローをFigure 9に示す。¶
Client Server
Initial[0]: CRYPTO[CH] ->
<- Retry+Token
Initial+Token[1]: CRYPTO[CH] ->
Initial[0]: CRYPTO[SH] ACK[1]
Handshake[0]: CRYPTO[EE, CERT, CV, FIN]
<- 1-RTT[0]: STREAM[1, "..."]
サーバーは、ある接続中に、後続の接続で使用できる アドレス検証トークンをクライアントへ提供してもよい(MAY)。 0-RTTでは、サーバーが0-RTTデータに応答して相当量のデータをクライアントへ 送信する可能性があるため、アドレス検証は特に重要である。¶
サーバーはNEW_TOKENフレーム(Section 19.7)を使用して、 将来の接続を検証するために使用できるアドレス検証トークンをクライアントへ提供する。 将来の接続では、クライアントはアドレス検証を提供するために、このトークンを Initialパケットに含める。Retryがこのトークンをより新しいものに置き換えない限り、 クライアントは送信するすべてのInitialパケットにトークンを含めなければならない (MUST)。クライアントはRetryで提供されたトークンを 将来の接続に使用してはならない(MUST NOT)。 サーバーは、期待されるトークンを運ばない任意のInitialパケットを破棄してもよい (MAY)。¶
即時に使用されるRetryパケット用に作成されるトークンとは異なり、 NEW_TOKENフレームで送信されるトークンは、ある程度の時間が経過した後に使用できる。 したがって、トークンは有効期限を持つべきである(SHOULD)。 これは明示的な有効期限でも、動的に有効期限を計算するために使用できる 発行時刻でもよい。サーバーは有効期限を保存するか、暗号化された形式で トークンに含めることができる。¶
NEW_TOKENで発行されるトークンは、それが発行された接続に オブザーバーが値を関連付けられるような情報を含んではならない (MUST NOT)。たとえば、値が暗号化されていない限り、 以前の接続IDやアドレス情報を含めることはできない。サーバーは、以前に送信された NEW_TOKENフレームの損失を修復するために送信されるものを除き、 送信するすべてのNEW_TOKENフレームがすべてのクライアントにわたって一意であることを 保証しなければならない(MUST)。Retry由来のトークンと NEW_TOKEN由来のトークンをサーバーが区別できるようにする情報は、 サーバー以外のエンティティからアクセス可能であってもよい(MAY)。¶
クライアントのポート番号が2つの異なる接続で同じである可能性は低い。 したがって、ポートを検証することは成功しにくい。¶
NEW_TOKENフレームで受信されたトークンは、その接続が権威を持つと 見なされる任意のサーバー(例: 証明書に含まれるサーバー名)に適用可能である。 クライアントが適用可能で未使用のトークンを保持しているサーバーへ接続する場合、 そのInitialパケットのTokenフィールドにそのトークンを含めるべきである (SHOULD)。トークンを含めることで、追加の往復なしに サーバーがクライアントアドレスを検証できる可能性がある。クライアントは、 トークンを発行したサーバーと接続先サーバーが共同でトークンを管理していることを 知っている場合を除き、接続先サーバーに適用できないトークンを含めてはならない (MUST NOT)。クライアントは、そのサーバーへの 任意の以前の接続から得たトークンを使用してもよい(MAY)。¶
トークンにより、サーバーはトークンが発行された接続と、それが使用される 任意の接続との間の活動を相関付けることができる。サーバーとのアイデンティティの 連続性を断ちたいクライアントは、NEW_TOKENフレームを用いて提供されたトークンを 破棄できる。これに対し、Retryパケットで取得されたトークンは接続試行中に 直ちに使用されなければならず(MUST)、 後続の接続試行では使用できない。¶
クライアントは、NEW_TOKENフレームからのトークンを異なる接続試行で 再使用するべきではない(SHOULD NOT)。 トークンを再使用すると、ネットワークパス上のエンティティによって接続が 関連付けられる可能性がある。Section 9.5を参照。¶
クライアントは、単一の接続で複数のトークンを受信することがある。 関連付け可能性を防ぐことを別にすれば、任意のトークンを任意の接続試行で使用できる。 サーバーは、複数の接続試行のためのアドレス検証を可能にするため、または 無効になる可能性のある古いトークンを置き換えるために、追加のトークンを送信できる。 クライアントにとって、この曖昧さは、最も新しい未使用トークンを送信することが 最も有効である可能性が高いことを意味する。古いトークンを保存して使用しても 悪影響はないが、クライアントは、古いトークンはサーバーにとってアドレス検証に 有用である可能性が低いと見なすことができる。¶
サーバーがアドレス検証トークンを含むInitialパケットを受信した場合、 アドレス検証をすでに完了していない限り、そのトークンの検証を試みなければならない (MUST)。トークンが無効な場合、サーバーは、Retryパケットを 送信する可能性を含め、クライアントが検証済みアドレスを持たないかのように 続行するべきである(SHOULD)。NEW_TOKENフレームで 提供されたトークンとRetryパケットで提供されたトークンは、サーバーで区別でき (Section 8.1.1を参照)、後者はより厳密に検証できる。検証が成功した場合、 サーバーはハンドシェイクの進行を許可するべきである(SHOULD)。¶
ステートレスな設計では、サーバーは暗号化され認証されたトークンを 使用して情報をクライアントへ渡し、サーバーが後で復元してクライアントアドレスの 検証に使用できる。トークンは暗号ハンドシェイクに統合されていないため、 認証されない。たとえば、クライアントがトークンを再使用できる可能性がある。 この性質を悪用する攻撃を避けるため、サーバーはトークンの使用をクライアント アドレスの検証に必要な情報のみに制限できる。¶
クライアントは、同じバージョンを使用する任意の接続試行について、 ある接続で取得したトークンを使用してもよい(MAY)。 使用するトークンを選択するとき、クライアントは、可能なアプリケーションプロトコルの 選択、セッションチケット、その他の接続特性を含め、試行される接続の他の性質を 考慮する必要はない。¶
アドレス検証トークンは推測困難でなければならない (MUST)。トークンに少なくとも128ビットのエントロピーを 持つランダム値を含めれば十分であるが、これはサーバーがクライアントへ送信した 値を記憶することに依存する。¶
トークンベースの方式により、サーバーは検証に関連する任意の状態を クライアントへオフロードできる。この設計が機能するためには、トークンは クライアントによる変更または偽造に対して完全性保護で覆われていなければならない (MUST)。完全性保護がないと、悪意あるクライアントが サーバーに受け入れられるトークン値を生成または推測できる可能性がある。 トークンの完全性保護鍵へのアクセスを必要とするのはサーバーのみである。¶
トークンには単一の明確に定義された形式は必要ない。 トークンを生成するサーバーがそれを消費するためである。Retryパケットで送信される トークンは、クライアントパケット内の送信元IPアドレスとポートが一定のままであることを サーバーが検証できる情報を含むべきである(SHOULD)。¶
NEW_TOKENフレームで送信されるトークンは、トークン発行時から クライアントIPアドレスが変更されていないことをサーバーが検証できる情報を 含まなければならない(MUST)。サーバーは、クライアントアドレスが 変更されていても、Retryパケットを送信しないと判断する際にNEW_TOKENフレーム由来の トークンを使用できる。クライアントIPアドレスが変更されている場合、サーバーは 増幅防止上限を遵守しなければならない(MUST)。 Section 8を参照。NATが存在する場合、 この要件は、同じNATを共有する他のホストを増幅攻撃から保護するには 不十分な可能性があることに注意すること。¶
攻撃者はトークンを再生して、DDoS攻撃における増幅器として サーバーを使用する可能性がある。そのような攻撃を防ぐため、サーバーは トークンの再生が防止または制限されることを保証しなければならない (MUST)。サーバーは、Retryパケットで送信されたトークンが クライアントによって直ちに返されるため、短時間だけ受け入れられることを 保証するべきである(SHOULD)。 NEW_TOKENフレーム(Section 19.7)で提供されるトークンは より長く有効である必要があるが、複数回受け入れられるべきではない (SHOULD NOT)。サーバーは、可能であればトークンを一度だけ 使用できるようにすることが推奨される。トークンは、適用可能性または再使用を さらに狭めるために、クライアントに関する追加情報を含んでもよい (MAY)。¶
パス検証は、接続移行中(Section 9を参照)に、 アドレス変更後の到達可能性を検証するため、両方のピアによって使用される。 パス検証では、エンドポイントは特定のローカルアドレスと特定のピアアドレスの間の 到達可能性をテストする。ここでアドレスはIPアドレスとポートの2タプルである。¶
パス検証は、ピアへのパス上で送信されたパケットがそのピアによって 受信されることをテストする。パス検証は、移行するピアから受信されたパケットが 偽装された送信元アドレスを運ばないことを保証するために使用される。¶
パス検証は、ピアが戻り方向に送信できることを検証しない。 確認応答は十分なエントロピーを含まず、偽装される可能性があるため、戻りパスの 検証には使用できない。エンドポイントはパスの各方向における到達可能性を独立に判断するため、 戻り方向の到達可能性はピアによってのみ確立できる。¶
パス検証は、どちらのエンドポイントによっても任意の時点で使用できる。 たとえば、エンドポイントは静穏期間の後に、ピアが引き続きそのアドレスを保持していることを 確認することがある。¶
パス検証はNATトラバーサル機構として設計されていない。 ここで説明される機構はNATトラバーサルをサポートするNATバインディングの作成に 有効である可能性があるが、期待されるのは、一方のエンドポイントがそのパス上で 先にパケットを送信しなくてもパケットを受信できることである。有効なNATトラバーサルには、 ここでは提供されない追加の同期機構が必要である。¶
エンドポイントは、パス検証に使用されるPATH_CHALLENGEおよび PATH_RESPONSEフレームに他のフレームを含めてもよい(MAY)。 特に、エンドポイントはPath Maximum Transmission Unit Discovery(PMTUD)のために PATH_CHALLENGEフレームとともにPADDINGフレームを含めることができる。 Section 14.2.1を参照。エンドポイントは PATH_RESPONSEフレームを送信するとき、自身のPATH_CHALLENGEフレームも含めることができる。¶
エンドポイントは、新しいローカルアドレスから送信されるプローブに 新しい接続IDを使用する。Section 9.5を参照。 新しいパスを探査するとき、エンドポイントは、ピアが応答のために未使用の接続IDを 利用できることを保証できる。ピアのactive_connection_id_limitが許す場合、 NEW_CONNECTION_IDフレームとPATH_CHALLENGEフレームを同じパケットで送信すると、 応答送信時に未使用の接続IDがピアで利用可能になることが保証される。¶
エンドポイントは、複数のパスを同時に探査することを選択できる。 探査に使用される同時パスの数は、ピアが以前に提供した追加接続IDの数によって制限される。 これは、プローブに使用される各新しいローカルアドレスが、以前に未使用だった接続IDを 必要とするためである。¶
パス検証を開始するため、エンドポイントは検証対象のパス上で、 予測困難なペイロードを含むPATH_CHALLENGEフレームを送信する。¶
エンドポイントは、パケット損失に備えるために複数の PATH_CHALLENGEフレームを送信してもよい(MAY)。 ただし、エンドポイントは単一のパケット内で複数のPATH_CHALLENGEフレームを 送信するべきではない(SHOULD NOT)。¶
エンドポイントは、Initialパケットを送信する頻度より高い頻度で、 PATH_CHALLENGEフレームを含むパケットにより新しいパスを探査するべきではない (SHOULD NOT)。これにより、接続移行が新しい接続の確立よりも 新しいパスに大きな負荷を与えないことが保証される。¶
エンドポイントは、対応するPATH_CHALLENGEにピアの応答を関連付けられるよう、 すべてのPATH_CHALLENGEフレームで予測困難なデータを使用しなければならない (MUST)。¶
エンドポイントは、そのパスの増幅防止上限がこのサイズのデータグラム送信を 許可しない場合を除き、PATH_CHALLENGEフレームを含むデータグラムを、 許可される最小最大データグラムサイズである少なくとも1200バイトまで 拡張しなければならない(MUST)。このサイズのUDPデータグラムを 送信することで、エンドポイントからピアへのネットワークパスがQUICに使用できることを 保証する。Section 14を参照。¶
増幅防止上限のため、エンドポイントがデータグラムサイズを1200バイトまで 拡張できない場合、パスMTUは検証されない。パスMTUが十分大きいことを保証するため、 エンドポイントは、少なくとも1200バイトのデータグラム内でPATH_CHALLENGEフレームを 送信することにより、2回目のパス検証を実行しなければならない (MUST)。この追加検証は、PATH_RESPONSEが正常に受信された後、 またはより大きなデータグラムを送信しても増幅防止上限を超えないだけのバイトが そのパスで受信されたときに実行できる。¶
データグラムが拡張される他の場合とは異なり、PATH_CHALLENGEまたは PATH_RESPONSEを含む場合、エンドポイントは小さすぎるように見えるデータグラムを 破棄してはならない(MUST NOT)。¶
PATH_CHALLENGEフレームを受信すると、エンドポイントは PATH_CHALLENGEフレームに含まれるデータをPATH_RESPONSEフレームでエコーして 応答しなければならない(MUST)。エンドポイントは、 輻輳制御によって制約される場合を除き、PATH_RESPONSEフレームを含むパケットの送信を 遅延してはならない(MUST NOT)。¶
PATH_RESPONSEフレームは、PATH_CHALLENGEフレームが受信された ネットワークパス上で送信されなければならない(MUST)。 これにより、ピアによるパス検証は、そのパスが両方向で機能する場合にのみ成功することが 保証される。この要件は、移行に対する攻撃を可能にするため、パス検証を開始した エンドポイントによって強制されてはならない(MUST NOT)。 Section 9.3.3を参照。¶
エンドポイントは、PATH_RESPONSEフレームを含むデータグラムを、 許可される最小最大データグラムサイズである少なくとも1200バイトまで 拡張しなければならない(MUST)。これにより、 パスがこのサイズのデータグラムを両方向に運べることが検証される。ただし、 その結果のデータが増幅防止上限を超える場合、エンドポイントはPATH_RESPONSEを含む データグラムを拡張してはならない(MUST NOT)。 これは、受信したPATH_CHALLENGEが拡張されたデータグラムで送信されなかった場合にのみ 発生することが予想される。¶
エンドポイントは、1つのPATH_CHALLENGEフレームに応答して 複数のPATH_RESPONSEフレームを送信してはならない(MUST NOT)。 Section 13.3を参照。ピアは、必要に応じて追加のPATH_RESPONSEフレームを 引き出すため、さらにPATH_CHALLENGEフレームを送信することが期待される。¶
以前のPATH_CHALLENGEフレームで送信されたデータを含む PATH_RESPONSEフレームが受信されると、パス検証は成功する。任意のネットワークパス上で 受信されたPATH_RESPONSEフレームは、PATH_CHALLENGEが送信されたパスを検証する。¶
エンドポイントが少なくとも1200バイトまで拡張されていない データグラム内でPATH_CHALLENGEフレームを送信し、その応答によってピアアドレスが 検証された場合、そのパスは検証されるがパスMTUは検証されない。その結果、 エンドポイントは受信したデータ量の3倍を超えるデータを送信できるようになる。 ただし、エンドポイントは、そのパスが必要なMTUをサポートしていることを検証するため、 拡張されたデータグラムを用いて別のパス検証を開始しなければならない (MUST)。¶
PATH_CHALLENGEフレームを含むパケットに対する確認応答の受信は、 十分な検証ではない。確認応答は悪意あるピアによって偽装される可能性があるためである。¶
パス検証は、パスの検証を試みているエンドポイントが そのパスの検証試行を放棄した場合にのみ失敗する。¶
エンドポイントは、タイマーに基づいてパス検証を放棄するべきである (SHOULD)。このタイマーを設定するとき、実装は、 新しいパスが元のパスより長い往復時間を持つ可能性があることに注意する。 現在のPTOまたは新しいパスのPTO([QUIC-RECOVERY]で 定義されるkInitialRttを使用)のいずれか大きい方の3倍の値が推奨される (RECOMMENDED)。¶
このタイムアウトにより、パス検証失敗前に複数のPTOが満了できるため、 単一のPATH_CHALLENGEまたはPATH_RESPONSEフレームの損失がパス検証失敗を引き起こさない。¶
エンドポイントは新しいパス上で他のフレームを含むパケットを受信する 可能性があるが、パス検証が成功するには適切なデータを持つPATH_RESPONSEフレームが 必要であることに注意すること。¶
エンドポイントがパス検証を放棄すると、そのパスは使用不能であると判断する。 これは必ずしも接続の失敗を意味しない。エンドポイントは適切であれば他のパス上で パケットを送信し続けることができる。利用可能なパスがない場合、エンドポイントは 新しいパスが利用可能になるのを待つか、接続を閉じることができる。ピアへの有効な ネットワークパスを持たないエンドポイントは、NO_VIABLE_PATH接続エラーを使用して これを通知してもよい(MAY)。ただし、これはネットワークパスは 存在するが必要なMTU(Section 14)を サポートしていない場合にのみ可能であることに注意すること。¶
パス検証は失敗以外の理由で放棄されることもある。主に、 古いパスでパス検証が進行中の間に、新しいパスへの接続移行が開始された場合に これが発生する。¶
接続IDの使用により、エンドポイントアドレス(IPアドレスとポート)の変更、 たとえばエンドポイントが新しいネットワークへ移行することによって生じる変更を 接続が生き延びることができる。本節では、エンドポイントが新しいアドレスへ移行する プロセスを説明する。¶
QUICの設計は、エンドポイントがハンドシェイク期間中に安定したアドレスを 保持することに依存する。エンドポイントは、Section 4.1.2 of [QUIC-TLS]で定義されるように、 ハンドシェイクが確認される前に接続移行を開始してはならない(MUST NOT)。¶
ピアがdisable_active_migrationトランスポートパラメーターを送信した場合、 エンドポイントは、ピアのpreferred_addressトランスポートパラメーターに基づいて動作した場合を除き、 ハンドシェイク中にピアが使用したアドレスへ、異なるローカルアドレスからパケット (プローブパケットを含む。Section 9.1を参照)を送信してはならない(MUST NOT)。 ピアがこの要件に違反した場合、エンドポイントは、そのパス上の到着パケットを Stateless Resetを生成せずに破棄するか、パス検証を進めてピアの移行を許可しなければならない (MUST)。Stateless Resetを生成したり接続を閉じたりすると、 ネットワーク内の第三者が観測されたトラフィックを偽装または操作することにより、 接続を閉じさせることが可能になる。¶
ピアアドレスのすべての変更が意図的な、または能動的な移行であるとは限らない。 ピアはNAT再バインディングを経験する可能性がある。これはミドルボックス、通常はNATが フローに対して新しい送信ポート、あるいは新しい送信IPアドレスを割り当てることによる アドレス変更である。エンドポイントは、ピアのアドレスへの変更を検出した場合、 そのアドレスを以前に検証していない限り、パス検証(Section 8.2)を実行しなければならない(MUST)。¶
エンドポイントがパケットを送信できる検証済みパスを持たない場合、 接続状態を破棄してもよい(MAY)。接続移行に対応できるエンドポイントは、接続状態を破棄する前に、 新しいパスが利用可能になるのを待ってもよい(MAY)。¶
本文書は、Section 9.6で 説明される場合を除き、新しいクライアントアドレスへの接続移行に制限する。 すべての移行の開始はクライアントの責任である。サーバーは、そのアドレスから非プローブ パケットを確認するまで、クライアントアドレスへ非プローブパケット (Section 9.1を参照)を送信しない。 クライアントが未知のサーバーアドレスからパケットを受信した場合、クライアントは これらのパケットを破棄しなければならない(MUST)。¶
エンドポイントは、接続を新しいローカルアドレスへ移行する前に、 パス検証(Section 8.2)を用いて 新しいローカルアドレスからのピア到達可能性を探査してもよい(MAY)。 パス検証の失敗は、その新しいパスがこの接続では使用できないことを意味するだけである。 パスを検証できないことは、有効な代替パスが利用可能でない場合を除き、接続を 終了させない。¶
PATH_CHALLENGE、PATH_RESPONSE、NEW_CONNECTION_ID、およびPADDINGフレームは 「プローブフレーム」であり、その他すべてのフレームは「非プローブフレーム」である。 プローブフレームのみを含むパケットは「プローブパケット」であり、その他のフレームを 含むパケットは「非プローブパケット」である。¶
エンドポイントは、新しいローカルアドレスから非プローブフレームを 含むパケットを送信することで、接続を新しいローカルアドレスへ移行できる。¶
各エンドポイントは、接続確立中にピアのアドレスを検証する。 したがって、移行するエンドポイントは、ピアが現在のアドレスで受信する意思があることを 知ったうえでピアへ送信できる。したがって、エンドポイントは最初にピアのアドレスを 検証せずに新しいローカルアドレスへ移行できる。¶
新しいパス上で到達可能性を確立するため、エンドポイントは 新しいパス上でパス検証(Section 8.2)を開始する。 エンドポイントは、ピアがその新しいアドレスへ次の非プローブフレームを送信するまで、 パス検証を延期してもよい(MAY)。¶
移行時、新しいパスはエンドポイントの現在の送信レートをサポートしない 可能性がある。したがって、エンドポイントはSection 9.4で 説明されるように、輻輳制御器とRTT推定値をリセットする。¶
新しいパスは同じECN能力を持たない可能性がある。したがって、 エンドポイントはSection 13.4で説明されるように ECN能力を検証する。¶
非プローブフレームを含むパケットを新しいピアアドレスから受信することは、 ピアがそのアドレスへ移行したことを示す。¶
受信者が移行を許可する場合、以後のパケットを新しいピアアドレスへ 送信しなければならず(MUST)、検証がまだ進行中でない場合は ピアがそのアドレスを所有していることを確認するためにパス検証 (Section 8.2)を開始しなければならない (MUST)。受信者がピアからの未使用の接続IDを持たない場合、 ピアが接続IDを提供するまで新しいパス上では何も送信できない。 Section 9.5を参照。¶
エンドポイントは、最も大きい番号の非プローブパケットへの応答としてのみ、 パケット送信先アドレスを変更する。これにより、並べ替えられたパケットを受信した場合に、 エンドポイントが古いピアアドレスへパケットを送信しないことが保証される。¶
エンドポイントは、未検証のピアアドレスへデータを送信してもよい (MAY)が、Sections 9.3.1および 9.3.2で説明される潜在的攻撃から 保護しなければならない(MUST)。エンドポイントは、 そのアドレスを最近確認している場合、ピアアドレスの検証を省略してもよい (MAY)。特に、何らかの偽の移行を検出した後に、 エンドポイントが以前に検証されたパスへ戻る場合、アドレス検証を省略し、 損失検出および輻輳状態を復元することで、攻撃による性能への影響を低減できる。¶
非プローブパケットの送信先アドレスを変更した後、エンドポイントは 他のアドレスに対する任意のパス検証を放棄できる。¶
新しいピアアドレスからパケットを受信することは、ピアにおける NAT再バインディングの結果である可能性がある。¶
新しいクライアントアドレスを検証した後、サーバーは新しい アドレス検証トークン(Section 8)を クライアントへ送信するべきである(SHOULD)。¶
ピアが送信元アドレスを偽装し、エンドポイントに対して望まないホストへ 過剰な量のデータを送信させる可能性がある。エンドポイントが偽装しているピアより 著しく多くのデータを送信する場合、接続移行は、攻撃者が被害者へ生成できる データ量を増幅するために使用される可能性がある。¶
Section 9.3で説明されるように、エンドポイントは、ピアが新しいアドレスを 所有していることを確認するため、ピアの新しいアドレスを検証することを要求される。 ピアのアドレスが有効と見なされるまで、エンドポイントはそのアドレスへ送信する データ量を制限する。Section 8を参照。 この制限がない場合、エンドポイントは無防備な被害者に対するサービス拒否攻撃に 使用される危険がある。¶
エンドポイントが上で説明したようにピアアドレスの検証を省略する場合、 送信レートを制限する必要はない。¶
オンパス攻撃者は、パケットをコピーし、元のパケットより先に 到着するよう偽装アドレス付きで転送することで、偽の接続移行を引き起こす可能性がある。 偽装アドレス付きのパケットは移行中の接続から来たように見え、元のパケットは重複として 見なされ破棄される。偽の移行後、送信元アドレスの検証は失敗する。 これは、その送信元アドレスにいるエンティティが、たとえ応答したいとしても、 送信されたPATH_CHALLENGEフレームを読み取ったり応答したりするために必要な 暗号鍵を持っていないためである。¶
そのような偽の移行によって接続が失敗することから保護するため、 エンドポイントは、新しいピアアドレスの検証が失敗した場合、最後に検証された ピアアドレスの使用に戻らなければならない(MUST)。 さらに、正当なピアアドレスからより大きいパケット番号のパケットを受信すると、 別の接続移行が発生する。これにより、偽の移行のアドレス検証は放棄され、 攻撃者が単一パケットを注入して開始した移行が封じ込められる。¶
エンドポイントが最後に検証されたピアアドレスに関する状態を持たない場合、 すべての接続状態を破棄して接続を静かに閉じなければならない (MUST)。これにより、その接続上の新しいパケットは 汎用的に処理される。たとえば、エンドポイントは以後の任意の到着パケットに応答して Stateless Resetを送信してもよい(MAY)。¶
パケットを観測できるオフパス攻撃者は、本物のパケットのコピーを エンドポイントへ転送する可能性がある。コピーされたパケットが本物のパケットより先に 到着すると、これはNAT再バインディングのように見える。本物のパケットは重複として 破棄される。攻撃者がパケットを転送し続けられる場合、攻撃者経由のパスへ移行させる ことが可能になることがある。これにより攻撃者はオンパスとなり、以後のすべての パケットを観測または破棄できる能力を得る。¶
この形式の攻撃は、攻撃者がエンドポイント間の直接パスとおおむね同じ特性を 持つパスを使用することに依存する。送信されるパケットが比較的少ない場合、または パケット損失が攻撃試行と一致する場合、この攻撃はより信頼性が高くなる。¶
最大受信パケット番号を増加させる非プローブパケットが元のパスで 受信されると、エンドポイントはそのパスへ戻る。このパス上でパケットを引き出すことにより、 攻撃が成功しない可能性が高まる。したがって、この攻撃の軽減はパケット交換を 誘発することに依存する。¶
見かけ上の移行に応答して、エンドポイントは以前にアクティブだったパスを PATH_CHALLENGEフレームで検証しなければならない(MUST)。これにより、そのパス上で新しいパケットの送信が 誘発される。パスがもはや利用可能でない場合、検証試行はタイムアウトして失敗する。 パスが利用可能だがもはや望まれない場合、検証は成功するが、そのパス上で プローブパケットが送信されるだけである。¶
アクティブなパス上でPATH_CHALLENGEを受信したエンドポイントは、 応答として非プローブパケットを送信するべきである(SHOULD)。攻撃者が作成したコピーより先に非プローブパケットが 到着すると、その接続は元のパスへ移行し直される。以後に別のパスへの移行が発生すると、 このプロセス全体が再開される。¶
この防御は不完全であるが、重大な問題とは見なされない。 元のパスを使用しようと複数回試みたにもかかわらず、攻撃経由のパスが 確実に元のパスより高速である場合、それを攻撃と経路改善とで区別することはできない。¶
エンドポイントは、この形式の攻撃の検出を改善するためにヒューリスティックを 使用することもできる。たとえば、古いパス上で最近パケットを受信していた場合、 NAT再バインディングは起こりにくい。同様に、IPv6パスでは再バインディングはまれである。 エンドポイントは重複パケットを探すこともできる。逆に、接続IDの変更は、 攻撃ではなく意図的な移行を示す可能性が高い。¶
新しいパスで利用可能な容量は、古いパスと同じではない可能性がある。 古いパス上で送信されたパケットは、新しいパスの輻輳制御またはRTT推定に寄与してはならない (MUST NOT)。¶
ピアが新しいアドレスを所有していることを確認したとき、エンドポイントは、 ピアのアドレスの変化がポート番号のみである場合を除き、新しいパスの輻輳制御器および 往復時間推定器を初期値へ直ちにリセットしなければならない(MUST) ([QUIC-RECOVERY]のAppendices A.3および B.3を参照)。 ポートのみの変更は一般にNAT再バインディングまたはその他のミドルボックス動作の結果であるため、 エンドポイントはそのような場合、初期値へ戻す代わりに輻輳制御状態と往復時間推定値を 保持してもよい(MAY)。古いパスから保持された輻輳制御状態が、 著しく異なる特性を持つ新しいパスで使用される場合、送信者は輻輳制御器とRTT推定器が 適応するまで過度に積極的に送信する可能性がある。一般に、実装は新しいパスで以前の値を 使用する際に慎重であることが推奨される。¶
移行期間中にエンドポイントが複数のアドレスから、または複数のアドレスへ データとプローブを送信すると、結果として生じる2つのパスが異なる往復時間を 持つ可能性があるため、受信者では見かけ上の並べ替えが発生しうる。複数のパス上で パケットを受信する受信者は、それでも受信したすべてのパケットを対象とするACKフレームを 送信する。¶
接続移行中に複数のパスが使用される可能性はあるが、単一の輻輳制御 コンテキストと単一の損失回復コンテキスト([QUIC-RECOVERY]で 説明されるもの)で十分な場合がある。たとえば、エンドポイントは、古いパスがもはや 必要ないことが確認されるまで(Section 9.3.3で説明される場合など)、 新しい輻輳制御コンテキストへの切り替えを遅延させることがある。¶
送信者は、プローブパケットについて例外を設け、その損失検出が独立し、 輻輳制御器が送信レートを不当に低下させないようにできる。エンドポイントは、 PATH_CHALLENGEが送信されたときに別のタイマーを設定し、対応するPATH_RESPONSEを 受信した場合にそれをキャンセルすることがある。PATH_RESPONSEを受信する前にタイマーが 発火した場合、エンドポイントは新しいPATH_CHALLENGEを送信し、より長い期間でタイマーを 再開することがある。このタイマーは、Section 6.2.1 of [QUIC-RECOVERY]で 説明されるように設定されるべきであり(SHOULD)、それより積極的であってはならない (MUST NOT)。¶
複数のネットワークパス上で安定した接続IDを使用すると、 受動的なオブザーバーがそれらのパス間の活動を相関付けられる。ネットワーク間を 移動するエンドポイントは、ピア以外のエンティティによって自身の活動を相関付けられることを 望まない可能性があるため、Section 5.1で述べたように、異なるローカルアドレスから送信するときには 異なる接続IDが使用される。これを有効にするため、エンドポイントは、自身が提供する 接続IDが他の任意のエンティティによって関連付けられないことを保証する必要がある。¶
任意の時点で、エンドポイントは送信に使用するDestination Connection IDを、 別のパスで使用されていない値に変更してもよい(MAY)。¶
エンドポイントは、複数のローカルアドレスから送信する場合に接続IDを 再使用してはならない(MUST NOT)。たとえば、 Section 9.2で説明される接続移行を 開始するとき、またはSection 9.1で説明されるように 新しいネットワークパスを探査するときである。¶
同様に、エンドポイントは複数の宛先アドレスへ送信する場合に接続IDを 再使用してはならない(MUST NOT)。ピアの制御外の ネットワーク変化により、エンドポイントが同じDestination Connection IDフィールド値を持つ 新しい送信元アドレスからパケットを受信することがある。この場合、エンドポイントは 同じローカルアドレスから送信し続ける限り、新しいリモートアドレスで現在の接続IDを 使用し続けてもよい(MAY)。¶
接続ID再使用に関するこれらの要件は、パケットの送信にのみ適用される。 接続IDを変更せずに意図しないパス変更が発生する可能性があるためである。 たとえば、ネットワーク非活動期間の後、クライアントが送信を再開したときに NAT再バインディングによりパケットが新しいパス上で送信されることがある。 エンドポイントはそのようなイベントにSection 9.3で説明されるように応答する。¶
各新しいネットワークパスで両方向に送信されるパケットに異なる接続IDを 使用すると、異なるネットワークパスにまたがる同じ接続のパケットを関連付けるために 接続IDを使用することが排除される。ヘッダー保護により、パケット番号を用いて活動を 相関付けられないことが保証される。これは、タイミングやサイズなど、パケットの他の性質を 用いて活動を相関付けることを防ぐものではない。¶
エンドポイントは、長さ0の接続IDを要求したピアとの移行を開始するべきではない (SHOULD NOT)。新しいパス上のトラフィックが、古いパス上の トラフィックと容易に関連付けられる可能性があるためである。サーバーが長さ0の 接続IDを持つパケットを正しい接続に関連付けられる場合、それはサーバーがパケットを 多重分離するために他の情報を使用していることを意味する。たとえば、サーバーは すべてのクライアントに一意のアドレスを提供する場合がある。たとえば、 HTTP代替サービス[ALTSVC]を使用する場合である。 複数のネットワークパスにわたってパケットを正しく経路付けできる情報は、ピア以外の エンティティによってそれらのパス上の活動を関連付けることも可能にする。¶
クライアントは、非活動期間後にトラフィックを送信するとき、 新しい接続ID、送信元UDPポート、またはIPアドレス([RFC8981]を参照)へ 切り替えることで、関連付け可能性を低減したい場合がある。同時にパケットを送信する アドレスを変更すると、サーバーが接続移行を検出する可能性がある。これにより、 NAT再バインディングや本物の移行を経験しないクライアントであっても、移行をサポートする 機構が実行されることが保証される。アドレス変更は、ピアに輻輳制御状態を リセットさせる可能性がある(Section 9.4を参照)ため、 アドレスは低頻度でのみ変更されるべきである(SHOULD)。¶
利用可能な接続IDを使い果たしたエンドポイントは、新しいパスを探査したり、 移行を開始したりできず、ピアによるプローブまたは移行試行にも応答できない。 移行が可能であり、異なるパスで送信されるパケットを関連付けられないことを保証するため、 エンドポイントはピアが移行する前に新しい接続IDを提供するべきである (SHOULD)。Section 5.1.1を参照。 ピアが利用可能な接続IDを使い果たしている可能性がある場合、移行するエンドポイントは 新しいネットワークパス上で送信されるすべてのパケットにNEW_CONNECTION_IDフレームを 含めることができる。¶
QUICでは、サーバーが1つのIPアドレスで接続を受け入れ、 ハンドシェイク直後にこれらの接続をより優先されるアドレスへ転送しようとすることが できる。これは、クライアントが最初に複数のサーバーで共有されるアドレスへ接続するが、 接続安定性を保証するためにユニキャストアドレスを使用したい場合に特に有用である。 本節では、接続を優先サーバーアドレスへ移行するためのプロトコルを説明する。¶
接続途中で新しいサーバーアドレスへ接続を移行することは、本文書で 規定されるQUICのバージョンではサポートされない。クライアントがそのアドレスへの移行を 開始していないときに、新しいサーバーアドレスからパケットを受信した場合、クライアントは これらのパケットを破棄するべきである(SHOULD)。¶
サーバーはTLSハンドシェイクにpreferred_address トランスポートパラメーターを含めることで、優先アドレスを伝達する。¶
サーバーは、クライアントが自身のネットワーク接続に最も適したものを 選択できるように、各アドレスファミリー(IPv4およびIPv6)の優先アドレスを 伝達してもよい(MAY)。¶
ハンドシェイクが確認されると、クライアントはサーバーから提供された 2つのアドレスのうち1つを選択し、パス検証(Section 8.2を参照)を 開始するべきである(SHOULD)。クライアントは、preferred_addressトランスポート パラメーターまたはNEW_CONNECTION_IDフレームのいずれかから取得された、以前に 未使用の任意のアクティブな接続IDを使用してパケットを構築する。¶
パス検証が成功し次第、クライアントは新しい接続IDを使用して、 以後のすべてのパケットを新しいサーバーアドレスへ送信し始め、古いサーバーアドレスの 使用を中止するべきである(SHOULD)。パス検証が失敗した場合、クライアントは 以後のすべてのパケットをサーバーの元のIPアドレスへ送信し続けなければならない (MUST)。¶
優先アドレスへ移行するクライアントは、移行前に選択したアドレスを 検証しなければならない(MUST)。Section 21.5.3を参照。¶
サーバーは、接続を受け入れた後の任意の時点で、優先IPアドレス宛の パケットを受信する可能性がある。このパケットがPATH_CHALLENGEフレームを含む場合、 サーバーはSection 8.2に従って PATH_RESPONSEフレームを含むパケットを送信する。サーバーは、クライアントから 優先アドレス宛の非プローブパケットを受信し、かつ新しいパスを検証するまで、 元のアドレスから非プローブパケットを送信しなければならない (MUST)。¶
サーバーは、優先アドレスからクライアントへのパス上で探査しなければならない (MUST)。これは、攻撃者によって開始される偽の移行に 備えるのに役立つ。¶
サーバーが自身のパス検証を完了し、優先アドレスで新しい最大パケット番号を 持つ非プローブパケットを受信すると、サーバーは優先IPアドレスからのみ クライアントへ非プローブパケットを送信し始める。サーバーは、古いIPアドレスで 受信されたこの接続のより新しいパケットを破棄するべきである (SHOULD)。サーバーは、古いIPアドレスで受信された 遅延パケットを処理し続けてもよい(MAY)。¶
サーバーがpreferred_addressトランスポートパラメーターで提供する アドレスは、それらが提供された接続でのみ有効である。クライアントは、現在の接続から 再開された接続を含め、他の接続でこれらを使用してはならない (MUST NOT)。¶
クライアントは、サーバーの優先アドレスへ移行する前に 接続移行を実行する必要があるかもしれない。この場合、クライアントは、 クライアントの新しいアドレスからサーバーの元のアドレスと優先アドレスの両方へ 同時にパス検証を実行するべきである(SHOULD)。¶
サーバーの優先アドレスのパス検証が成功した場合、クライアントは 元のアドレスの検証を放棄し、サーバーの優先アドレスの使用へ移行しなければならない (MUST)。サーバーの優先アドレスのパス検証が失敗したが、 サーバーの元のアドレスの検証が成功した場合、クライアントは自身の新しいアドレスへ 移行し、サーバーの元のアドレスへ送信し続けてもよい(MAY)。¶
サーバーの優先アドレスで受信されたパケットが、ハンドシェイク中に クライアントから観測されたものと異なる送信元アドレスを持つ場合、サーバーは Sections 9.3.1および9.3.2で 説明される潜在的攻撃から保護しなければならない(MUST)。意図的な同時移行に加え、これはクライアントの アクセスネットワークがサーバーの優先アドレスに対して異なるNATバインディングを 使用したために発生する可能性もある。¶
サーバーは、異なるアドレスからプローブパケットを受信したとき、 クライアントの新しいアドレスへのパス検証を開始するべきである (SHOULD)。Section 8を参照。¶
新しいアドレスへ移行するクライアントは、サーバーについて同じ アドレスファミリーの優先アドレスを使用するべきである (SHOULD)。¶
preferred_addressトランスポートパラメーターで提供される接続IDは、 提供されるアドレスに固有ではない。この接続IDは、クライアントが移行のために 利用可能な接続IDを持つことを保証するために提供されるが、クライアントは任意のパスで この接続IDを使用してもよい(MAY)。¶
IPv6を使用してデータを送信するエンドポイントは、ローカルAPIが IPv6フローラベルの設定を許可しない場合を除き、[RFC6437]に 準拠してIPv6フローラベルを適用するべきである(SHOULD)。¶
フローラベルの生成は、以前に使用されたフローラベルとの関連付け可能性を 最小化するように設計されなければならない(MUST)。 安定したフローラベルは複数のパス上の活動を相関付けることを可能にするためである。 Section 9.5を参照。¶
[RFC6437]は、 擬似ランダム関数を使用して値を導出し、フローラベルを生成することを提案している。 フローラベルを生成する際に送信元および宛先アドレスに加えて Destination Connection IDフィールドを含めることで、他の観測可能な識別子の変更と 変更が同期されることが保証される。これらの入力をローカル秘密と組み合わせる 暗号学的ハッシュ関数は、これを実装する1つの方法である。¶
確立されたQUIC接続は、次の3つの方法のいずれかで終了できる。¶
エンドポイントは、パケットを送信できる検証済みパスを持たない場合、 接続状態を破棄してもよい(MAY)。Section 8.2を参照。¶
いずれかのエンドポイントがトランスポートパラメーター (Section 18.2)で max_idle_timeoutを指定した場合、両方のエンドポイントが通知したmax_idle_timeout値の 最小値より長くアイドル状態が続くと、接続は静かに閉じられ、その状態は破棄される。¶
各エンドポイントはmax_idle_timeoutを通知するが、エンドポイントでの 有効値は、通知された2つの値の最小値(または、非ゼロ値を通知したエンドポイントが 1つだけの場合は、その唯一の通知値)として計算される。max_idle_timeoutを通知することにより、 エンドポイントは、有効値より前に接続を放棄する場合、即時クローズ (Section 10.2)を開始することを約束する。¶
エンドポイントは、ピアからのパケットを受信して正常に処理したときに、 アイドルタイマーを再開する。エンドポイントはまた、最後にパケットを受信して処理してから 他のACKを誘発するパケットを送信していない場合、ACKを誘発するパケットを送信するときにも アイドルタイマーを再開する。パケット送信時にこのタイマーを再開することで、新しい活動が 開始された後に接続が閉じられないことが保証される。¶
過度に短いアイドルタイムアウト期間を避けるため、エンドポイントは アイドルタイムアウト期間を現在のProbe Timeout(PTO)の少なくとも3倍に増加させなければならない (MUST)。これにより、アイドルタイムアウトの前に複数のPTOが満了し、 したがって複数のプローブが送信され、失われることが許容される。¶
有効タイムアウトの近くでパケットを送信するエンドポイントは、 そのパケットが到着する前にピアでアイドルタイムアウト期間が満了している可能性があるため、 ピアで破棄される危険がある。¶
ピアが間もなくタイムアウトする可能性がある場合、たとえばPTO以内である場合、 エンドポイントは接続の生存性をテストするためにPINGまたは別のACKを誘発するフレームを 送信できる。Section 6.2 of [QUIC-RECOVERY]を参照。これは、利用可能なアプリケーションデータを 安全に再試行できない場合に特に有用である。どのデータを再試行して安全かは アプリケーションが判断することに注意すること。¶
エンドポイントは、応答データを期待しているがアプリケーションデータを 持たない、または送信できない場合、アイドルタイムアウトを避けるために ACKを誘発するパケットを送信する必要があるかもしれない。¶
QUICの実装は、アプリケーションにアイドルタイムアウトを延期するための オプションを提供することがある。この機能は、アプリケーションが開いている接続に 関連付けられた状態を失うことを避けたいが、しばらくの間アプリケーションデータを 交換することを期待しない場合に使用できる。このオプションにより、エンドポイントは PINGフレーム(Section 19.2)を定期的に 送信でき、これによってピアはアイドルタイムアウト期間を再開する。PINGフレームを含む パケットの送信は、これがパケット受信後に送信される最初のACKを誘発するパケットである場合、 このエンドポイントのアイドルタイムアウトも再開する。PINGフレームの送信により、 ピアは確認応答で応答し、これもエンドポイントのアイドルタイムアウトを再開する。¶
QUICを使用するアプリケーションプロトコルは、いつアイドルタイムアウトの 延期が適切かについて指針を提供するべきである(SHOULD)。不要なPINGフレームの送信は性能に悪影響を 及ぼす可能性がある。¶
max_idle_timeoutトランスポートパラメーターを使用して ネゴシエーションされた時間より長い期間、パケットが送信または受信されない場合、 接続はタイムアウトする。Section 10を参照。 ただし、ミドルボックス内の状態はそれより早くタイムアウトする可能性がある。 [RFC4787]のREQ-5は2分のタイムアウト間隔を 推奨しているが、経験上、UDPフローについて大多数のミドルボックスが状態を失うことを 防ぐには、30秒ごとにパケットを送信する必要がある [GATEWAY]。¶
エンドポイントは、接続を直ちに終了するためにCONNECTION_CLOSEフレーム (Section 19.19)を送信する。CONNECTION_CLOSEフレームにより、 すべてのストリームは直ちに閉じた状態になる。開いているストリームは暗黙に リセットされたと仮定できる。¶
CONNECTION_CLOSEフレームを送信した後、エンドポイントは直ちに closing状態に入る。Section 10.2.1を参照。 CONNECTION_CLOSEフレームを受信した後、エンドポイントはdraining状態に入る。 Section 10.2.2を参照。¶
プロトコル違反は即時クローズにつながる。¶
アプリケーションプロトコルが接続を閉じるよう手配した後、 即時クローズを使用できる。これは、アプリケーションプロトコルが正常なシャットダウンを ネゴシエーションした後である可能性がある。アプリケーションプロトコルは、 両方のアプリケーションエンドポイントが接続を閉じられることに合意するために必要な メッセージを交換でき、その後アプリケーションはQUICに接続を閉じるよう要求する。 その結果QUICが接続を閉じるとき、アプリケーションが提供したエラーコードを持つ CONNECTION_CLOSEフレームが、ピアへクローズを通知するために使用される。¶
closingおよびdraining接続状態は、接続がきれいに閉じられ、 遅延または並べ替えられたパケットが適切に破棄されることを保証するために存在する。 これらの状態は、[QUIC-RECOVERY]で 定義される現在のPTO間隔の少なくとも3倍の期間継続するべきである (SHOULD)。¶
closingまたはdraining状態を終了する前に接続状態を破棄すると、 遅れて到着したパケットを受信したときに、エンドポイントが不要なStateless Resetを 生成する結果となる可能性がある。UDPソケットを閉じられるものなど、遅れて到着した パケットが応答を誘発しないことを保証する代替手段を持つエンドポイントは、 より迅速なリソース回収を可能にするため、これらの状態をより早く終了してもよい (MAY)。新しい接続を受け入れるために開いたソケットを 保持するサーバーは、closingまたはdraining状態を早期に終了するべきではない (SHOULD NOT)。¶
closingまたはdraining状態が終了すると、エンドポイントはすべての 接続状態を破棄するべきである(SHOULD)。エンドポイントは、この接続に属する以後の任意の到着パケットに 応答してStateless Resetを送信してもよい(MAY)。¶
エンドポイントは、即時クローズを開始した後にclosing状態に入る。¶
closing状態では、エンドポイントはCONNECTION_CLOSEフレームを含む パケットを生成し、パケットがその接続に属するものとして識別するために十分な情報のみを 保持する。closing状態のエンドポイントは、その接続に帰属させる任意の到着パケットに 応答して、CONNECTION_CLOSEフレームを含むパケットを送信する。¶
エンドポイントは、closing状態でパケットを生成するレートを制限する べきである(SHOULD)。たとえば、エンドポイントは 受信パケットへ応答する前に、受信パケット数または時間を段階的に増加させて 待機できる。¶
エンドポイントが選択した接続IDとQUICバージョンは、closing状態の 接続に対するパケットを識別するのに十分な情報である。エンドポイントは他のすべての 接続状態を破棄してもよい(MAY)。closing中のエンドポイントは、受信したフレームを 処理することを要求されない。エンドポイントは、CONNECTION_CLOSEフレームを読み取って 処理できるよう、到着パケット用のパケット保護鍵を保持してもよい (MAY)。¶
エンドポイントは、closing状態へ入るときにパケット保護鍵を破棄し、 受信した任意のUDPデータグラムに応答してCONNECTION_CLOSEフレームを含むパケットを 送信してもよい(MAY)。ただし、パケット保護鍵を 破棄したエンドポイントは、無効なパケットを識別して破棄できない。 増幅攻撃に使用されることを避けるため、そのようなエンドポイントは、送信する パケットの累積サイズを、受信され接続に帰属されたパケットの累積サイズの3倍に 制限しなければならない(MUST)。closing中の接続について エンドポイントが維持する状態を最小化するため、エンドポイントは受信した任意の パケットに応答してまったく同じパケットを送信してもよい(MAY)。¶
closing状態にある間、エンドポイントは新しい送信元アドレスからの パケットを受信する可能性があり、これは接続移行を示しているかもしれない。 Section 9を参照。closing状態のエンドポイントは、 未検証アドレスから受信されたパケットを破棄するか、未検証アドレスへ送信する パケットの累積サイズを、そのアドレスから受信するパケットサイズの3倍に制限しなければならない (MUST)。¶
エンドポイントは、closing中に鍵更新を処理することは期待されない (Section 6 of [QUIC-TLS])。鍵更新により、エンドポイントが以後に受信する パケットを処理できなくなるため、closing状態からdraining状態へ移行できなくなる可能性が あるが、それ以外の影響はない。¶
draining状態には、エンドポイントがCONNECTION_CLOSEフレームを 受信すると入る。これはピアがclosingまたはdraining中であることを示す。 その他の点ではclosing状態と同一だが、draining状態のエンドポイントは いかなるパケットも送信してはならない(MUST NOT)。接続がdraining状態に入ると、パケット保護鍵を 保持する必要はない。¶
CONNECTION_CLOSEフレームを受信したエンドポイントは、 draining状態に入る前に、適切であればNO_ERRORコードを使用して、CONNECTION_CLOSEフレームを 含む単一のパケットを送信してもよい(MAY)。エンドポイントは以後のパケットを送信してはならない (MUST NOT)。そうすると、いずれかのエンドポイントが closing状態を終了するまで、CONNECTION_CLOSEフレームの定常的な交換が発生する可能性がある。¶
エンドポイントは、ピアもclosingまたはdraining中であることを示す CONNECTION_CLOSEフレームを受信した場合、closing状態からdraining状態に入ってもよい (MAY)。この場合、draining状態はclosing状態が終了するはずだった 時点で終了する。言い換えると、エンドポイントは同じ終了時刻を使用するが、 この接続上でのすべてのパケット送信を停止する。¶
CONNECTION_CLOSEフレームを送信するときの目標は、ピアがそのフレームを 処理することを保証することである。一般に、これはパケットが破棄されることを避けるため、 最も高いレベルのパケット保護を持つパケットでフレームを送信することを意味する。 ハンドシェイクが確認された後(Section 4.1.2 of [QUIC-TLS]を参照)、エンドポイントは任意の CONNECTION_CLOSEフレームを1-RTTパケットで送信しなければならない (MUST)。ただし、ハンドシェイク確認前には、より高度な パケット保護鍵がピアで利用可能でない可能性があるため、より低いパケット保護レベルを 使用するパケットで別のCONNECTION_CLOSEフレームを送信してもよい (MAY)。より具体的には次のとおりである。¶
InitialまたはHandshakeパケットで0x1d型のCONNECTION_CLOSEを 送信すると、アプリケーション状態を露出したり、アプリケーション状態の変更に使用されたりする 可能性がある。0x1d型のCONNECTION_CLOSEは、InitialまたはHandshakeパケットでフレームを 送信する場合、0x1c型のCONNECTION_CLOSEに置き換えられなければならない (MUST)。そうしないと、アプリケーション状態に関する情報が 明らかになる可能性がある。エンドポイントはReason Phraseフィールドの値を クリアしなければならず(MUST)、0x1c型のCONNECTION_CLOSEへ変換する際には APPLICATION_ERRORコードを使用するべきである(SHOULD)。¶
複数のパケット種別で送信されるCONNECTION_CLOSEフレームは、 単一のUDPデータグラムに結合できる。Section 12.2を参照。¶
エンドポイントはInitialパケットでCONNECTION_CLOSEフレームを送信できる。 これはInitialまたはHandshakeパケットで受信された未認証情報への応答である可能性がある。 そのような即時クローズは、正当な接続をサービス拒否にさらす可能性がある。 QUICはハンドシェイク中のオンパス攻撃に対する防御手段を含まない。 Section 21.2を参照。ただし、 正当なピアに対するエラーに関するフィードバックを減らす代償として、 エンドポイントがCONNECTION_CLOSEで接続を終了するのではなく不正なパケットを破棄する場合、 攻撃者にとって一部の形態のサービス拒否はより困難になる。この理由から、 エンドポイントは、認証を欠くパケットでエラーが検出された場合、直ちに閉じるのではなく パケットを破棄してもよい(MAY)。¶
Initialパケットでエラーを検出したサーバーなど、状態を確立していない エンドポイントはclosing状態に入らない。接続の状態を持たないエンドポイントは、 CONNECTION_CLOSEフレームを送信してもclosingまたはdraining期間に入らない。¶
ステートレスリセットは、接続の状態にアクセスできないエンドポイントのための 最後の手段としてのオプションとして提供される。クラッシュまたは停止により、ピアが接続を 適切に継続できないエンドポイントへデータを送信し続ける可能性がある。エンドポイントは、 アクティブな接続に関連付けられないパケットを受信したことへの応答として、 Stateless Resetを送信してもよい(MAY)。¶
ステートレスリセットは、アクティブな接続におけるエラーを示すには 適切ではない。致命的な接続エラーを通信したいエンドポイントは、可能であれば CONNECTION_CLOSEフレームを使用しなければならない(MUST)。¶
このプロセスをサポートするため、エンドポイントは推測困難な16バイト値である ステートレスリセットトークンを発行する。ピアが後で、そのステートレスリセットトークンで 終わるUDPデータグラムであるStateless Resetを受信すると、ピアは直ちに接続を終了する。¶
ステートレスリセットトークンは接続IDに固有である。エンドポイントは、 NEW_CONNECTION_IDフレームのStateless Reset Tokenフィールドに値を含めることで、 ステートレスリセットトークンを発行する。サーバーはまた、ハンドシェイク中に stateless_reset_tokenトランスポートパラメーターを発行でき、これはハンドシェイク中に サーバーが選択した接続IDに適用される。これらの交換は暗号化によって保護されるため、 クライアントとサーバーだけがその値を知る。クライアントのトランスポートパラメーターには 機密性保護がないため、クライアントはstateless_reset_tokenトランスポートパラメーターを 使用できないことに注意すること。¶
トークンは、関連付けられた接続IDがRETIRE_CONNECTION_IDフレーム (Section 19.16)によって廃止されると無効化される。¶
処理できないパケットを受信したエンドポイントは、次のレイアウトのパケットを 送信する(Section 1.3を参照)。¶
Stateless Reset {
Fixed Bits (2) = 1,
Unpredictable Bits (38..),
Stateless Reset Token (128),
}
この設計により、Stateless Resetは可能な限り、ショートヘッダーを持つ 通常のパケットと区別できないことが保証される。¶
Stateless Resetは、パケットヘッダーの最初の2ビットから始まる UDPデータグラム全体を使用する。最初のバイトの残りと、それに続く任意の数のバイトは、 ランダムと区別できないべき値に設定される(SHOULD)。 データグラムの最後の16バイトにはステートレスリセットトークンが含まれる。¶
意図された受信者以外のエンティティには、Stateless Resetは ショートヘッダーを持つパケットのように見える。Stateless Resetが有効なQUICパケットのように 見えるためには、Unpredictable Bitsフィールドに少なくとも38ビットのデータ (または5バイトから2つの固定ビットを除いたもの)を含める必要がある。¶
結果として得られる最小サイズ21バイトは、受信者が接続IDの使用を要求する場合、 Stateless Resetが他のパケットと区別しにくいことを保証しない。この目的を達成するため、 エンドポイントは、必要に応じてPADDINGフレームを追加し、送信するすべてのパケットが、 ピアに自身のパケットへ含めるよう要求する最小接続ID長より少なくとも22バイト長いことを 保証するべきである(SHOULD)。これにより、ピアによって送信される 任意のStateless Resetが、エンドポイントへ送信された有効なパケットと区別できないことが 保証される。43バイト以下のパケットに応答してStateless Resetを送信するエンドポイントは、 応答対象のパケットより1バイト短いStateless Resetを送信するべきである (SHOULD)。¶
これらの値は、ステートレスリセットトークンがパケット保護AEADの 最小拡張と同じ長さであることを仮定している。エンドポイントがより大きな最小拡張を持つ パケット保護方式をネゴシエーションしていた可能性がある場合、追加の予測困難なバイトが 必要である。¶
エンドポイントは、増幅に使用されることを避けるため、受信したパケットの 3倍以上大きいStateless Resetを送信してはならない(MUST NOT)。 Section 10.3.3ではStateless Resetサイズに対する 追加の制限を説明する。¶
エンドポイントは、有効なQUICパケットとして小さすぎるパケットを 破棄しなければならない(MUST)。例として、 [QUIC-TLS]で定義されるAEAD関数の集合では、 21バイト未満のショートヘッダーパケットは決して有効ではない。¶
エンドポイントは、ショートヘッダーを持つパケットとして整形された Stateless Resetを送信しなければならない(MUST)。 ただし、他のQUICバージョンではロングヘッダーの使用が許可される可能性があるため、 エンドポイントは、有効なステートレスリセットトークンで終わる任意のパケットを Stateless Resetとして扱わなければならない(MUST)。¶
エンドポイントは、ロングヘッダーを持つパケットに応答して Stateless Resetを送信してもよい(MAY)。Stateless Resetの送信は、 ステートレスリセットトークンがピアで利用可能になる前には有効ではない。このQUICバージョンでは、 ロングヘッダーを持つパケットは接続確立中にのみ使用される。ステートレスリセットトークンは 接続確立が完了するか完了間近になるまで利用可能でないため、ロングヘッダーを持つ未知の パケットを無視することは、Stateless Resetを送信するのと同程度に有効な場合がある。¶
エンドポイントは、ショートヘッダーを持つパケットからSource Connection IDを 判断できない。したがって、Stateless Reset内のDestination Connection IDを設定できない。 そのため、Destination Connection IDは以前のパケットで使用された値とは異なる。 ランダムなDestination Connection IDは、接続IDがNEW_CONNECTION_IDフレームを用いて 提供された新しい接続IDへ移動した結果のように見せる。 Section 19.15を参照。¶
ランダム化された接続IDを使用すると、次の2つの問題が生じる。¶
このステートレスリセット設計はQUICバージョン1に固有である。 複数のQUICバージョンをサポートするエンドポイントは、そのエンドポイントが サポートする可能性がある(または状態を失う前にサポートしていた可能性がある) 任意のバージョンをサポートするピアに受け入れられるStateless Resetを生成する必要がある。 新しいQUICバージョンの設計者はこれを認識し、(1)この設計を再使用するか、 (2)データを運ぶために最後の16バイト以外のパケット部分を使用する必要がある。¶
エンドポイントは、UDPデータグラムの末尾16バイトを使用して 潜在的なStateless Resetを検出する。エンドポイントは、最近送信したデータグラムについて、 接続IDおよびリモートアドレスに関連付けられたすべてのステートレスリセットトークンを 記憶する。これには、NEW_CONNECTION_IDフレームのStateless Reset Tokenフィールド値と、 サーバーのトランスポートパラメーターが含まれるが、未使用または廃止された接続IDに 関連付けられたステートレスリセットトークンは除外される。エンドポイントは、 データグラムの最後の16バイトを、そのデータグラムが受信されたリモートアドレスに 関連付けられたすべてのステートレスリセットトークンと比較することにより、 受信データグラムをStateless Resetとして識別する。¶
この比較はすべての到着データグラムに対して実行できる。 エンドポイントは、データグラム内のいずれかのパケットが正常に処理された場合、 この確認を省略してもよい(MAY)。ただし、到着データグラム内の 最初のパケットが接続に関連付けられない、または復号できない場合、比較は 実行されなければならない(MUST)。¶
エンドポイントは、使用していない接続IDに関連付けられた ステートレスリセットトークン、または廃止された接続IDについて確認してはならない (MUST NOT)。¶
データグラムをステートレスリセットトークン値と比較するとき、 エンドポイントはトークン値に関する情報を漏らさずに比較を実行しなければならない (MUST)。たとえば、この比較を定数時間で実行することで、 個々のステートレスリセットトークンの値をタイミングサイドチャネルによる情報漏えいから 保護する。別の方法として、ステートレスリセットトークンの生の値ではなく変換後の値を 保存して比較することもできる。この変換は、秘密鍵を使用する暗号学的に安全な 擬似ランダム関数(例: ブロック暗号、Hashed Message Authentication Code(HMAC) [RFC2104])として定義される。 エンドポイントは、パケットが正常に復号されたかどうか、または有効な ステートレスリセットトークンの数に関する情報を保護することは期待されない。¶
データグラムの最後の16バイトがステートレスリセットトークンと 同一の値である場合、エンドポイントはdraining期間に入り、この接続上で それ以上のパケットを送信してはならない(MUST)。¶
ステートレスリセットトークンは推測困難でなければならない (MUST)。ステートレスリセットトークンを作成するために、 エンドポイントは作成する各接続ごとに秘密をランダム生成できる [RANDOM]。しかし、これはクラスタ内に複数のインスタンスが ある場合には協調の問題を、状態を失う可能性があるエンドポイントには保存の問題を 引き起こす。ステートレスリセットは特に状態が失われた場合を扱うために存在するため、 この方法は最適ではない。¶
静的鍵と、エンドポイントによって選択された接続ID (Section 5.1を参照)を入力とする擬似ランダム関数を使用して証明を 生成することにより、同じエンドポイントへのすべての接続にわたって単一の静的鍵を 使用できる。エンドポイントはHMAC [RFC2104] (たとえば、HMAC(static_key, connection_id))またはHMAC-based Key Derivation Function (HKDF)[RFC5869] (たとえば、静的鍵を入力鍵材料として使用し、接続IDをsaltとして使用する)を 使用できる。この関数の出力を16バイトに切り詰め、その接続のステートレスリセット トークンを生成する。¶
状態を失ったエンドポイントは、同じ方法を使用して有効な ステートレスリセットトークンを生成できる。接続IDは、エンドポイントが受信する パケットから取得される。¶
この設計は、エンドポイントがパケットから接続IDを使用して接続を リセットできるように、ピアが常にパケット内で接続IDを送信することに依存する。 この設計を使用するエンドポイントは、すべての接続で同じ接続ID長を使用するか、 状態なしで復元できるよう接続IDの長さを符号化しなければならない (MUST)。さらに、長さ0の接続IDを提供できない。¶
ステートレスリセットトークンを明らかにすると、任意のエンティティが 接続を終了できるようになるため、その値は一度だけ使用できる。ステートレスリセット トークンを選択するこの方法は、接続IDと静的鍵の組み合わせが別の接続に使用されては ならない(MUST NOT)ことを意味する。同じ接続IDが静的鍵を 共有するインスタンスによって使用される場合、または攻撃者が、状態を持たないが 同じ静的鍵を持つインスタンスへパケットを経路付けさせることができる場合、 サービス拒否攻撃が可能である。Section 21.11を参照。 ステートレスリセットトークンを明らかにすることによってリセットされた接続の接続IDは、 静的鍵を共有するノードの新しい接続に再使用されてはならない(MUST NOT)。¶
同じステートレスリセットトークンは、複数の接続IDに使用されてはならない (MUST NOT)。エンドポイントは新しい値をすべての以前の値と 比較することを要求されないが、重複する値はPROTOCOL_VIOLATION型の接続エラーとして 扱ってもよい(MAY)。¶
Stateless Resetには暗号保護がないことに注意すること。¶
Stateless Resetの設計は、ステートレスリセットトークンを知らなければ 有効なパケットと区別できないようになっている。たとえば、サーバーが別のサーバーへ Stateless Resetを送信すると、応答として別のStateless Resetを受信する可能性があり、 それが無限の交換につながる可能性がある。¶
エンドポイントは、ループを防ぐのに十分な状態を維持している場合を除き、 送信するすべてのStateless Resetが、それを引き起こしたパケットより小さいことを 保証しなければならない(MUST)。ループが発生した場合、 これにより、パケットは最終的に小さすぎて応答を引き起こせなくなる。¶
エンドポイントは、送信したStateless Resetの数を記憶し、 上限に達したら新しいStateless Resetの生成を停止できる。異なるリモートアドレスに 別々の上限を使用することで、他のピアまたは接続が上限を使い果たした場合でも、 Stateless Resetを使用して接続を閉じられることが保証される。¶
41バイトより小さいStateless Resetは、ピアの接続IDの長さによっては、 オブザーバーにStateless Resetとして識別される可能性がある。逆に、小さいパケットに 応答してStateless Resetを送信しないと、非常に小さいパケットだけが送信される 壊れた接続の場合に、Stateless Resetが検出に有用でなくなる可能性がある。そのような 失敗は、タイマーなど他の手段によってのみ検出される可能性がある。¶
エラーを検出したエンドポイントは、そのエラーの存在をピアに通知するべきである (SHOULD)。トランスポートレベルとアプリケーションレベルの 両方のエラーは、接続全体に影響を与える可能性がある。Section 11.1を参照。 単一のストリームに分離できるのは、アプリケーションレベルのエラーのみである。 Section 11.2を参照。¶
エラーを通知するフレームには、最も適切なエラーコード (Section 20)を含めるべきである (SHOULD)。本仕様がエラー条件を識別する場合、 使用されるエラーコードも識別する。これらは要件として表現されているが、 実装戦略の違いにより、報告されるエラーが異なる可能性がある。特に、 エンドポイントはエラー条件を検出したとき、適用可能な任意のエラーコードを 使用してもよい(MAY)。汎用エラーコード (PROTOCOL_VIOLATIONやINTERNAL_ERRORなど)は、特定のエラーコードの代わりとして 常に使用できる。¶
ステートレスリセット(Section 10.3)は、 CONNECTION_CLOSEまたはRESET_STREAMフレームで通知できる任意のエラーには適さない。 接続上でフレームを送信するために必要な状態を持つエンドポイントは、 ステートレスリセットを使用してはならない(MUST NOT)。¶
プロトコル意味論の明らかな違反や、接続全体に影響する状態の破損など、 接続を使用不能にするエラーは、CONNECTION_CLOSEフレーム (Section 19.19)を用いて 通知されなければならない(MUST)。¶
アプリケーション固有のプロトコルエラーは、フレーム型0x1dの CONNECTION_CLOSEフレームを用いて通知される。本文書で説明されるすべてのエラーを含む、 トランスポートに固有のエラーは、フレーム型0x1cのCONNECTION_CLOSEフレームで運ばれる。¶
CONNECTION_CLOSEフレームは、失われるパケットで送信される可能性がある。 エンドポイントは、終了した接続上でさらにパケットを受信した場合、 CONNECTION_CLOSEフレームを含むパケットを再送信する準備をしておくべきである (SHOULD)。再送回数と、この最終パケットが送信される時間を 制限することで、終了した接続に費やされる労力を制限できる。¶
CONNECTION_CLOSEフレームを含むパケットを再送信しないことを選択する エンドポイントは、ピアが最初のそのようなパケットを見逃すリスクを負う。 終了した接続に対してデータを受信し続けるエンドポイントが利用できる唯一の機構は、 ステートレスリセット処理(Section 10.3)を試みることである。¶
InitialパケットのAEADは強い認証を提供しないため、エンドポイントは 無効なInitialパケットを破棄してもよい(MAY)。 本仕様がそれ以外の場合に接続エラーを要求している場合でも、Initialパケットの破棄は 許可される。エンドポイントは、そのパケット内のフレームを処理しない場合、または 任意の処理の効果を元に戻す場合にのみ、パケットを破棄できる。無効なInitialパケットの 破棄は、サービス拒否への露出を低減するために使用される可能性がある。 Section 21.2を参照。¶
アプリケーションレベルのエラーが単一のストリームに影響するが、 接続はそれ以外の点で回復可能な状態のままである場合、エンドポイントは適切な エラーコードを持つRESET_STREAMフレーム(Section 19.4)を 送信して、影響を受けたストリームのみを終了できる。¶
アプリケーションプロトコルの関与なしにストリームをリセットすると、 アプリケーションプロトコルが回復不能な状態に入る可能性がある。RESET_STREAMは、 QUICを使用するアプリケーションプロトコルによってのみ開始されなければならない (MUST)。¶
RESET_STREAMで運ばれるアプリケーションエラーコードの意味論は、 アプリケーションプロトコルによって定義される。ストリームを終了させることができるのは、 アプリケーションプロトコルのみである。アプリケーションプロトコルのローカルインスタンスは 直接のAPI呼び出しを使用し、リモートインスタンスはSTOP_SENDINGフレームを使用する。 これは自動的なRESET_STREAMを引き起こす。¶
アプリケーションプロトコルは、いずれかのエンドポイントによって早期に キャンセルされたストリームを処理するための規則を定義するべきである (SHOULD)。¶
QUICエンドポイントは、パケットを交換することで通信する。パケットは 機密性および完全性の保護を持つ。Section 12.1を参照。 パケットはUDPデータグラムで運ばれる。Section 12.2を参照。¶
このQUICバージョンは、接続確立中にロングパケットヘッダーを使用する。 Section 17.2を参照。ロングヘッダーを持つパケットは、 Initial(Section 17.2.2)、0-RTT(Section 17.2.3)、Handshake(Section 17.2.4)、およびRetry(Section 17.2.5)である。 バージョンネゴシエーションは、ロングヘッダーを持つバージョン非依存のパケットを使用する。 Section 17.2.1を参照。¶
ショートヘッダーを持つパケットは、最小限のオーバーヘッドのために設計され、 接続が確立されて1-RTT鍵が利用可能になった後に使用される。 Section 17.3を参照。¶
QUICパケットは、パケットの種類に基づき、異なるレベルの暗号保護を持つ。 パケット保護の詳細は[QUIC-TLS]にある。本節では、提供される保護の概要を含める。¶
Version Negotiationパケットには暗号保護がない。[QUIC-INVARIANTS]を参照。¶
Retryパケットは、偶発的な変更から保護するためにAEAD関数 [AEAD]を使用する。¶
InitialパケットはAEAD関数を使用し、その鍵はネットワーク上で見える値を 使用して導出される。したがって、Initialパケットは有効な機密性保護を持たない。 Initial保護は、パケットの送信者がネットワークパス上にいることを保証するために存在する。 クライアントからInitialパケットを受信する任意のエンティティは、そのパケットの内容を 読み取ることと、どちらのエンドポイントでも正常に認証されるInitialパケットを生成することの 両方を可能にする鍵を復元できる。AEADはInitialパケットを偶発的な変更からも保護する。¶
その他すべてのパケットは、暗号ハンドシェイクから導出された鍵で保護される。 暗号ハンドシェイクにより、通信しているエンドポイントのみが、Handshake、0-RTT、および 1-RTTパケットに対応する鍵を受信することが保証される。0-RTTおよび1-RTT鍵で保護された パケットは、強い機密性および完全性の保護を持つ。¶
一部のパケット種別に現れるPacket Numberフィールドには、 ヘッダー保護の一部として適用される代替の機密性保護がある。詳細は Section 5.4 of [QUIC-TLS]を参照。 基礎となるパケット番号は、与えられたパケット番号空間で送信される各パケットごとに 増加する。詳細はSection 12.3を参照。¶
Initial(Section 17.2.2)、 0-RTT(Section 17.2.3)、およびHandshake (Section 17.2.4)パケットには、パケットの終端を 決定するLengthフィールドが含まれる。この長さにはPacket NumberフィールドとPayload フィールドの両方が含まれ、これらはいずれも機密性保護され、最初は長さが不明である。 Payloadフィールドの長さは、ヘッダー保護が取り除かれると分かる。¶
Lengthフィールドを使用して、送信者は複数のQUICパケットを1つのUDP データグラムに結合できる。これにより、暗号ハンドシェイクを完了し、データ送信を 開始するために必要なUDPデータグラムの数を減らせる。これはPath Maximum Transmission Unit (PMTU)プローブを構築するためにも使用できる。Section 14.4.1を参照。 受信者は結合されたパケットを処理できなければならない(MUST)。¶
暗号化レベルが増加する順序(Initial、0-RTT、Handshake、1-RTT。 Section 4.1.4 of [QUIC-TLS]を参照)でパケットを結合すると、 受信者が1回の処理で全パケットを処理できる可能性が高くなる。ショートヘッダーを持つ パケットには長さが含まれないため、UDPデータグラムに含まれる最後のパケットにしか なれない。エンドポイントは、同じ暗号化レベルで送信されるフレームについては、 同じ暗号化レベルの複数のパケットを結合する代わりに、単一のパケットに複数のフレームを 含めるべきである(SHOULD)。¶
受信者は、UDPデータグラムに含まれる最初のパケット内の情報に基づいて 経路付けしてもよい(MAY)。送信者は、異なる接続IDを持つ QUICパケットを単一のUDPデータグラムに結合してはならない(MUST NOT)。 受信者は、データグラム内の最初のパケットとは異なるDestination Connection IDを持つ 後続パケットを無視するべきである(SHOULD)。¶
単一のUDPデータグラムに結合された各QUICパケットは、それぞれ独立して 完全である。結合されたQUICパケットの受信者は、各QUICパケットを個別に処理し、 異なるUDPデータグラムのペイロードとして受信されたかのように、それぞれを別々に 確認応答しなければならない(MUST)。たとえば、 復号が失敗した場合(鍵が利用できない、またはその他の理由による)、受信者はそのパケットを 破棄または後で処理するためにバッファしてもよく(MAY)、 残りのパケットの処理を試みなければならない(MUST)。¶
Retryパケット(Section 17.2.5)、 Version Negotiationパケット(Section 17.2.1)、 およびショートヘッダーを持つパケット(Section 17.3)にはLengthフィールドが含まれないため、 同じUDPデータグラム内で他のパケットを後続させることはできない。Retryまたは Version Negotiationパケットが別のパケットと結合される状況は存在しないことにも注意すること。¶
パケット番号は、0から262-1までの範囲の整数である。 この番号は、パケット保護のための暗号ノンスを決定する際に使用される。 各エンドポイントは、送信と受信のために別々のパケット番号を維持する。¶
パケット番号は、ACKフレーム(Section 19.3)のLargest Acknowledgedフィールド内で 全体を表現可能である必要があるため、この範囲に制限される。ただし、ロングまたは ショートヘッダーに存在する場合、パケット番号は短縮され、1から4バイトで符号化される。 Section 17.1を参照。¶
Version Negotiation(Section 17.2.1)およびRetry(Section 17.2.5) パケットは、パケット番号を含まない。¶
QUICでは、パケット番号は3つの空間に分けられる。¶
すべてのInitialパケット(Section 17.2.2)はこの空間に属する。¶
すべてのHandshakeパケット(Section 17.2.4)はこの空間に属する。¶
すべての0-RTT(Section 17.2.3)および1-RTT(Section 17.3.1) パケットはこの空間に属する。¶
[QUIC-TLS]で説明されるように、 各パケット種別は異なる保護鍵を使用する。¶
概念的には、パケット番号空間は、パケットを処理および確認応答できる 文脈である。InitialパケットはInitialパケット保護鍵でのみ送信でき、 同じくInitialパケットであるパケットでのみ確認応答できる。同様に、Handshakeパケットは Handshake暗号化レベルで送信され、Handshakeパケットでのみ確認応答できる。¶
これにより、異なるパケット番号空間で送信されるデータ間の暗号学的分離が 強制される。各空間のパケット番号はパケット番号0から始まる。同じパケット番号空間で 送信される後続のパケットは、パケット番号を少なくとも1増加させなければならない (MUST)。¶
0-RTTデータと1-RTTデータは、2つのパケット種別間で損失回復アルゴリズムを 実装しやすくするため、同じパケット番号空間に存在する。¶
QUICエンドポイントは、1つの接続における同じパケット番号空間内で パケット番号を再使用してはならない(MUST NOT)。 送信のためのパケット番号が262-1に達した場合、送信者は CONNECTION_CLOSEフレームまたは以後のいかなるパケットも送信せずに接続を閉じなければならない (MUST)。エンドポイントは、以後に受信するパケットに応答して Stateless Reset(Section 10.3)を送信してもよい (MAY)。¶
受信者は、同じパケット番号空間から同じパケット番号を持つ別のパケットを 処理していないことが確実でない限り、新たに保護解除されたパケットを破棄しなければならない (MUST)。重複抑制は、Section 9.5 of [QUIC-TLS]で説明される理由により、 パケット保護を取り除いた後に行われなければならない(MUST)。¶
重複検出を目的としてすべての個別パケットを追跡するエンドポイントは、 過剰な状態を蓄積するリスクがある。重複検出に必要なデータは、これより小さい番号の すべてのパケットを直ちに破棄する最小パケット番号を維持することで制限できる。 いかなる最小値も、往復時間の大きな変動を考慮する必要がある。これには、ピアが はるかに大きな往復時間を持つネットワークパスを探査する可能性が含まれる。 Section 9を参照。¶
送信者におけるパケット番号の符号化と、受信者における復号は Section 17.1で説明される。¶
パケット保護を取り除いた後のQUICパケットのペイロードは、 Figure 11に示すように、完全なフレームの列で構成される。 Version Negotiation、Stateless Reset、およびRetryパケットはフレームを含まない。¶
フレームを含むパケットのペイロードは、少なくとも1つのフレームを 含まなければならず(MUST)、複数のフレームおよび 複数のフレーム型を含んでもよい(MAY)。 エンドポイントは、フレームを含まないパケットの受信をPROTOCOL_VIOLATION型の 接続エラーとして扱わなければならない(MUST)。 フレームは常に単一のQUICパケット内に収まり、複数のパケットにまたがることはできない。¶
各フレームは、その型を示すFrame Typeで始まり、その後に型依存の 追加フィールドが続く。¶
Frame {
Frame Type (i),
Type-Dependent Fields (..),
}
Table 3は、 本仕様で定義される各フレーム型に関する情報を一覧し要約する。 この要約の説明は表の後に含まれる。¶
| 型値 | フレーム型名 | 定義 | Pkts | Spec |
|---|---|---|---|---|
| 0x00 | PADDING | Section 19.1 | IH01 | NP |
| 0x01 | PING | Section 19.2 | IH01 | |
| 0x02-0x03 | ACK | Section 19.3 | IH_1 | NC |
| 0x04 | RESET_STREAM | Section 19.4 | __01 | |
| 0x05 | STOP_SENDING | Section 19.5 | __01 | |
| 0x06 | CRYPTO | Section 19.6 | IH_1 | |
| 0x07 | NEW_TOKEN | Section 19.7 | ___1 | |
| 0x08-0x0f | STREAM | Section 19.8 | __01 | F |
| 0x10 | MAX_DATA | Section 19.9 | __01 | |
| 0x11 | MAX_STREAM_DATA | Section 19.10 | __01 | |
| 0x12-0x13 | MAX_STREAMS | Section 19.11 | __01 | |
| 0x14 | DATA_BLOCKED | Section 19.12 | __01 | |
| 0x15 | STREAM_DATA_BLOCKED | Section 19.13 | __01 | |
| 0x16-0x17 | STREAMS_BLOCKED | Section 19.14 | __01 | |
| 0x18 | NEW_CONNECTION_ID | Section 19.15 | __01 | P |
| 0x19 | RETIRE_CONNECTION_ID | Section 19.16 | __01 | |
| 0x1a | PATH_CHALLENGE | Section 19.17 | __01 | P |
| 0x1b | PATH_RESPONSE | Section 19.18 | ___1 | P |
| 0x1c-0x1d | CONNECTION_CLOSE | Section 19.19 | ih01 | N |
| 0x1e | HANDSHAKE_DONE | Section 19.20 | ___1 |
各フレーム型の形式と意味論は、Section 19で より詳細に説明される。本節の残りでは、重要かつ一般的な情報の要約を提供する。¶
ACK、STREAM、MAX_STREAMS、STREAMS_BLOCKED、および CONNECTION_CLOSEフレームのFrame Typeは、その他のフレーム固有フラグを運ぶために 使用される。その他すべてのフレームについて、Frame Typeフィールドは単にフレームを 識別する。¶
Table 3の"Pkts"列は、 各フレーム型が出現しうるパケット種別を、次の文字で示している。¶
Initial(Section 17.2.2)¶
Handshake(Section 17.2.4)¶
0-RTT(Section 17.2.3)¶
1-RTT(Section 17.3.1)¶
InitialまたはHandshakeパケットに出現できるのは、 型0x1cのCONNECTION_CLOSEフレームのみである。¶
これらの制限の詳細については、Section 12.5を参照。すべてのフレームは1-RTTパケットに 出現できることに注意すること。エンドポイントは、許可されていないパケット種別で フレームを受信した場合、PROTOCOL_VIOLATION型の接続エラーとして扱わなければならない (MUST)。¶
Table 3の"Spec"列は、 次の文字で示されるように、そのフレーム型の処理または生成を支配する特別な規則を 要約している。¶
この印を持つフレームのみを含むパケットはACKを誘発しない。 Section 13.2を参照。¶
この印を持つフレームのみを含むパケットは、 輻輳制御の目的における飛行中バイトに数えられない。 [QUIC-RECOVERY]を参照。¶
この印を持つフレームのみを含むパケットは、 接続移行中に新しいネットワークパスを探査するために使用できる。 Section 9.1を参照。¶
Table 3の"Pkts"および"Spec"列は、IANAレジストリの一部を構成しない。 Section 22.4を参照。¶
エンドポイントは、未知の型のフレームの受信を FRAME_ENCODING_ERROR型の接続エラーとして扱わなければならない (MUST)。¶
このQUICバージョンでは、すべてのフレームは冪等である。 つまり、有効なフレームは複数回受信されても望ましくない副作用やエラーを引き起こさない。¶
Frame Typeフィールドは、1つの例外を除き、可変長整数符号化 (Section 16を参照)を使用する。 フレーム解析の単純で効率的な実装を保証するため、フレーム型は可能な限り最短の 符号化を使用しなければならない(MUST)。本文書で定義される フレーム型について、これは1バイト符号化を意味する。これらの値を2、4、または 8バイトの可変長整数として符号化することも可能であるにもかかわらずである。 たとえば、0x4001は値1を持つ可変長整数の正当な2バイト符号化であるが、 PINGフレームは常に値0x01を持つ単一バイトとして符号化される。 この規則は、現在および将来のすべてのQUICフレーム型に適用される。 エンドポイントは、必要以上に長い符号化を使用するフレーム型の受信を PROTOCOL_VIOLATION型の接続エラーとして扱ってもよい(MAY)。¶
一部のフレームは、異なるパケット番号空間で禁止される。 ここでの規則はTLSの規則を一般化したものであり、接続確立に関連するフレームは通常 任意のパケット番号空間のパケットに出現できる一方、データ転送に関連するものは アプリケーションデータパケット番号空間にのみ出現できる。¶
次のフレームは、さまざまな理由により0-RTTパケットで送信できないことに 注意すること。ACK、CRYPTO、HANDSHAKE_DONE、NEW_TOKEN、PATH_RESPONSE、および RETIRE_CONNECTION_ID。サーバーは、0-RTTパケットでこれらのフレームを受信した場合、 PROTOCOL_VIOLATION型の接続エラーとして扱ってもよい(MAY)。¶
送信者は、1つ以上のフレームをQUICパケット内で送信する。 Section 12.4を参照。¶
送信者は、各QUICパケットに可能な限り多くのフレームを含めることで、 パケットごとの帯域幅および計算コストを最小化できる。送信者は、多数の小さなパケットを 送出することを避けるため、最大限詰め込まれていないパケットを送信する前に、 複数のフレームを収集する短い時間だけ待ってもよい(MAY)。 実装は、アプリケーションの送信動作に関する知識またはヒューリスティックを使用して、 待つかどうか、およびどの程度待つかを決定してもよい(MAY)。 この待機期間は実装上の判断であり、遅延はアプリケーションに見えるレイテンシを増加させる 可能性が高いため、実装は保守的に遅延させるよう注意するべきである。¶
ストリーム多重化は、複数のストリームからのSTREAMフレームを1つ以上の QUICパケットへ交互に配置することで実現される。単一のQUICパケットは、1つ以上のストリームから 複数のSTREAMフレームを含むことができる。¶
QUICの利点の1つは、複数のストリームにまたがるヘッドオブラインブロッキングの 回避である。パケット損失が発生したとき、そのパケット内にデータを持つストリームのみが 再送信の受信を待ってブロックされる一方、他のストリームは進行を継続できる。 単一のQUICパケットに複数のストリームからのデータが含まれる場合、そのパケットの損失は それらすべてのストリームの進行をブロックすることに注意すること。実装は、詰め不足のパケットに よる送信効率の低下を招かない範囲で、送出パケットに含めるストリームを必要最小限にすることが 推奨される。¶
パケットは、パケット保護が正常に取り除かれ、パケットに含まれる すべてのフレームが処理されるまで、確認応答されてはならない(MUST NOT)。 STREAMフレームの場合、これはデータがアプリケーションプロトコルによって受信される準備として キューに入れられたことを意味するが、データが配信され消費されることまでは要求しない。¶
パケットが完全に処理されると、受信者は受信したパケットのパケット番号を 含む1つ以上のACKフレームを送信することで受信を確認応答する。¶
エンドポイントは、その条件を検出できる場合、自身が送信していない パケットに対する確認応答の受信をPROTOCOL_VIOLATION型の接続エラーとして扱うべきである (SHOULD)。これがどのように達成されるかについてのさらなる議論は、 Section 21.4を参照。¶
エンドポイントは、受信して処理したすべてのパケットを確認応答する。 ただし、最大ACK遅延内にACKフレームを送信させるのはACKを誘発するパケットのみである。 ACKを誘発しないパケットは、他の理由でACKフレームが送信されるときにのみ確認応答される。¶
何らかの理由でパケットを送信するとき、エンドポイントは、 ACKフレームが最近送信されていない場合、それを含めるよう試みるべきである (SHOULD)。そうすることで、ピアでの適時の損失検出に役立つ。¶
一般に、受信者からの頻繁なフィードバックは損失および輻輳応答を改善するが、 これはACKを誘発するすべてのパケットに応答して受信者がACKフレームを送信することで 生じる過剰な負荷との間でバランスを取らなければならない。以下に示す指針は、 このバランスを取ることを目指す。¶
すべてのパケットは少なくとも1回確認応答されるべきであり (SHOULD)、ACKを誘発するパケットは、 エンドポイントがmax_ack_delayトランスポートパラメーターを使用して通知した 最大遅延内に少なくとも1回確認応答されなければならない(MUST)。 Section 18.2を参照。 max_ack_delayは明示的な契約を宣言する。すなわち、エンドポイントは、 ACKを誘発するパケットの確認応答を、示された値より意図的に長く遅延させないことを約束する。 そうした場合、超過分はRTT推定に加算され、ピアからの不要または遅延した再送信を 引き起こす可能性がある。送信者は、Section 6.2 of [QUIC-RECOVERY]で 詳述されるように、タイマーに基づく再送信のタイムアウトを決定する際に、 受信者のmax_ack_delay値を使用する。¶
エンドポイントは、ACKを誘発するすべてのInitialおよびHandshake パケットを直ちに確認応答し、ACKを誘発するすべての0-RTTおよび1-RTTパケットを 自身が通知したmax_ack_delay内に確認応答しなければならない (MUST)。ただし、次の例外がある。ハンドシェイク確認前には、 エンドポイントがHandshake、0-RTT、または1-RTTパケットを受信したとき、 それらを復号するためのパケット保護鍵を持っていないことがある。そのため、 それらをバッファし、必要な鍵が利用可能になったときに確認応答することがある。¶
ACKフレームのみを含むパケットは輻輳制御されないため、 エンドポイントは、ACKを誘発するパケットの受信に応答して、そのようなパケットを 複数送信してはならない(MUST NOT)。¶
エンドポイントは、受信したパケットに先行するパケットギャップが ある場合であっても、ACKを誘発しないパケットに応答してACKを誘発しないパケットを 送信してはならない(MUST NOT)。これにより、 確認応答の無限フィードバックループを避けることができる。そのようなループは、 接続が永遠にアイドルにならないことを引き起こす可能性がある。ACKを誘発しないパケットは、 エンドポイントが他のイベントに応答してACKフレームを送信するときに最終的に確認応答される。¶
ACKフレームのみを送信しているエンドポイントは、それらの確認応答が ACKを誘発するフレームを持つパケットに含まれない限り、ピアから確認応答を受信しない。 新たに確認応答すべきACKを誘発するパケットがある場合、エンドポイントは他のフレームと ともにACKフレームを送信するべきである(SHOULD)。 ACKを誘発しないパケットのみを確認応答する必要がある場合、エンドポイントは、 ACKを誘発するパケットを受信するまで、送出フレームとともにACKフレームを送信しないことを 選択してもよい(MAY)。¶
ACKを誘発しないパケットのみを送信しているエンドポイントは、 確認応答を受信することを保証するため、そのようなパケットにACKを誘発するフレームを 時折追加することを選択できる。Section 13.2.4を参照。 その場合、エンドポイントは確認応答の無限フィードバックループを避けるため、 それ以外ではACKを誘発しないすべてのパケットにACKを誘発するフレームを送信してはならない (MUST NOT)。¶
送信者での損失検出を支援するため、エンドポイントは、 ACKを誘発するパケットを受信したとき、次のいずれかの場合に遅延なくACKフレームを 生成して送信するべきである(SHOULD)。¶
同様に、IPヘッダーでECN Congestion Experienced(CE) コードポイントが付けられたパケットは、輻輳イベントに対するピアの応答時間を短縮するため、 直ちに確認応答されるべきである(SHOULD)。¶
[QUIC-RECOVERY]のアルゴリズムは、上で示した指針に従わない 受信者に対しても堅牢であることが期待される。ただし、実装は、エンドポイントによる接続と ネットワークの他の利用者に対する性能上の影響を慎重に検討した後にのみ、 これらの要件から逸脱するべきである。¶
受信者は、ACKを誘発するパケットに応答して確認応答を送信する頻度を 決定する。この決定にはトレードオフが伴う。¶
エンドポイントは損失を検出するために適時の確認応答に依存する。 Section 6 of [QUIC-RECOVERY]を参照。 Section 7 of [QUIC-RECOVERY]で説明されるものなどのウィンドウベースの 輻輳制御器は、輻輳ウィンドウを管理するために確認応答に依存する。どちらの場合も、 確認応答を遅延させることは性能に悪影響を及ぼす可能性がある。¶
一方で、確認応答のみを運ぶパケットの頻度を減らすことは、 両エンドポイントでのパケット送信および処理コストを減らす。これは、著しく非対称な リンクで接続スループットを改善し、戻りパス容量を使用する確認応答トラフィック量を 減らすことができる。Section 3 of [RFC3449]を参照。¶
受信者は、少なくとも2つのACKを誘発するパケットを受信した後、 ACKフレームを送信するべきである(SHOULD)。 この推奨は一般的な性質のものであり、TCPエンドポイントのふるまいに関する推奨 [RFC5681]と一致する。ネットワーク条件に関する知識、 ピアの輻輳制御器に関する知識、またはさらなる研究と実験により、より良い性能特性を持つ 代替の確認応答戦略が示唆される可能性がある。¶
受信者は、応答としてACKフレームを送信するかどうかを決定する前に、 利用可能な複数のパケットを処理してもよい(MAY)。¶
ACKフレームが送信されるとき、確認応答されたパケットの1つ以上の 範囲が含まれる。古いパケットの確認応答を含めることで、以前に送信されたACKフレームの 損失によって生じる不要な再送信の可能性を減らせるが、その代償としてACKフレームは 大きくなる。¶
ACKフレームは常に最も最近受信されたパケットを確認応答するべきであり (SHOULD)、パケットの順序外れが大きいほど、ピアが パケットを失われたと宣言してそこに含まれるフレームを不要に再送信することを防ぐため、 更新されたACKフレームを迅速に送信することがより重要になる。ACKフレームは 単一のQUICパケット内に収まることが期待される。収まらない場合、古い範囲 (パケット番号が最小のもの)が省略される。¶
受信者は、ACKフレームのサイズを制限し、リソース枯渇を避けるため、 記憶してACKフレームで送信するACK Ranges(Section 19.3.1)の数を制限する。 ACKフレームに対する確認応答を受信した後、受信者はそれらの確認応答されたACK Rangesの 追跡を停止するべきである(SHOULD)。送信者は大半の パケットに対する確認応答を期待できるが、QUICは受信者が処理するすべてのパケットに対して 確認応答の受信を保証しない。¶
多くのACK Rangesを保持すると、ACKフレームが大きくなりすぎる可能性がある。 受信者はACKフレームサイズを制限するために未確認応答のACK Rangesを破棄できるが、 その代償として送信者からの再送信が増加する。ACKフレームがパケットに収まらない場合、 これは必要である。受信者は、他のフレームのための空間を確保するため、または 確認応答が消費する容量を制限するために、ACKフレームサイズをさらに制限してもよい (MAY)。¶
受信者は、その範囲内の番号を持つパケットを以後受け入れないことを 保証できない限り、ACK Rangeを保持しなければならない(MUST)。 範囲が破棄されるにつれて増加する最小パケット番号を維持することは、最小限の状態で これを達成する1つの方法である。¶
受信者はすべてのACK Rangesを破棄できるが、後続のパケットから パケット番号を復元するために使用されるため、正常に処理された最大パケット番号を 保持しなければならない(MUST)。Section 17.1を参照。¶
受信者は、すべてのACKフレームに最大受信パケット番号を含む ACK Rangeを含めるべきである(SHOULD)。 Largest Acknowledgedフィールドは送信者でのECN検証に使用され、以前のACKフレームに 含まれていた値より低い値を含めると、ECNが不要に無効化される可能性がある。 Section 13.4.2を参照。¶
Section 13.2.4では、 各ACKフレームでどのパケットを確認応答するかを決定するための例示的な方法を 説明する。このアルゴリズムの目的は、処理されるすべてのパケットに対する確認応答を 生成することであるが、それでも確認応答が失われる可能性はある。¶
ACKフレームを含むパケットが送信されるとき、そのフレーム内の Largest Acknowledgedフィールドを保存できる。ACKフレームを含むパケットが確認応答されると、 受信者は送信したACKフレーム内のLargest Acknowledgedフィールド以下のパケットの 確認応答を停止できる。¶
ACKフレームなど、ACKを誘発しないパケットのみを送信する受信者は、 長期間にわたって確認応答を受信しない可能性がある。これにより、受信者が長期間にわたり 多数のACKフレームの状態を維持することになり、送信するACKフレームが不要に大きくなる 可能性がある。そのような場合、受信者はピアからACKを引き出すために、往復ごとに1回など、 PINGまたはその他の小さなACKを誘発するフレームを時折送信できる。¶
ACKフレームの損失がない場合、このアルゴリズムは最小1 RTT分の 並べ替えを許容する。ACKフレームの損失と並べ替えがある場合、この方法は、 すべての確認応答がACKフレームに含まれなくなる前に送信者に見えることを保証しない。 パケットは順不同に受信される可能性があり、それらを含む後続のACKフレームがすべて 失われる可能性がある。この場合、損失回復アルゴリズムは不要な再送信を引き起こす 可能性があるが、送信者は前進し続ける。¶
エンドポイントは、最大パケット番号を持つパケットを受信した時刻と 確認応答が送信される時刻の間に意図的に導入された遅延を測定する。 エンドポイントは、この確認応答遅延をACKフレームのACK Delayフィールドに符号化する。 Section 19.3を参照。これにより、ACKフレームの 受信者は任意の意図的遅延を補正できる。これは、確認応答が遅延される場合に パスRTTのより良い推定値を得るために重要である。¶
パケットは、処理される前にOSカーネルまたはホスト上の他の場所に 保持される可能性がある。エンドポイントは、ACKフレームのACK Delayフィールドに値を 入れる際、自身が制御しない遅延を含めてはならない(MUST NOT)。 ただし、復号鍵が利用できないことによって生じるバッファリング遅延は、大きく、 繰り返されない可能性が高いため、エンドポイントはそれを含めるべきである (SHOULD)。¶
測定された確認応答遅延が自身のmax_ack_delayより大きい場合、 エンドポイントは測定された遅延を報告するべきである(SHOULD)。 この情報は、遅延が大きくなりうるハンドシェイク中に特に有用である。 Section 13.2.1を参照。¶
ACKフレームは、確認応答されるパケットと同じパケット番号空間を 持つパケットでのみ運ばれなければならない(MUST)。 Section 12.1を参照。たとえば、1-RTT鍵で保護されたパケットは、 同じく1-RTT鍵で保護されたパケットで確認応答されなければならない (MUST)。¶
クライアントが0-RTTパケット保護で送信するパケットは、 サーバーによって1-RTT鍵で保護されたパケットで確認応答されなければならない (MUST)。これは、サーバーの暗号ハンドシェイクメッセージが 遅延または失われた場合、クライアントがこれらの確認応答を使用できないことを意味しうる。 同じ制限は、1-RTT鍵で保護されてサーバーから送信される他のデータにも適用されることに 注意すること。¶
PADDINGフレームを含むパケットは、輻輳制御の目的では飛行中と 見なされる[QUIC-RECOVERY]。 したがって、PADDINGフレームのみを含むパケットは輻輳ウィンドウを消費するが、 輻輳ウィンドウを開く確認応答を生成しない。デッドロックを避けるため、送信者は PADDINGフレームに加え、受信者から確認応答を引き出すために他のフレームが 定期的に送信されることを保証するべきである(SHOULD)。¶
失われたと判断されたQUICパケットは、全体として再送信されない。 失われたパケットに含まれるフレームにも同じことが適用される。代わりに、フレームで 運ばれていた可能性のある情報が、必要に応じて新しいフレームで再度送信される。¶
失われたと判断された情報を運ぶために、新しいフレームとパケットが使用される。 一般に、その情報を含むパケットが失われたと判断されたときに情報は再度送信され、 その情報を含むパケットが確認応答されると送信は停止する。¶
エンドポイントは、アプリケーションによって指定された優先度が そうでないことを示さない限り、新しいデータの送信よりもデータの再送信を優先するべきである (SHOULD)。Section 2.3を参照。¶
送信者は、パケットを送信するたびに最新情報を含むフレームを組み立てることが 推奨されるが、失われたパケットからフレームのコピーを再送信することは禁止されていない。 フレームのコピーを再送信する送信者は、パケット番号長、接続ID長、およびパスMTUの変化に よる利用可能ペイロードサイズの減少を処理する必要がある。受信者は、古いパケットに見られる ものより小さい最大データ値を運ぶMAX_DATAフレームなど、古いフレームを含むパケットを 受け入れなければならない(MUST)。¶
送信者は、パケットが確認応答された後、それらのパケットからの情報を 再送信することを避けるべきである(SHOULD)。これには、 失われたと宣言された後に確認応答されるパケットも含まれる。これはネットワークで 並べ替えが存在する場合に起こりうる。そうするには、送信者がパケットを失われたと宣言した後も そのパケットに関する情報を保持する必要がある。送信者は、PTO(Section 6.2 of [QUIC-RECOVERY])など、 並べ替えを十分に許容する時間が経過した後、またはメモリ上限に達するなど他のイベントに 基づいて、この情報を破棄できる。¶
損失を検出すると、送信者は適切な輻輳制御動作を取らなければならない (MUST)。損失検出および輻輳制御の詳細は [QUIC-RECOVERY]で説明される。¶
QUICエンドポイントは、ネットワーク輻輳を検出し応答するために ECN [RFC3168]を使用できる。ECNにより、エンドポイントは IPパケットのECNフィールドにECN-Capable Transport(ECT)コードポイントを設定できる。 その後、ネットワークノードは、パケットを破棄する代わりにECNフィールドにECN-CE コードポイントを設定することで輻輳を示すことができる [RFC8087]。エンドポイントは、 [QUIC-RECOVERY]で説明されるように、報告された輻輳に対して 送信レートを下げることで応答する。¶
ECNを有効にするため、送信側QUICエンドポイントはまず、 パスがECNマーキングをサポートするか、およびピアが受信IPヘッダー内のECN値を報告するかを 判断する。Section 13.4.2を参照。¶
ECNの使用には、受信側エンドポイントがIPパケットからECNフィールドを 読み取る必要があるが、これはすべてのプラットフォームで可能とは限らない。 エンドポイントがECNサポートを実装していない、または受信したECNフィールドに アクセスできない場合、受信したパケットについてECNカウントを報告しない。¶
エンドポイントは、自身が送信するパケットにECTフィールドを 設定しない場合であっても、受信したECNマーキングにアクセスできるなら、 それに関するフィードバックを提供しなければならない(MUST)。ECNカウントの報告に失敗すると、送信者はこの接続で ECNの使用を無効にする。¶
ECT(0)、ECT(1)、またはECN-CEコードポイントを持つIPパケットを 受信すると、ECN対応エンドポイントはECNフィールドにアクセスし、対応する ECT(0)、ECT(1)、またはECN-CEカウントを増加させる。これらのECNカウントは 後続のACKフレームに含められる。Sections 13.2および 19.3を参照。¶
各パケット番号空間は、別個の確認応答状態と別個のECNカウントを 維持する。結合されたQUICパケット(Section 12.2を参照)は同じIPヘッダーを共有するため、ECNカウントは結合された 各QUICパケットごとに1回増加する。¶
たとえば、Initial、Handshake、および1-RTT QUICパケットが それぞれ1つずつ単一のUDPデータグラムに結合されている場合、3つすべての パケット番号空間のECNカウントは、単一のIPヘッダーのECNフィールドに基づいて それぞれ1ずつ増加する。¶
ECNカウントは、受信IPパケットからのQUICパケットが処理されたときにのみ 増加する。そのため、重複したQUICパケットは処理されず、ECNカウントを増加させない。 関連するセキュリティ上の懸念についてはSection 21.10を 参照。¶
欠陥のあるネットワークデバイスが、非ゼロのECNコードポイントを 運ぶパケットを破損させたり、誤って破棄したりする可能性がある。そのようなデバイスが 存在する場合でも接続性を保証するため、エンドポイントは各ネットワークパスについて ECNカウントを検証し、エラーが検出された場合はそのパス上でECNの使用を無効にする。¶
新しいパスに対してECN検証を実行するには、次のようにする。¶
エンドポイントが、ECTコードポイントを持つIPパケットが欠陥のある ネットワーク要素によって破棄される可能性があると予想する理由を持つ場合、 エンドポイントは、パス上の最初の10個の送出パケットだけに、または3 PTOの期間 (Section 6.2 of [QUIC-RECOVERY]を参照)だけにECTコードポイントを 設定できる。その後、非ゼロのECNコードポイントでマーキングされたすべてのパケットが 失われた場合、マーキングが損失を引き起こしたという仮定のもとでマーキングを無効にできる。¶
したがって、エンドポイントはECNの使用を試み、新しい接続ごと、 サーバーの優先アドレスへ切り替えるとき、および新しいパスへの能動的な接続移行時に、 これを検証する。Appendix A.4では、1つの可能な アルゴリズムを説明する。¶
ECNサポートについてパスを探査する他の方法も可能であり、 異なるマーキング戦略も可能である。実装は、RFCで定義された他の方法を使用してもよい (MAY)。[RFC8311]を参照。 ECT(1)コードポイントを使用する実装は、報告されたECT(1)カウントを使用してECN検証を 実行する必要がある。¶
ネットワークによるECN-CEマーキングの誤った適用は、 接続性能の低下をもたらす可能性がある。したがって、ECNカウントを持つ ACKフレームを受信するエンドポイントは、それらを使用する前にカウントを検証する。 これは、新たに受信したカウントを、最後に正常に処理されたACKフレームからの カウントと比較することで実行される。ECNカウントの任意の増加は、ACKフレームで 新たに確認応答されたパケットに適用されたECNマーキングに基づいて検証される。¶
ACKフレームが、エンドポイントがECT(0)またはECT(1) コードポイントを設定して送信したパケットを新たに確認応答する場合、 対応するECNカウントがACKフレーム内に存在しないとECN検証は失敗する。 この確認は、ECNフィールドをゼロにするネットワーク要素、またはECNマーキングを 報告しないピアを検出する。¶
ECT(0)およびECN-CEカウントの増加の合計が、 もともとECT(0)マーキングを付けて送信された新たに確認応答されたパケット数より 少ない場合にも、ECN検証は失敗する。同様に、ECT(1)およびECN-CEカウントの 増加の合計が、ECT(1)マーキングを付けて送信された新たに確認応答されたパケット数より 少ない場合にも、ECN検証は失敗する。これらの確認は、ネットワークによる ECN-CEマーキングの再マーキングを検出できる。¶
ACKフレームが失われると、エンドポイントはパケットに対する 確認応答を見逃す可能性がある。そのため、ECT(0)、ECT(1)、およびECN-CEカウントの 合計増加が、ACKフレームによって新たに確認応答されたパケット数より大きくなることが ありうる。これが、ECNカウントが確認応答されたパケットの総数より大きいことを 許可される理由である。¶
並べ替えられたACKフレームからECNカウントを検証すると、 失敗につながる可能性がある。エンドポイントは、最大確認応答済みパケット番号を 増加させないACKフレームを処理した結果として、ECN検証を失敗させてはならない (MUST NOT)。¶
受信したECT(0)またはECT(1)のいずれかの総カウントが、 対応する各ECTコードポイントで送信されたパケットの総数を超える場合、ECN検証は 失敗する可能性がある。特に、エンドポイントが適用したことのないECTコードポイントに 対応する非ゼロのECNカウントを受信した場合、検証は失敗する。この確認は、 ネットワーク内でパケットがECT(0)またはECT(1)へ再マーキングされる場合を検出する。¶
検証が失敗した場合、エンドポイントはECNを無効にしなければならない (MUST)。ネットワークパスまたはピアのいずれかが ECNをサポートしていないと仮定し、送信するIPパケットでECTコードポイントの設定を 停止する。¶
検証が失敗した場合でも、エンドポイントは同じパスについて、 接続中の任意の後の時点でECNを再検証してもよい(MAY)。エンドポイントは定期的に検証の試行を継続できる。¶
検証が成功すると、エンドポイントは、そのパスがECN対応であることを 期待して、以後に送信するパケットでECTコードポイントを設定し続けてもよい (MAY)。ネットワークの経路付けとパス要素は接続途中で 変化する可能性がある。後で検証が失敗した場合、エンドポイントはECNを無効に しなければならない(MUST)。¶
UDPデータグラムは1つ以上のQUICパケットを含むことができる。 データグラムサイズとは、QUICパケットを運ぶ単一のUDPデータグラムの UDPペイロード全体のサイズを指す。データグラムサイズには、1つ以上のQUICパケットヘッダーと 保護されたペイロードが含まれるが、UDPヘッダーまたはIPヘッダーは含まれない。¶
最大データグラムサイズは、単一のUDPデータグラムを使用してネットワークパス上で 送信できるUDPペイロードの最大サイズとして定義される。ネットワークパスが少なくとも1200バイトの 最大データグラムサイズをサポートできない場合、QUICを使用してはならない(MUST NOT)。¶
QUICは、少なくとも1280バイトの最小IPパケットサイズを仮定する。これはIPv6の 最小サイズ[IPv6]であり、ほとんどの現代的なIPv4 ネットワークでもサポートされる。IPv6の最小IPヘッダーサイズを40バイト、IPv4を20バイト、 UDPヘッダーサイズを8バイトと仮定すると、IPv6では最大データグラムサイズが1232バイト、 IPv4では1252バイトとなる。したがって、現代的なIPv4およびすべてのIPv6ネットワークパスは QUICをサポートできることが期待される。¶
1200バイトより大きい任意の最大データグラムサイズは、Path Maximum Transmission Unit Discovery(PMTUD)(Section 14.2.1を参照)または Datagram Packetization Layer PMTU Discovery(DPLPMTUD)(Section 14.3を参照)を 使用して発見できる。¶
max_udp_payload_sizeトランスポートパラメーター (Section 18.2)の強制は、 最大データグラムサイズに対する追加の制限として機能する可能性がある。送信者は、その値が 分かればこの制限を超えることを避けられる。しかし、トランスポートパラメーターの値を知る前に、 エンドポイントが許可される最小最大データグラムサイズである1200バイトより大きい データグラムを送信すると、データグラムが失われるリスクがある。¶
UDPデータグラムはIP層でフラグメント化されてはならない (MUST NOT)。IPv4 [IPv4]では、パス上でのフラグメント化を防ぐため、 可能であればDon't Fragment(DF)ビットを設定しなければならない(MUST)。¶
QUICは、データグラムが一定のサイズ以上であることを要求することがある。 例としてSection 8.1を参照。 しかし、データグラムのサイズは認証されない。つまり、エンドポイントが特定のサイズの データグラムを受信しても、送信者が同じサイズでデータグラムを送信したことは分からない。 したがって、サイズ制約を満たさないデータグラムを受信したとき、エンドポイントは接続を 閉じてはならない(MUST NOT)。エンドポイントはそのような データグラムを破棄してもよい(MAY)。¶
クライアントは、InitialパケットにPADDINGフレームを追加するか、 Initialパケットを結合することで、Initialパケットを運ぶすべてのUDPデータグラムの ペイロードを、許可される最小最大データグラムサイズである1200バイト以上に 拡張しなければならない(MUST)。Section 12.2を参照。 Initialパケットは、受信者が破棄する無効なパケットと結合されることさえある。 同様に、サーバーは、ACKを誘発するInitialパケットを運ぶすべてのUDPデータグラムの ペイロードを、許可される最小最大データグラムサイズである1200バイト以上に 拡張しなければならない(MUST)。¶
このサイズのUDPデータグラムを送信することで、ネットワークパスが 妥当なPath Maximum Transmission Unit(PMTU)を両方向でサポートしていることが保証される。 さらに、Initialパケットを拡張するクライアントは、未検証のクライアントアドレスへ向けた サーバー応答によって引き起こされる増幅攻撃の振幅を低減するのに役立つ。 Section 8を参照。¶
送信者が、ネットワークパスとピアの両方が自身の選択したサイズを サポートすると信じる場合、Initialパケットを含むデータグラムは1200バイトを 超えてもよい(MAY)。¶
サーバーは、許可される最小最大データグラムサイズである1200バイトより 小さいペイロードを持つUDPデータグラムで運ばれるInitialパケットを破棄しなければならない (MUST)。サーバーは、PROTOCOL_VIOLATIONのエラーコードを持つ CONNECTION_CLOSEフレームを送信して接続を直ちに閉じてもよい(MAY)。Section 10.2.3を参照。¶
サーバーは、クライアントのアドレスを検証する前に送信するバイト数も 制限しなければならない(MUST)。Section 8を参照。¶
PMTUは、IPヘッダー、UDPヘッダー、およびUDPペイロードを含む IPパケット全体の最大サイズである。UDPペイロードには、1つ以上のQUICパケットヘッダーと 保護されたペイロードが含まれる。PMTUはパス特性に依存する可能性があり、したがって 時間とともに変化する可能性がある。任意の時点でエンドポイントが送信する最大の UDPペイロードは、エンドポイントの最大データグラムサイズと呼ばれる。¶
エンドポイントは、宛先へのパスが望ましい最大データグラムサイズを フラグメント化なしでサポートするかどうかを判断するため、DPLPMTUD(Section 14.3)またはPMTUD(Section 14.2.1)を使用するべきである (SHOULD)。これらの機構がない場合、QUICエンドポイントは 許可される最小最大データグラムサイズより大きいデータグラムを送信するべきではない (SHOULD NOT)。¶
DPLPMTUDとPMTUDはいずれも、現在の最大データグラムサイズより 大きいデータグラムを送信する。これはPMTUプローブと呼ばれる。PMTUプローブで送信されない すべてのQUICパケットは、データグラムがフラグメント化または破棄されることを避けるため、 最大データグラムサイズ内に収まるようにサイズ設定されるべきである (SHOULD)[RFC8085]。¶
QUICエンドポイントが、任意のローカルおよびリモートIPアドレスの 組み合わせの間のPMTUが、許可される最小最大データグラムサイズである1200バイトを サポートできないと判断した場合、影響を受けるパス上では、PMTUプローブ内のもの、 またはCONNECTION_CLOSEフレームを含むものを除き、QUICパケットの送信を直ちに停止しなければならない (MUST)。代替パスが見つからない場合、エンドポイントは接続を 終了してもよい(MAY)。¶
ローカルアドレスとリモートアドレスの各組み合わせは、異なるPMTUを 持つ可能性がある。したがって、何らかのPMTU発見を実装するQUIC実装は、ローカルおよび リモートIPアドレスの各組み合わせについて最大データグラムサイズを維持するべきである (SHOULD)。¶
QUIC実装は、未知のトンネルオーバーヘッドまたはIPヘッダーの オプション/拡張を考慮して、最大データグラムサイズの計算においてより保守的であってもよい (MAY)。¶
PMTUD [RFC1191] [RFC8201]は、IPパケットが ローカルルーターMTUより大きいため破棄されたことを示すICMPメッセージ (すなわちIPv6 Packet Too Big(PTB)メッセージ)の受信に依存する。 DPLPMTUDも任意でこれらのメッセージを使用できる。このICMPメッセージの使用は、 パケットを観測できないが、パス上で使用されるアドレスをうまく推測する可能性のある エンティティによる攻撃に潜在的に脆弱である。これらの攻撃は、PMTUを帯域幅効率の 悪い値まで低下させる可能性がある。¶
エンドポイントは、PMTUがQUICで許可される最小最大データグラムサイズを 下回ったと主張するICMPメッセージを無視しなければならない (MUST)。¶
ICMP生成の要件[RFC1812] [RFC4443]では、引用されたパケットは、 IPバージョンの最小MTUを超えない範囲で、元のパケットを可能な限り多く含むべきであると 述べられている。引用されたパケットのサイズは実際にはより小さい場合があり、または 情報が理解不能である場合がある。これはSection 1.1 of [DPLPMTUD]で説明されている。¶
PMTUDを使用するQUICエンドポイントは、 [RFC8201]および Section 5.2 of [RFC8085]で規定されるように、 パケット注入から保護するためICMPメッセージを検証するべきである (SHOULD)。この検証は、ICMPメッセージのペイロードで 提供された引用パケットを使用して、そのメッセージを対応するトランスポート接続に 関連付けるべきである(SHOULD) (Section 4.6.1 of [DPLPMTUD]を参照)。ICMPメッセージ検証には、 IPアドレスおよびUDPポートの一致[RFC8085]、 ならびに可能な場合はアクティブなQUICセッションへの接続IDの一致を含めなければならない (MUST)。エンドポイントは、検証に失敗するすべての ICMPメッセージを無視するべきである(SHOULD)。¶
エンドポイントは、ICMPメッセージに基づいてPMTUを増加させてはならない (MUST NOT)。Section 3 of [DPLPMTUD]の項目6を参照。 ICMPメッセージに応答したQUICの最大データグラムサイズの任意の低下は、QUICの 損失検出アルゴリズムが引用されたパケットが実際に失われたと判断するまで、 暫定的であってもよい(MAY)。¶
DPLPMTUD [DPLPMTUD]は、 PMTUプローブで運ばれるQUICパケットの損失または確認応答の追跡に依存する。 PADDINGフレームを使用するDPLPMTUD用のPMTUプローブは、Section 4.1 of [DPLPMTUD]で定義される 「パディングデータを用いた探査」を実装する。¶
エンドポイントは、BASE_PLPMTU(Section 5.1 of [DPLPMTUD])の初期値を、QUICで許可される 最小最大データグラムサイズと整合するよう設定するべきである(SHOULD)。 MIN_PLPMTUはBASE_PLPMTUと同じである。¶
DPLPMTUDを実装するQUICエンドポイントは、ローカルおよびリモート IPアドレスの各組み合わせについて、DPLPMTUD Maximum Packet Size(MPS) (Section 4.4 of [DPLPMTUD])を 維持する。これは最大データグラムサイズに対応する。¶
DPLPMTUDの観点から見ると、QUICは確認応答される Packetization Layer(PL)である。したがって、QUIC送信者は、QUIC接続ハンドシェイクが 完了したとき、DPLPMTUD BASE状態(Section 5.2 of [DPLPMTUD])に 入ることができる。¶
QUICは確認応答されるPLである。したがって、QUIC送信者は SEARCH_COMPLETE状態にある間、DPLPMTUD CONFIRMATION_TIMERを実装しない。 Section 5.2 of [DPLPMTUD]を参照。¶
DPLPMTUDを使用するエンドポイントは、PTB情報を使用する前に、 受信した任意のICMP PTBメッセージを検証する必要がある。これは Section 4.6 of [DPLPMTUD]で定義される。 UDPポート検証に加えて、QUICは他のPL情報(例: 受信した任意のICMPメッセージの 引用パケット内の接続IDの検証)を使用してICMPメッセージを検証する。¶
Section 14.2.1で説明されるICMPメッセージ処理に 関する考慮事項は、これらのメッセージがDPLPMTUDで使用される場合にも適用される。¶
PMTUプローブはACKを誘発するパケットである。¶
エンドポイントは、PMTUプローブの内容をPINGおよびPADDINGフレームに 制限することができる。現在の最大データグラムサイズより大きいパケットは、ネットワークにより 破棄される可能性が高いためである。したがって、PMTUプローブで運ばれるQUICパケットの損失は 輻輳の信頼できる指標ではなく、輻輳制御反応を引き起こすべきではない (SHOULD NOT)。Section 3 of [DPLPMTUD]の項目7を参照。 ただし、PMTUプローブは輻輳ウィンドウを消費し、アプリケーションによる後続の送信を 遅延させる可能性がある。¶
到着するQUICパケットの経路付けをDestination Connection IDフィールドに 依存するエンドポイントは、結果として生じる任意のICMPメッセージ (Section 14.2.1)を正しいエンドポイントへ戻すため、PMTUプローブに接続IDを 含めることを必要とする可能性が高い。しかし、Source Connection IDフィールドを含むのは ロングヘッダーパケット(Section 17.2)のみであり、ハンドシェイクが完了すると、ロングヘッダーパケットは ピアによって復号または確認応答されない。¶
PMTUプローブを構築する1つの方法は、Handshakeまたは0-RTTパケット (Section 17.2)などのロングヘッダーを持つ パケットを、単一のUDPデータグラム内でショートヘッダーパケットと結合する (Section 12.2を参照)ことである。 結果として得られるPMTUプローブがエンドポイントに到達した場合、ロングヘッダーを持つ パケットは無視されるが、ショートヘッダーパケットは確認応答される。PMTUプローブが ICMPメッセージの送信を引き起こす場合、そのメッセージにはプローブの最初の部分が引用される。 Source Connection IDフィールドがプローブの引用部分内にある場合、それをICMPメッセージの 経路付けまたは検証に使用できる。¶
QUICバージョンは、32ビット符号なし数を使用して識別される。¶
バージョン0x00000000は、バージョンネゴシエーションを表すために予約される。 この仕様のバージョンは、数値0x00000001によって識別される。¶
QUICの他のバージョンは、このバージョンとは異なる性質を持つ可能性がある。 プロトコルのすべてのバージョンにわたって一貫していることが保証されるQUICの性質は、 [QUIC-INVARIANTS]で説明される。¶
QUICのバージョン0x00000001は、[QUIC-TLS]で 説明されるように、暗号ハンドシェイクプロトコルとしてTLSを使用する。¶
バージョン番号の最上位16ビットがクリアされたバージョンは、将来の IETFコンセンサス文書で使用するために予約される。¶
0x?a?a?a?aというパターンに従うバージョンは、バージョンネゴシエーションの 実行を強制するために使用するものとして予約される。すなわち、すべてのバイトの下位4ビットが 1010(二進数)である任意のバージョン番号である。クライアントまたはサーバーは、これらの 予約済みバージョンのいずれかへの対応を通知してもよい(MAY)。¶
予約済みバージョン番号は、実際のプロトコルを表すことは決してない。 クライアントは、サーバーがバージョンネゴシエーションを開始することを期待して、これらの バージョン番号の1つを使用してもよい(MAY)。サーバーは、これらのバージョンの1つへの対応を通知してもよく (MAY)、クライアントがその値を無視することを期待できる。¶
QUICパケットおよびフレームは、非負整数値に対して一般に可変長符号化を 使用する。この符号化により、小さい整数値はより少ないバイトで符号化できる。¶
QUIC可変長整数符号化は、最初のバイトの最上位2ビットを、整数符号化長の バイト単位での2を底とする対数を符号化するために予約する。整数値は、残りのビットに ネットワークバイト順で符号化される。¶
これは、整数が1、2、4、または8バイトで符号化され、それぞれ6、14、30、 または62ビットの値を符号化できることを意味する。Table 4は 符号化の性質を要約する。¶
| 2MSB | 長さ | 使用可能ビット | 範囲 |
|---|---|---|---|
| 00 | 1 | 6 | 0-63 |
| 01 | 2 | 14 | 0-16383 |
| 10 | 4 | 30 | 0-1073741823 |
| 11 | 8 | 62 | 0-4611686018427387903 |
復号アルゴリズムの例と符号化例は Appendix A.1に示されている。¶
Frame Typeフィールドを唯一の例外として、値は必要最小限のバイト数で 符号化される必要はない。Section 12.4を参照。¶
バージョン(Section 15)、ヘッダーで送信される パケット番号(Section 17.1)、およびロングヘッダー パケット内の接続IDの長さ(Section 17.2)は 整数を使用して説明されるが、この符号化を使用しない。¶
すべての数値はネットワークバイト順(すなわちビッグエンディアン)で 符号化され、すべてのフィールドサイズはビット単位である。フィールド値の説明には 十六進表記が使用される。¶
パケット番号は0から262-1までの範囲の整数である (Section 12.3)。ロングまたはショートパケット ヘッダーに存在する場合、1から4バイトで符号化される。パケット番号を表現するために 必要なビット数は、パケット番号の最下位ビットのみを含めることで削減される。¶
符号化されたパケット番号は、Section 5.4 of [QUIC-TLS]で説明されるように 保護される。¶
パケット番号空間について確認応答を受信する前は、完全なパケット番号が 含まれなければならない(MUST)。以下で説明するように、 切り詰めてはならない。¶
パケット番号空間について確認応答を受信した後、送信者は、 最大確認応答済みパケット番号と送信されるパケット番号との差の2倍より大きい範囲を 表現できるパケット番号サイズを使用しなければならない(MUST)。 パケットを受信するピアは、多くのより大きい番号のパケットが受信された後に到着するほど パケットが転送中に遅延しない限り、パケット番号を正しく復号する。エンドポイントは、 その後に送信されたパケットの後にそのパケットが到着した場合でもパケット番号を復元できるよう、 十分に大きいパケット番号符号化を使用するべきである(SHOULD)。¶
その結果、パケット番号符号化のサイズは、新しいパケットを含む 連続した未確認応答パケット番号の数の2を底とする対数より少なくとも1ビット大きくなる。 パケット番号符号化の疑似コードと例は、Appendix A.2にある。¶
受信者では、完全なパケット番号を復元する前にパケット番号の保護が 取り除かれる。完全なパケット番号は、存在する有意ビット数、それらのビットの値、および 正常に認証されたパケットで受信した最大パケット番号に基づいて再構築される。 パケット保護の除去を正常に完了するためには、完全なパケット番号の復元が必要である。¶
ヘッダー保護が取り除かれると、次に期待されるパケットに最も近い パケット番号値を見つけることで、パケット番号が復号される。次に期待されるパケットは、 受信した最大パケット番号に1を加えたものである。パケット番号復号の疑似コードと例は Appendix A.3にある。¶
Long Header Packet {
Header Form (1) = 1,
Fixed Bit (1) = 1,
Long Packet Type (2),
Type-Specific Bits (4),
Version (32),
Destination Connection ID Length (8),
Destination Connection ID (0..160),
Source Connection ID Length (8),
Source Connection ID (0..160),
Type-Specific Payload (..),
}
ロングヘッダーは、1-RTT鍵が確立される前に送信されるパケットで使用される。 1-RTT鍵が利用可能になると、送信者はショートヘッダーを使用したパケットの送信に切り替える (Section 17.3)。ロング形式により、 Version Negotiationパケットなどの特殊なパケットを、この一様な固定長パケット形式で表現できる。 ロングヘッダーを使用するパケットは、次のフィールドを含む。¶
バイト0(最初のバイト)の最上位ビット(0x80)は、 ロングヘッダーでは1に設定される。¶
バイト0の次のビット(0x40)は、パケットがVersion Negotiationパケットでない限り1に設定される。このビットがゼロ値のパケットは、 このバージョンでは有効なパケットではなく、破棄されなければならない (MUST)。このビットの値が1であることにより、 QUICは他のプロトコルと共存できる。[RFC7983]を参照。¶
バイト0の次の2ビット(マスク0x30を持つもの)は パケット種別を含む。パケット種別はTable 5に 一覧される。¶
バイト0の下位4ビット(マスク0x0fを持つもの)の意味論は、 パケット種別によって決定される。¶
QUIC Versionは、最初のバイトに続く32ビットフィールドである。 このフィールドは使用中のQUICバージョンを示し、残りのプロトコルフィールドが どのように解釈されるかを決定する。¶
バージョンに続くバイトは、その後に続く Destination Connection IDフィールドのバイト単位の長さを含む。この長さは8ビットの 符号なし整数として符号化される。QUICバージョン1では、この値は20バイトを 超えてはならない(MUST NOT)。20より大きい値を持つ バージョン1ロングヘッダーを受信したエンドポイントは、パケットを破棄しなければならない (MUST)。Version Negotiationパケットを適切に形成するため、 サーバーは他のQUICバージョンからより長い接続IDを読み取ることができるべきである (SHOULD)。¶
Destination Connection IDフィールドは、 Destination Connection ID Lengthフィールドに続き、そのフィールドがこのフィールドの 長さを示す。Section 7.2では、 このフィールドの使用をより詳細に説明する。¶
Destination Connection IDに続くバイトは、その後に続く Source Connection IDフィールドのバイト単位の長さを含む。この長さは8ビットの 符号なし整数として符号化される。QUICバージョン1では、この値は20バイトを 超えてはならない(MUST NOT)。20より大きい値を持つ バージョン1ロングヘッダーを受信したエンドポイントは、パケットを破棄しなければならない (MUST)。Version Negotiationパケットを適切に形成するため、 サーバーは他のQUICバージョンからより長い接続IDを読み取ることができるべきである (SHOULD)。¶
Source Connection IDフィールドは、 Source Connection ID Lengthフィールドに続き、そのフィールドがこのフィールドの 長さを示す。Section 7.2では、このフィールドの使用をより詳細に説明する。¶
パケットの残りがある場合、それは型固有である。¶
このQUICバージョンでは、ロングヘッダーを持つ次のパケット種別が 定義される。¶
| Type | Name | Section |
|---|---|---|
| 0x00 | Initial | Section 17.2.2 |
| 0x01 | 0-RTT | Section 17.2.3 |
| 0x02 | Handshake | Section 17.2.4 |
| 0x03 | Retry | Section 17.2.5 |
ロングヘッダーパケットのヘッダー形式ビット、Destinationおよび Source Connection ID長、DestinationおよびSource Connection IDフィールド、ならびに Versionフィールドはバージョン非依存である。最初のバイトのその他のフィールドは バージョン固有である。異なるQUICバージョンのパケットがどのように解釈されるかの 詳細については、[QUIC-INVARIANTS]を参照。¶
フィールドおよびペイロードの解釈は、バージョンおよびパケット種別に 固有である。このバージョンの型固有の意味論は以下の節で説明されるが、このQUICバージョンの いくつかのロングヘッダーパケットは、次の追加フィールドを含む。¶
バイト0の2ビット(マスク0x0cを持つもの)は、複数の パケット種別にわたって予約される。これらのビットはヘッダー保護を使用して保護される。 Section 5.4 of [QUIC-TLS]を参照。 保護前に含まれる値は0に設定されなければならない(MUST)。 エンドポイントは、パケット保護とヘッダー保護の両方を取り除いた後にこれらのビットが 非ゼロ値であるパケットの受信を、PROTOCOL_VIOLATION型の接続エラーとして扱わなければならない (MUST)。ヘッダー保護のみを取り除いた後にそのようなパケットを 破棄すると、エンドポイントは攻撃にさらされる可能性がある。 Section 9.5 of [QUIC-TLS]を参照。¶
Packet Numberフィールドを含むパケット種別では、 バイト0の最下位2ビット(マスク0x03を持つもの)が、Packet Numberフィールドの 長さを含む。この長さは、Packet Numberフィールドのバイト単位の長さより1少ない 値として、符号なし2ビット整数で符号化される。つまり、Packet Numberフィールドの 長さは、このフィールドの値に1を加えたものである。これらのビットはヘッダー保護を 使用して保護される。Section 5.4 of [QUIC-TLS]を参照。¶
これは、パケットの残り(すなわちPacket Numberおよび Payloadフィールド)のバイト単位の長さであり、可変長整数 (Section 16)として符号化される。¶
このフィールドは1から4バイト長である。パケット番号は ヘッダー保護を使用して保護される。Section 5.4 of [QUIC-TLS]を参照。Packet Numberフィールドの長さは、 バイト0のPacket Number Lengthビットに符号化される。上記を参照。¶
これは、フレーム列を含むパケットのペイロードであり、 パケット保護を使用して保護される。¶
Version Negotiationパケットは本質的にバージョン固有ではない。 クライアントによって受信されると、Versionフィールドが値0を持つことに基づいて Version Negotiationパケットとして識別される。¶
Version Negotiationパケットは、サーバーがサポートしていない バージョンを含むクライアントパケットへの応答である。これはサーバーによってのみ送信される。¶
Version Negotiationパケットのレイアウトは次のとおりである。¶
Version Negotiation Packet {
Header Form (1) = 1,
Unused (7),
Version (32) = 0,
Destination Connection ID Length (8),
Destination Connection ID (0..2040),
Source Connection ID Length (8),
Source Connection ID (0..2040),
Supported Version (32) ...,
}
Unusedフィールドの値は、サーバーによって任意の値に設定される。 クライアントはこのフィールドの値を無視しなければならない(MUST)。 QUICが他のプロトコルと多重化される可能性がある場合([RFC7983]を参照)、 サーバーはVersion NegotiationパケットがFixed Bitフィールドを持つように見えるよう、 このフィールドの最上位ビット(0x40)を1に設定するべきである(SHOULD)。 他のQUICバージョンは同様の推奨を行わない可能性があることに注意すること。¶
Version NegotiationパケットのVersionフィールドは 0x00000000に設定されなければならない(MUST)。¶
サーバーは、受信したパケットのSource Connection IDフィールドの値を Destination Connection IDフィールドに含めなければならない(MUST)。 Source Connection IDの値は、受信したパケットのDestination Connection IDから コピーされなければならない(MUST)。これは最初にクライアントが ランダムに選択したものである。両方の接続IDをエコーすることで、クライアントは、 サーバーがそのパケットを受信したこと、およびVersion NegotiationパケットがInitialパケットを 観測していないエンティティによって生成されたものではないことについて、ある程度の保証を得る。¶
将来のQUICバージョンは、接続IDの長さについて異なる要件を 持つ可能性がある。特に、接続IDはより小さい最小長またはより大きい最大長を 持つ可能性がある。したがって、接続IDに関するバージョン固有の規則は、 Version Negotiationパケットを送信するかどうかの判断に影響してはならない (MUST NOT)。¶
Version Negotiationパケットの残りは、サーバーがサポートする 32ビットバージョンのリストである。¶
Version Negotiationパケットは確認応答されない。 これはサポートされていないバージョンを示すパケットへの応答としてのみ送信される。 Section 5.2.2を参照。¶
Version Negotiationパケットは、ロングヘッダー形式を使用する 他のパケットに存在するPacket NumberおよびLengthフィールドを含まない。したがって、 Version NegotiationパケットはUDPデータグラム全体を消費する。¶
サーバーは、単一のUDPデータグラムに応答して複数の Version Negotiationパケットを送信してはならない(MUST NOT)。¶
Initialパケットは、型値0x00のロングヘッダーを使用する。 これは鍵交換を実行するためにクライアントおよびサーバーによって送信される最初の CRYPTOフレームを運び、いずれの方向にもACKフレームを運ぶ。¶
Initial Packet {
Header Form (1) = 1,
Fixed Bit (1) = 1,
Long Packet Type (2) = 0,
Reserved Bits (2),
Packet Number Length (2),
Version (32),
Destination Connection ID Length (8),
Destination Connection ID (0..160),
Source Connection ID Length (8),
Source Connection ID (0..160),
Token Length (i),
Token (..),
Length (i),
Packet Number (8..32),
Packet Payload (8..),
}
Initialパケットは、ロングヘッダーに加えてLengthおよび Packet Numberフィールドを含む。Section 17.2を参照。 最初のバイトはReservedおよびPacket Number Lengthビットを含む。 Section 17.2も参照。Source Connection IDと Lengthフィールドの間には、Initialパケットに固有の2つの追加フィールドがある。¶
Tokenフィールドの長さをバイト単位で指定する 可変長整数。トークンが存在しない場合、この値は0である。サーバーによって 送信されるInitialパケットは、Token Lengthフィールドを0に設定しなければならない (MUST)。非ゼロのToken Lengthフィールドを持つInitial パケットを受信したクライアントは、そのパケットを破棄するか、PROTOCOL_VIOLATION型の 接続エラーを生成しなければならない(MUST)。¶
以前にRetryパケットまたはNEW_TOKENフレームで 提供されたトークンの値。Section 8.1を参照。¶
バージョン非認識のミドルボックスによる改ざんを防ぐため、 Initialパケットは、[QUIC-TLS]で 説明される接続およびバージョン固有の鍵(Initial鍵)で保護される。この保護は、 パケットを観測できる攻撃者に対する機密性または完全性を提供しないが、パケットを 観測できない攻撃者がInitialパケットを偽装することを防ぐ。¶
クライアントとサーバーは、初期の暗号ハンドシェイクメッセージを 含む任意のパケットにInitialパケット種別を使用する。これには、Retryパケットを 受信した後に送信されるパケットなど、初期の暗号メッセージを含む新しいパケットを 作成する必要があるすべての場合が含まれる。Section 17.2.5を参照。¶
サーバーは、クライアントInitialへの応答として最初のInitialパケットを 送信する。サーバーは複数のInitialパケットを送信してもよい(MAY)。 暗号鍵交換では、このデータの複数の往復または再送信が必要になる可能性がある。¶
Initialパケットのペイロードには、暗号ハンドシェイクメッセージを 含むCRYPTOフレーム(または複数のフレーム)、ACKフレーム、またはその両方が含まれる。 PING、PADDING、および型0x1cのCONNECTION_CLOSEフレームも許可される。 他のフレームを含むInitialパケットを受信したエンドポイントは、そのパケットを 不要なものとして破棄するか、接続エラーとして扱うことができる。¶
クライアントによって送信される最初のパケットは、常に最初の 暗号ハンドシェイクメッセージの開始または全体を含むCRYPTOフレームを含む。 最初に送信されるCRYPTOフレームは常にオフセット0から始まる。 Section 7を参照。¶
サーバーがTLS HelloRetryRequestを送信する場合 (Section 4.7 of [QUIC-TLS]を参照)、クライアントは別のInitialパケット列を 送信することに注意すること。これらのInitialパケットは暗号ハンドシェイクを継続し、 最初のInitialパケットのフライトで送信されたCRYPTOフレームのサイズに一致する オフセットから始まるCRYPTOフレームを含む。¶
クライアントは、最初のHandshakeパケットを送信すると、 Initialパケットの送信と処理の両方を停止する。サーバーは、最初のHandshakeパケットを 受信すると、Initialパケットの送信と処理を停止する。パケットがまだ飛行中であったり 確認応答待ちであったりしても、この時点以降、それ以上のInitialパケットを交換する 必要はない。Initialパケット保護鍵は、損失回復および輻輳制御状態とともに破棄される (Section 4.9.1 of [QUIC-TLS]を参照)。 Section 6.4 of [QUIC-RECOVERY]を参照。¶
CRYPTOフレーム内の任意のデータは、Initial鍵が 破棄されると破棄され、以後再送信されない。¶
0-RTTパケットは、型値0x01のロングヘッダーを使用し、 その後にLengthおよびPacket Numberフィールドが続く。Section 17.2を参照。最初のバイトはReservedおよびPacket Number Lengthビットを含む。 Section 17.2を参照。0-RTTパケットは、ハンドシェイク完了前に、 最初のフライトの一部としてクライアントからサーバーへ「early」データを運ぶために使用される。 TLSハンドシェイクの一部として、サーバーはこのearlyデータを受け入れるか拒否できる。¶
0-RTTデータとその制限に関する議論については、 Section 2.3 of [TLS13]を参照。¶
0-RTT Packet {
Header Form (1) = 1,
Fixed Bit (1) = 1,
Long Packet Type (2) = 1,
Reserved Bits (2),
Packet Number Length (2),
Version (32),
Destination Connection ID Length (8),
Destination Connection ID (0..160),
Source Connection ID Length (8),
Source Connection ID (0..160),
Length (i),
Packet Number (8..32),
Packet Payload (8..),
}
0-RTT保護パケットのパケット番号は、1-RTT保護パケットと 同じ空間を使用する。¶
クライアントがRetryパケットを受信した後、0-RTTパケットはサーバーにより 失われたか破棄された可能性が高い。クライアントは、新しいInitialパケットを送信した後、 0-RTTパケット内のデータの再送信を試みるべきである(SHOULD)。 送信される任意の新しいパケットには、新しいパケット番号が使用されなければならない (MUST)。Section 17.2.5.3で説明されるように、パケット番号の再使用は パケット保護を危殆化させる可能性がある。¶
クライアントは、Section 4.1.1 of [QUIC-TLS]で定義されるようにハンドシェイクが完了した後でのみ、 自身の0-RTTパケットに対する確認応答を受信する。¶
クライアントは、サーバーからの1-RTTパケットの処理を開始した後、 0-RTTパケットを送信してはならない(MUST NOT)。 これは、0-RTTパケットが1-RTTパケットからのフレームに対するいかなる応答も 含むことができないことを意味する。たとえば、クライアントは0-RTTパケットで ACKフレームを送信できない。それは1-RTTパケットのみを確認応答できるためである。 1-RTTパケットに対する確認応答は、1-RTTパケットで運ばれなければならない (MUST)。¶
サーバーは、記憶された上限(Section 7.4.1)の 違反を、適切な型の接続エラーとして扱うべきである(SHOULD) (たとえば、ストリームデータ上限を超過した場合はFLOW_CONTROL_ERROR)。¶
Handshakeパケットは、型値0x02のロングヘッダーを使用し、 その後にLengthおよびPacket Numberフィールドが続く。Section 17.2を参照。最初のバイトはReservedおよびPacket Number Lengthビットを含む。 Section 17.2を参照。これは、サーバーとクライアントからの 暗号ハンドシェイクメッセージおよび確認応答を運ぶために使用される。¶
Handshake Packet {
Header Form (1) = 1,
Fixed Bit (1) = 1,
Long Packet Type (2) = 2,
Reserved Bits (2),
Packet Number Length (2),
Version (32),
Destination Connection ID Length (8),
Destination Connection ID (0..160),
Source Connection ID Length (8),
Source Connection ID (0..160),
Length (i),
Packet Number (8..32),
Packet Payload (8..),
}
クライアントがサーバーからHandshakeパケットを受信すると、 クライアントは後続の暗号ハンドシェイクメッセージおよび確認応答をサーバーへ送信するために Handshakeパケットを使用する。¶
Handshakeパケット内のDestination Connection IDフィールドは、 パケットの受信者によって選択された接続IDを含む。Source Connection IDには、 パケットの送信者が使用したい接続IDが含まれる。Section 7.2を参照。¶
Handshakeパケットは独自のパケット番号空間を持つため、 サーバーが送信する最初のHandshakeパケットはパケット番号0を含む。¶
このパケットのペイロードはCRYPTOフレームを含み、 PING、PADDING、またはACKフレームを含む可能性がある。Handshakeパケットは 型0x1cのCONNECTION_CLOSEフレームを含んでもよい(MAY)。 エンドポイントは、他のフレームを持つHandshakeパケットの受信を PROTOCOL_VIOLATION型の接続エラーとして扱わなければならない (MUST)。¶
Initialパケット(Section 17.2.2.1を参照)と同様に、Handshakeパケット用の CRYPTOフレーム内のデータは、Handshake保護鍵が破棄されると破棄され、 以後再送信されない。¶
Figure 18に示すように、 Retryパケットは型値0x03のロングパケットヘッダーを使用する。これはサーバーによって 作成されたアドレス検証トークンを運ぶ。リトライを実行したいサーバーによって使用される。 Section 8.1を参照。¶
Retry Packet {
Header Form (1) = 1,
Fixed Bit (1) = 1,
Long Packet Type (2) = 3,
Unused (4),
Version (32),
Destination Connection ID Length (8),
Destination Connection ID (0..160),
Source Connection ID Length (8),
Source Connection ID (0..160),
Retry Token (..),
Retry Integrity Tag (128),
}
Retryパケットは保護されたフィールドを含まない。 Unusedフィールドの値はサーバーによって任意の値に設定される。クライアントはこれらの ビットを無視しなければならない(MUST)。 ロングヘッダー由来のフィールドに加えて、次の追加フィールドを含む。¶
サーバーがクライアントのアドレスを検証するために 使用できる不透明なトークン。¶
[QUIC-TLS]のSection 5.8("Retry Packet Integrity")で定義される。¶
サーバーは、クライアントがInitialパケットの Source Connection IDに含めた接続IDをDestination Connection IDに設定する。¶
サーバーは、Source Connection IDフィールドに自身が選択した 接続IDを含める。この値は、クライアントによって送信されたパケットの Destination Connection IDフィールドと等しくてはならない(MUST NOT)。 クライアントは、自身のInitialパケットのDestination Connection IDフィールドと 同一のSource Connection IDフィールドを含むRetryパケットを破棄しなければならない (MUST)。クライアントは、Retryパケットの Source Connection IDフィールドの値を、以後に送信するパケットの Destination Connection IDフィールドで使用しなければならない (MUST)。¶
サーバーは、Initialおよび0-RTTパケットに応答して Retryパケットを送信してもよい(MAY)。 サーバーは受信した0-RTTパケットを破棄またはバッファできる。サーバーは Initialまたは0-RTTパケットを受信するたびに複数のRetryパケットを送信できる。 サーバーは、単一のUDPデータグラムに応答して複数のRetryパケットを送信してはならない (MUST NOT)。¶
クライアントは、各接続試行について最大1つのRetryパケットを 受け入れて処理しなければならない(MUST)。 クライアントがサーバーからInitialまたはRetryパケットを受信して処理した後、 それ以後に受信するRetryパケットはすべて破棄しなければならない (MUST)。¶
クライアントは、検証できないRetry Integrity Tagを持つ Retryパケットを破棄しなければならない(MUST)。 Section 5.8 of [QUIC-TLS]を参照。これは攻撃者がRetryパケットを 注入する能力を低減し、Retryパケットの偶発的な破損から保護する。クライアントは 長さ0のRetry Tokenフィールドを持つRetryパケットを破棄しなければならない (MUST)。¶
クライアントは、提供されたRetryトークンを含む InitialパケットでRetryパケットに応答し、接続確立を継続する。¶
クライアントは、このInitialパケットの Destination Connection IDフィールドを、Retryパケット内のSource Connection IDフィールドの 値に設定する。Destination Connection IDフィールドの変更は、Initialパケットの保護に 使用される鍵の変更ももたらす。また、TokenフィールドをRetryパケットで提供された トークンに設定する。サーバーが自身のトークン検証ロジックの一部として接続IDを 含める可能性があるため、クライアントはSource Connection IDを変更してはならない (MUST NOT)。Section 8.1.4を参照。¶
Retryパケットはパケット番号を含まず、クライアントによって 明示的に確認応答されることはできない。¶
クライアントからの後続のInitialパケットは、Retryパケットからの 接続IDおよびトークン値を含む。クライアントは、Retryパケットの Source Connection IDフィールドをDestination Connection IDフィールドにコピーし、 更新された値を持つInitialパケットを受信するまでこの値を使用する。 Section 7.2を参照。 Tokenフィールドの値は、後続のすべてのInitialパケットにコピーされる。 Section 8.1.2を参照。¶
Destination Connection IDおよびTokenフィールドの更新を除き、 クライアントによって送信されるInitialパケットは、最初のInitialパケットと同じ制限を 受ける。クライアントは、このパケットに含めたものと同じ暗号ハンドシェイクメッセージを 使用しなければならない(MUST)。サーバーは、 異なる暗号ハンドシェイクメッセージを含むパケットを、接続エラーとして扱うか破棄してもよい (MAY)。Tokenフィールドを含めると、暗号ハンドシェイクメッセージに 利用できる空間が減るため、クライアントが複数のInitialパケットを送信する必要が 生じる可能性があることに注意すること。¶
クライアントは、Retryパケットを受信した後、サーバーによって 提供された接続IDへ0-RTTパケットを送信することで0-RTTを試みてもよい (MAY)。¶
クライアントは、Retryパケットを処理した後、いかなる パケット番号空間についてもパケット番号をリセットしてはならない (MUST NOT)。特に、0-RTTパケットは、Retryパケットの受信時に 再送信される可能性が最も高い機密情報を含む。これらの新しい0-RTTパケットを 保護するために使用される鍵は、Retryパケットへの応答の結果としては変化しない。 しかし、これらのパケットで送信されるデータは、以前に送信されたものと異なる可能性がある。 同じパケット番号でこれらの新しいパケットを送信すると、同じ鍵とノンスが異なる内容を 保護するために使用される可能性があるため、それらのパケットのパケット保護を 危殆化させる可能性が高い。サーバーは、クライアントがパケット番号をリセットしたことを 検出した場合、接続を中止してもよい(MAY)。¶
クライアントとサーバーの間で交換されるInitialおよびRetryパケットで 使用される接続IDは、トランスポートパラメーターにコピーされ、 Section 7.3で説明されるように検証される。¶
このQUICバージョンは、ショートパケットヘッダーを使用する単一の パケット種別を定義する。¶
1-RTTパケットはショートパケットヘッダーを使用する。 これはバージョンおよび1-RTT鍵がネゴシエートされた後に使用される。¶
1-RTT Packet {
Header Form (1) = 0,
Fixed Bit (1) = 1,
Spin Bit (1),
Reserved Bits (2),
Key Phase (1),
Packet Number Length (2),
Destination Connection ID (0..160),
Packet Number (8..32),
Packet Payload (8..),
}
1-RTTパケットは次のフィールドを含む。¶
バイト0の最上位ビット(0x80)は、 ショートヘッダーでは0に設定される。¶
バイト0の次のビット(0x40)は1に設定される。 このビットがゼロ値のパケットは、このバージョンでは有効なパケットではなく、 破棄されなければならない(MUST)。このビットの値が1であることにより、 QUICは他のプロトコルと共存できる。[RFC7983]を参照。¶
バイト0の3番目の最上位ビット(0x20)は レイテンシスピンビットであり、Section 17.4で 説明されるように設定される。¶
バイト0の次の2ビット(マスク0x18を持つもの)は 予約される。これらのビットはヘッダー保護を使用して保護される。 Section 5.4 of [QUIC-TLS]を参照。保護前に含まれる値は 0に設定されなければならない(MUST)。 エンドポイントは、パケット保護とヘッダー保護の両方を取り除いた後に、 これらのビットが非ゼロ値であるパケットの受信を、PROTOCOL_VIOLATION型の 接続エラーとして扱わなければならない(MUST)。 ヘッダー保護のみを取り除いた後にそのようなパケットを破棄すると、 エンドポイントは攻撃にさらされる可能性がある。Section 9.5 of [QUIC-TLS]を参照。¶
バイト0の次のビット(0x04)は鍵フェーズを示す。 これにより、パケットの受信者は、そのパケットを保護するために使用される パケット保護鍵を識別できる。詳細は[QUIC-TLS]を参照。このビットはヘッダー保護を 使用して保護される。Section 5.4 of [QUIC-TLS]を参照。¶
バイト0の最下位2ビット(マスク0x03を持つもの)は、 Packet Numberフィールドの長さを含む。この長さは、Packet Numberフィールドの バイト単位の長さより1少ない値として、符号なし2ビット整数で符号化される。 つまり、Packet Numberフィールドの長さは、このフィールドの値に1を加えたものである。 これらのビットはヘッダー保護を使用して保護される。Section 5.4 of [QUIC-TLS]を参照。¶
Destination Connection IDは、パケットの意図された 受信者によって選択された接続IDである。詳細はSection 5.1を参照。¶
Packet Numberフィールドは1から4バイト長である。 パケット番号はヘッダー保護を使用して保護される。Section 5.4 of [QUIC-TLS]を参照。Packet Numberフィールドの長さは Packet Number Lengthフィールドに符号化される。詳細は Section 17.1を参照。¶
1-RTTパケットは常に1-RTT保護ペイロードを含む。¶
ショートヘッダーパケットのヘッダー形式ビットおよび Destination Connection IDフィールドはバージョン非依存である。残りのフィールドは 選択されたQUICバージョンに固有である。異なるQUICバージョンのパケットがどのように 解釈されるかの詳細については、[QUIC-INVARIANTS]を参照。¶
1-RTTパケット(Section 17.3.1)に対して定義される レイテンシスピンビットは、接続の継続期間を通じて、ネットワークパス上の観測点からの 受動的なレイテンシ監視を可能にする。サーバーは受信したスピン値を反映し、クライアントは 1 RTT後にそれを「スピン」する。オンパスの観測者は、2つのスピンビット切り替えイベント間の 時間を測定して、接続のエンドツーエンドRTTを推定できる。¶
スピンビットは1-RTTパケットにのみ存在する。接続の初期RTTは ハンドシェイクを観測することで測定可能であるためである。したがって、スピンビットは バージョンネゴシエーションおよび接続確立が完了した後に利用可能である。 オンパス測定とレイテンシスピンビットの使用については、[QUIC-MANAGEABILITY]で さらに議論される。¶
スピンビットは、このQUICバージョンのOPTIONALな 機能である。この機能をサポートしないエンドポイントは、以下で定義されるように、 それを無効にしなければならない(MUST)。¶
各エンドポイントは、接続についてスピンビットを有効にするか無効にするかを 単独で決定する。実装は、クライアントおよびサーバーの管理者が、グローバルに、または 接続ごとにスピンビットを無効にできるようにしなければならない(MUST)。 管理者によってスピンビットが無効にされていない場合でも、エンドポイントは、スピンビットを 無効にするQUIC接続がネットワーク上で一般的に観測されることを保証するため、少なくとも 16個のネットワークパスに1つ、または16個の接続IDに1つのランダムな選択について、 スピンビットの使用を無効にしなければならない(MUST)。 各エンドポイントが独立にスピンビットを無効にするため、これにより、スピンビット信号が およそ8つのネットワークパスに1つで無効になることが保証される。¶
スピンビットが無効である場合、エンドポイントはスピンビットを任意の値に 設定してもよく(MAY)、任意の到着値を無視しなければならない (MUST)。エンドポイントは、各パケットごとに独立に選択された ランダム値、または各接続IDごとに独立に選択されたランダム値にスピンビットを設定することが 推奨される(RECOMMENDED)。¶
接続についてスピンビットが有効である場合、エンドポイントは各ネットワークパスに 対してスピン値を維持し、そのパス上で1-RTTパケットを送信するときに、パケットヘッダーの スピンビットを現在保存されている値に設定する。スピン値は、エンドポイントにおいて 各ネットワークパスごとに0へ初期化される。各エンドポイントはまた、各パス上でピアから 見た最大パケット番号を記憶する。¶
サーバーが、与えられたネットワークパス上でクライアントから見た最大パケット番号を 増加させる1-RTTパケットを受信すると、そのパスのスピン値を受信パケット内のスピンビットと 等しい値に設定する。¶
クライアントが、与えられたネットワークパス上でサーバーから見た最大パケット番号を 増加させる1-RTTパケットを受信すると、そのパスのスピン値を受信パケット内のスピンビットの 反転値に設定する。¶
エンドポイントは、あるネットワークパスで使用される接続IDを変更するとき、 そのネットワークパスのスピン値を0にリセットする。¶
[QUIC-TLS]で定義される quic_transport_parameters拡張のextension_dataフィールドは、QUICトランスポートパラメーターを含む。 それらは、Figure 20に示すように、トランスポートパラメーターの列として符号化される。¶
Transport Parameters {
Transport Parameter (..) ...,
}
各トランスポートパラメーターは、Figure 21に 示すように、(識別子、長さ、値)のタプルとして符号化される。¶
Transport Parameter {
Transport Parameter ID (i),
Transport Parameter Length (i),
Transport Parameter Value (..),
}
Transport Parameter Lengthフィールドは、Transport Parameter Valueフィールドの長さをバイト単位で含む。¶
QUICはトランスポートパラメーターをバイト列へ符号化し、それが 暗号ハンドシェイクに含められる。¶
整数値Nについて31 * N + 27という形式の識別子を持つ
トランスポートパラメーターは、未知のトランスポートパラメーターを無視するという要件を
実行させるために予約される。これらのトランスポートパラメーターは意味論を持たず、
任意の値を運ぶことができる。¶
本節では、本文書で定義されるトランスポートパラメーターを詳述する。¶
ここに列挙される多くのトランスポートパラメーターは整数値を持つ。 整数として識別されるこれらのトランスポートパラメーターは、可変長整数符号化を使用する。 Section 16を参照。特に明記されない限り、 トランスポートパラメーターが存在しない場合、そのデフォルト値は0である。¶
次のトランスポートパラメーターが定義される。¶
このパラメーターは、クライアントによって送信された 最初のInitialパケットのDestination Connection IDフィールドの値である。 Section 7.3を参照。このトランスポートパラメーターはサーバーによってのみ送信される。¶
最大アイドルタイムアウトは、整数として符号化される ミリ秒単位の値である。Section 10.1を参照。 両エンドポイントがこのトランスポートパラメーターを省略するか、値0を指定した場合、 アイドルタイムアウトは無効になる。¶
ステートレスリセットトークンは、ステートレスリセットの検証に 使用される。Section 10.3を参照。 このパラメーターは16バイトの列である。このトランスポートパラメーターは クライアントによって送信されてはならない(MUST NOT)が、 サーバーによって送信されてもよい(MAY)。このトランスポートパラメーターを送信しないサーバーは、 ハンドシェイク中にネゴシエートされた接続IDについて、ステートレスリセット (Section 10.3)を使用できない。¶
最大UDPペイロードサイズパラメーターは、エンドポイントが 受信する意思のあるUDPペイロードのサイズを制限する整数値である。この制限より大きい ペイロードを持つUDPデータグラムは、受信者によって処理される可能性が低い。¶
このパラメーターのデフォルトは、許可される最大UDP ペイロードである65527である。1200未満の値は無効である。¶
この制限は、パスMTUと同じようにデータグラムサイズに対する 追加の制約として作用するが、これはパスではなくエンドポイントの性質である。 Section 14を参照。これは、エンドポイントが 到着パケットの保持に割り当てる空間であることが期待される。¶
初期最大データパラメーターは、接続上で送信できる データ量の最大値の初期値を含む整数値である。これは、ハンドシェイク完了直後に 接続に対してMAX_DATA(Section 19.9)を送信することと等価である。¶
このパラメーターは、ローカルで開始される双方向ストリームの 初期フロー制御上限を指定する整数値である。この上限は、トランスポートパラメーターを 送信するエンドポイントによって開かれる、新たに作成された双方向ストリームに適用される。 クライアントのトランスポートパラメーターでは、これは識別子の最下位2ビットが 0x00に設定されたストリームに適用される。サーバーのトランスポートパラメーターでは、 これは最下位2ビットが0x01に設定されたストリームに適用される。¶
このパラメーターは、ピアによって開始される双方向ストリームの 初期フロー制御上限を指定する整数値である。この上限は、トランスポートパラメーターを 受信するエンドポイントによって開かれる、新たに作成された双方向ストリームに適用される。 クライアントのトランスポートパラメーターでは、これは識別子の最下位2ビットが 0x01に設定されたストリームに適用される。サーバーのトランスポートパラメーターでは、 これは最下位2ビットが0x00に設定されたストリームに適用される。¶
このパラメーターは、単方向ストリームの初期フロー制御上限を 指定する整数値である。この上限は、トランスポートパラメーターを受信するエンドポイントに よって開かれる、新たに作成された単方向ストリームに適用される。クライアントの トランスポートパラメーターでは、これは識別子の最下位2ビットが0x03に設定された ストリームに適用される。サーバーのトランスポートパラメーターでは、これは最下位2ビットが 0x02に設定されたストリームに適用される。¶
初期最大双方向ストリームパラメーターは、このトランスポート パラメーターを受信するエンドポイントが開始することを許可される双方向ストリームの 初期最大数を含む整数値である。このパラメーターが存在しないかゼロである場合、 ピアはMAX_STREAMSフレームが送信されるまで双方向ストリームを開くことができない。 このパラメーターを設定することは、同じ値を持つ対応する型のMAX_STREAMS (Section 19.11)を送信することと等価である。¶
初期最大単方向ストリームパラメーターは、このトランスポート パラメーターを受信するエンドポイントが開始することを許可される単方向ストリームの 初期最大数を含む整数値である。このパラメーターが存在しないかゼロである場合、 ピアはMAX_STREAMSフレームが送信されるまで単方向ストリームを開くことができない。 このパラメーターを設定することは、同じ値を持つ対応する型のMAX_STREAMS (Section 19.11)を送信することと等価である。¶
確認応答遅延指数は、ACKフレーム (Section 19.3)内のACK Delayフィールドを 復号するために使用される指数を示す整数値である。この値が存在しない場合、 デフォルト値3(乗数8を示す)が仮定される。20を超える値は無効である。¶
最大確認応答遅延は、エンドポイントが確認応答の送信を 遅延させる最大時間をミリ秒単位で示す整数値である。この値は、アラーム発火における 受信者の予想される遅延を含むべきである(SHOULD)。 たとえば、受信者が5msのタイマーを設定し、アラームが通常最大1ms遅れて発火する場合、 max_ack_delayとして6msを送信するべきである。この値が存在しない場合、 デフォルトとして25ミリ秒が仮定される。214以上の値は無効である。¶
disable active migrationトランスポートパラメーターは、 エンドポイントがハンドシェイク中に使用されているアドレス上での能動的な接続移行 (Section 9)をサポートしない場合に含められる。 このトランスポートパラメーターを受信したエンドポイントは、ピアがハンドシェイク中に 使用したアドレスへ送信するとき、新しいローカルアドレスを使用してはならない (MUST NOT)。このトランスポートパラメーターは、 クライアントがpreferred_addressトランスポートパラメーターに基づいて行動した後の 接続移行を禁止しない。このパラメーターは長さ0の値である。¶
サーバーの優先アドレスは、Section 9.6で説明されるように、ハンドシェイクの終端で サーバーアドレスの変更を実施するために使用される。このトランスポートパラメーターは サーバーによってのみ送信される。サーバーは、一方のアドレスファミリーについて 全ゼロのアドレスとポート(0.0.0.0:0または[::]:0)を送信することで、 一方のアドレスファミリーの優先アドレスのみを送信することを選択してもよい (MAY)。IPアドレスはネットワークバイト順で符号化される。¶
preferred_addressトランスポートパラメーターは、 IPv4とIPv6の両方についてアドレスとポートを含む。4バイトのIPv4 Addressフィールドの 後に、関連する2バイトのIPv4 Portフィールドが続く。その後に、16バイトの IPv6 Addressフィールドと2バイトのIPv6 Portフィールドが続く。アドレスとポートの ペアの後に、Connection ID Lengthフィールドが後続のConnection IDフィールドの長さを 記述する。最後に、16バイトのStateless Reset Tokenフィールドが、その接続IDに 関連付けられたステートレスリセットトークンを含む。このトランスポートパラメーターの形式は、 下のFigure 22に示される。¶
Connection IDフィールドとStateless Reset Tokenフィールドは、 シーケンス番号1を持つ代替接続IDを含む。Section 5.1.1を参照。 これらの値を優先アドレスとともに送信することで、クライアントが優先アドレスへの 移行を開始するとき、未使用のアクティブ接続IDが少なくとも1つ存在することが保証される。¶
優先アドレスのConnection IDおよびStateless Reset Tokenフィールドは、 NEW_CONNECTION_IDフレーム(Section 19.15)の対応するフィールドと構文および意味論が同一である。 長さ0の接続IDを選択するサーバーは、優先アドレスを提供してはならない (MUST NOT)。同様に、サーバーはこのトランスポート パラメーターに長さ0の接続IDを含めてはならない(MUST NOT)。 クライアントは、これらの要件への違反をTRANSPORT_PARAMETER_ERROR型の接続エラーとして 扱わなければならない(MUST)。¶
Preferred Address {
IPv4 Address (32),
IPv4 Port (16),
IPv6 Address (128),
IPv6 Port (16),
Connection ID Length (8),
Connection ID (..),
Stateless Reset Token (128),
}
これは、エンドポイントが保存する意思のあるピアからの 接続IDの最大数を指定する整数値である。この値には、ハンドシェイク中に受信した 接続ID、preferred_addressトランスポートパラメーターで受信したもの、および NEW_CONNECTION_IDフレームで受信したものが含まれる。 active_connection_id_limitパラメーターの値は少なくとも2でなければならない (MUST)。2未満の値を受信したエンドポイントは、 TRANSPORT_PARAMETER_ERROR型のエラーで接続を閉じなければならない(MUST)。 このトランスポートパラメーターが存在しない場合、デフォルトとして2が仮定される。 エンドポイントが長さ0の接続IDを発行する場合、NEW_CONNECTION_IDフレームを送信することは ないため、ピアから受信したactive_connection_id_limit値を無視する。¶
これは、接続についてエンドポイントが送信する最初の InitialパケットのSource Connection IDフィールドに含めた値である。 Section 7.3を参照。¶
これは、サーバーがRetryパケットのSource Connection IDフィールドに含めた値である。Section 7.3を参照。 このトランスポートパラメーターはサーバーによってのみ送信される。¶
存在する場合、初期のストリームごとのフロー制御上限を設定する トランスポートパラメーター(initial_max_stream_data_bidi_local、 initial_max_stream_data_bidi_remote、およびinitial_max_stream_data_uni)は、 対応する型のすべてのストリームについて、開いた直後にMAX_STREAM_DATAフレーム (Section 19.10)を送信することと等価である。 トランスポートパラメーターが存在しない場合、その型のストリームはフロー制御上限0で 開始する。¶
クライアントは、サーバー専用のトランスポートパラメーター、 original_destination_connection_id、preferred_address、 retry_source_connection_id、またはstateless_reset_tokenを含めてはならない (MUST NOT)。サーバーは、これらのトランスポートパラメーターの いずれかの受信をTRANSPORT_PARAMETER_ERROR型の接続エラーとして扱わなければならない (MUST)。¶
Section 12.4で説明されるように、パケットは 1つ以上のフレームを含む。本節では、コアQUICフレーム種別の形式と意味論を説明する。¶
PADDINGフレーム(type=0x00)は意味的な値を持たない。 PADDINGフレームは、パケットのサイズを増やすために使用できる。パディングは、 Initialパケットを要求される最小サイズまで増やすため、または保護されたパケットに対する トラフィック解析からの保護を提供するために使用できる。¶
PADDINGフレームはFigure 23に示すように形式化される。この図は PADDINGフレームが内容を持たないことを示している。つまり、PADDINGフレームは、 そのフレームをPADDINGフレームとして識別する単一バイトで構成される。¶
PADDING Frame {
Type (i) = 0x00,
}
エンドポイントは、ピアがまだ生存していることを検証するため、 またはピアへの到達可能性を確認するために、PINGフレーム(type=0x01)を使用できる。¶
PINGフレームはFigure 24に示すように形式化され、この図はPINGフレームが 内容を持たないことを示している。¶
PING Frame {
Type (i) = 0x01,
}
PINGフレームの受信者は、このフレームを含むパケットを確認応答するだけでよい。¶
アプリケーションまたはアプリケーションプロトコルが接続のタイムアウトを 防ぎたい場合、PINGフレームは接続を維持するために使用できる。 Section 10.1.2を参照。¶
受信者は、受信し処理したパケットを送信者に知らせるため、 ACKフレーム(types 0x02および0x03)を送信する。ACKフレームは1つ以上のACK Rangeを 含む。ACK Rangeは確認応答されたパケットを識別する。フレーム型が0x03である場合、 ACKフレームは、この時点までに接続上で受信された、関連するECNマーキングを持つ QUICパケットの累積カウントも含む。QUIC実装は両方の型を適切に処理しなければならず (MUST)、送信するパケットについてECNを有効にしている場合、 輻輳状態を管理するためにECN節の情報を使用するべきである(SHOULD)。¶
QUICの確認応答は取り消し不能である。一度確認応答されると、 パケットは将来のACKフレームに現れなくても、確認応答済みのままである。これはTCPの Selective Acknowledgments(SACKs)[RFC2018]におけるrenegingとは異なる。¶
異なるパケット番号空間のパケットは、同じ数値を使用して識別されることがある。 パケットに対する確認応答は、パケット番号とパケット番号空間の両方を示す必要がある。 これは、各ACKフレームが、それを含むパケットと同じ空間内のパケット番号のみを確認応答することで 実現される。¶
Version NegotiationおよびRetryパケットは、パケット番号を含まないため 確認応答できない。ACKフレームに依存する代わりに、これらのパケットはクライアントによって 次に送信されるInitialパケットによって暗黙的に確認応答される。¶
ACKフレームはFigure 25に示すように形式化される。¶
ACK Frame {
Type (i) = 0x02..0x03,
Largest Acknowledged (i),
ACK Delay (i),
ACK Range Count (i),
First ACK Range (i),
ACK Range (..) ...,
[ECN Counts (..)],
}
ACKフレームは次のフィールドを含む。¶
ピアが確認応答している最大パケット番号を表す可変長整数。 これは通常、ACKフレームの生成前にピアが受信した最大パケット番号である。 QUICのロングまたはショートヘッダー内のパケット番号とは異なり、ACKフレーム内の値は 切り詰められない。¶
確認応答遅延をマイクロ秒単位で符号化する可変長整数。 Section 13.2.5を参照。これは、フィールド内の 値にACKフレームの送信者によって送信されたack_delay_exponentトランスポート パラメーターの2の累乗を乗じることで復号される。 Section 18.2を参照。 遅延を単に整数として表す場合と比較して、この符号化は、解像度を下げる代わりに、 同じバイト数でより大きい値の範囲を許可する。¶
フレーム内のACK Rangeフィールドの数を指定する可変長整数。¶
Largest Acknowledgedに先行して連続して確認応答される パケット数を示す可変長整数。すなわち、その範囲内で確認応答される最小パケットは、 Largest AcknowledgedフィールドからFirst ACK Range値を減算することで決定される。¶
交互に確認応答されない(Gap)パケット範囲と確認応答される (ACK Range)パケット範囲を追加で含む。Section 19.3.1を参照。¶
3つのECNカウント。Section 19.3.2を参照。¶
各ACK Rangeは、パケット番号の降順で交互に現れるGap値と ACK Range Length値で構成される。ACK Rangeは繰り返すことができる。Gap値および ACK Range Length値の数はACK Range Countフィールドによって決定され、 ACK Range Countフィールド内の各値につき、それぞれ1つずつ値が存在する。¶
ACK RangeはFigure 26に示すように構造化される。¶
各ACK Rangeを構成するフィールドは次のとおりである。¶
直前のACK Range内の最小パケット番号より1小さい パケット番号に先行する、連続した未確認応答パケットの数を示す可変長整数。¶
直前のGapによって決定される最大パケット番号に 先行する、連続して確認応答されたパケットの数を示す可変長整数。¶
Gap値およびACK Range Length値は、効率のため相対整数符号化を 使用する。各符号化値は正であるが、値は減算されるため、各ACK Rangeは より小さい番号のパケットを順に記述する。¶
各ACK Rangeは、その範囲内の最大パケット番号に先行する 確認応答されたパケット数を示すことで、連続したパケット範囲を確認応答する。 値0は、最大パケット番号のみが確認応答されることを示す。より大きいACK Range値は より大きい範囲を示し、それに対応して範囲内の最小パケット番号はより小さい値となる。 したがって、範囲の最大パケット番号が与えられると、最小値は次の式で決定される。¶
smallest = largest - ack_range¶
ACK Rangeは、最小パケット番号から最大パケット番号までの すべてのパケットを両端を含めて確認応答する。¶
ACK Rangeの最大値は、先行するすべてのACK Range Lengthおよび Gapのサイズを累積的に減算することで決定される。¶
各Gapは、確認応答されないパケット範囲を示す。ギャップ内の パケット数は、Gapフィールドの符号化値より1大きい。¶
Gapフィールドの値は、後続のACK Rangeの最大パケット番号値を 次の式を使用して確立する。¶
largest = previous_smallest - gap - 2¶
計算されたパケット番号のいずれかが負である場合、 エンドポイントはFRAME_ENCODING_ERROR型の接続エラーを生成しなければならない (MUST)。¶
ACKフレームは、型値の最下位ビット(すなわちtype 0x03)を 使用して、ECNフィードバックを示し、パケットのIPヘッダーに関連付けられた ECT(0)、ECT(1)、またはECN-CEのECNコードポイントを持つQUICパケットの受信を 報告する。ECNカウントは、ACKフレーム型が0x03の場合にのみ存在する。¶
存在する場合、Figure 27に示すように、3つのECNカウントがある。¶
ECNカウントフィールドは次のとおりである。¶
ACKフレームのパケット番号空間内で、ECT(0) コードポイントを持って受信されたパケットの総数を表す可変長整数。¶
ACKフレームのパケット番号空間内で、ECT(1) コードポイントを持って受信されたパケットの総数を表す可変長整数。¶
ACKフレームのパケット番号空間内で、ECN-CE コードポイントを持って受信されたパケットの総数を表す可変長整数。¶
ECNカウントは、各パケット番号空間ごとに別々に維持される。¶
エンドポイントは、ストリームの送信部分を突然終了するために RESET_STREAMフレーム(type=0x04)を使用する。¶
RESET_STREAMを送信した後、エンドポイントは識別されたストリーム上での STREAMフレームの送信および再送信を停止する。RESET_STREAMの受信者は、そのストリーム上で すでに受信した任意のデータを破棄できる。¶
送信専用ストリームに対するRESET_STREAMフレームを受信した エンドポイントは、STREAM_STATE_ERRORエラーで接続を終了しなければならない (MUST)。¶
RESET_STREAMフレームはFigure 28に示すように形式化される。¶
RESET_STREAM Frame {
Type (i) = 0x04,
Stream ID (i),
Application Protocol Error Code (i),
Final Size (i),
}
RESET_STREAMフレームは次のフィールドを含む。¶
終了されるストリームのストリームIDの可変長整数符号化。¶
ストリームが閉じられる理由を示すアプリケーションプロトコル エラーコード(Section 20.2を参照)を 含む可変長整数。¶
RESET_STREAM送信者によるストリームの最終サイズを バイト単位で示す可変長整数。Section 4.5を参照。¶
エンドポイントは、アプリケーション要求に従って到着データが 受信時に破棄されていることを伝達するため、STOP_SENDINGフレーム(type=0x05)を使用する。 STOP_SENDINGは、ピアにストリーム上での送信停止を要求する。¶
STOP_SENDINGフレームは、"Recv"または"Size Known"状態のストリームに 対して送信できる。Section 3.2を参照。 まだ作成されていないローカルで開始されたストリームに対するSTOP_SENDINGフレームの受信は、 STREAM_STATE_ERROR型の接続エラーとして扱われなければならない(MUST)。 受信専用ストリームに対するSTOP_SENDINGフレームを受信したエンドポイントは、 STREAM_STATE_ERRORエラーで接続を終了しなければならない(MUST)。¶
STOP_SENDINGフレームはFigure 29に示すように形式化される。¶
STOP_SENDING Frame {
Type (i) = 0x05,
Stream ID (i),
Application Protocol Error Code (i),
}
STOP_SENDINGフレームは次のフィールドを含む。¶
無視されているストリームのストリームIDを運ぶ可変長整数。¶
送信者がそのストリームを無視している、アプリケーションが 指定した理由を含む可変長整数。Section 20.2を参照。¶
CRYPTOフレーム(type=0x06)は、暗号ハンドシェイクメッセージを 送信するために使用される。0-RTTを除くすべてのパケット種別で送信できる。 CRYPTOフレームは、暗号プロトコルに順序付きのバイトストリームを提供する。 CRYPTOフレームは、ストリーム識別子を持たないこと、フロー制御されないこと、ならびに 任意のオフセット、任意の長さ、およびストリーム終端のマーカーを運ばないことを除き、 STREAMフレームと機能的に同一である。¶
CRYPTOフレームはFigure 30に示すように形式化される。¶
CRYPTO Frame {
Type (i) = 0x06,
Offset (i),
Length (i),
Crypto Data (..),
}
CRYPTOフレームは次のフィールドを含む。¶
このCRYPTOフレーム内のデータについて、ストリーム内の バイトオフセットを指定する可変長整数。¶
このCRYPTOフレーム内のCrypto Dataフィールドの長さを 指定する可変長整数。¶
暗号メッセージデータ。¶
各暗号化レベルには、暗号ハンドシェイクデータの別個のフローがあり、 それぞれはオフセット0から始まる。これは、各暗号化レベルがデータの別個のCRYPTOストリームとして 扱われることを意味する。¶
ストリーム上で配送される最大オフセット、すなわちオフセットと データ長の合計は、262-1を超えることはできない。この制限を超えるフレームの 受信は、FRAME_ENCODING_ERRORまたはCRYPTO_BUFFER_EXCEEDED型の接続エラーとして 扱われなければならない(MUST)。¶
データがどのストリームに属するかを示すストリームIDを含む STREAMフレームとは異なり、CRYPTOフレームは暗号化レベルごとに単一のストリームのデータを 運ぶ。そのストリームには明示的な終端がないため、CRYPTOフレームはFINビットを持たない。¶
サーバーは、将来の接続のためにInitialパケットのヘッダーで送信する トークンをクライアントに提供するため、NEW_TOKENフレーム(type=0x07)を送信する。¶
NEW_TOKENフレームはFigure 31に示すように形式化される。¶
NEW_TOKEN Frame {
Type (i) = 0x07,
Token Length (i),
Token (..),
}
NEW_TOKENフレームは次のフィールドを含む。¶
トークンの長さをバイト単位で指定する可変長整数。¶
クライアントが将来のInitialパケットで使用できる不透明なblob。 トークンは空であってはならない(MUST NOT)。 クライアントは、空のTokenフィールドを持つNEW_TOKENフレームの受信を FRAME_ENCODING_ERROR型の接続エラーとして扱わなければならない(MUST)。¶
フレームを含むパケットが誤って失われたと判断された場合、 クライアントは同じトークン値を含む複数のNEW_TOKENフレームを受信する可能性がある。 クライアントは、接続試行を関連付けるために使用される可能性のある重複値を破棄する責任を負う。 Section 8.1.3を参照。¶
クライアントはNEW_TOKENフレームを送信してはならない (MUST NOT)。サーバーはNEW_TOKENフレームの受信を PROTOCOL_VIOLATION型の接続エラーとして扱わなければならない(MUST)。¶
STREAMフレームは暗黙的にストリームを作成し、ストリームデータを運ぶ。 STREAMフレーム内のTypeフィールドは、0b00001XXXという形式(または0x08から0x0fまでの 値集合)を取る。フレーム型の下位3ビットは、フレーム内に存在するフィールドを決定する。¶
まだ作成されていないローカルで開始されたストリーム、または送信専用 ストリームに対するSTREAMフレームを受信した場合、エンドポイントはSTREAM_STATE_ERRORエラーで 接続を終了しなければならない(MUST)。¶
STREAMフレームはFigure 32に示すように形式化される。¶
STREAM Frame {
Type (i) = 0x08..0x0f,
Stream ID (i),
[Offset (i)],
[Length (i)],
Stream Data (..),
}
STREAMフレームは次のフィールドを含む。¶
ストリームのストリームIDを示す可変長整数。 Section 2.1を参照。¶
このSTREAMフレーム内のデータについて、ストリーム内の バイトオフセットを指定する可変長整数。このフィールドはOFFビットが1に設定される場合に 存在する。Offsetフィールドが存在しない場合、オフセットは0である。¶
このSTREAMフレーム内のStream Dataフィールドの長さを 指定する可変長整数。このフィールドはLENビットが1に設定される場合に存在する。 LENビットが0に設定される場合、Stream Dataフィールドはパケット内の残りすべての バイトを消費する。¶
配送される、指定されたストリームからのバイト。¶
Stream Dataフィールドの長さが0である場合、STREAMフレーム内の オフセットは、次に送信されることになるバイトのオフセットである。¶
ストリーム内の最初のバイトのオフセットは0である。ストリーム上で 配送される最大オフセット、すなわちオフセットとデータ長の合計は、262-1を 超えることはできない。そのデータに対してフロー制御クレジットを提供することが不可能なためである。 この制限を超えるフレームの受信は、FRAME_ENCODING_ERRORまたはFLOW_CONTROL_ERROR型の 接続エラーとして扱われなければならない(MUST)。¶
MAX_DATAフレーム(type=0x10)は、接続全体で送信できるデータ量の 最大値をピアに知らせるため、フロー制御で使用される。¶
MAX_DATAフレームはFigure 33に示すように形式化される。¶
MAX_DATA Frame {
Type (i) = 0x10,
Maximum Data (i),
}
MAX_DATAフレームは次のフィールドを含む。¶
接続全体で送信できるデータ量の最大値を、バイト単位で 示す可変長整数。¶
STREAMフレームで送信されるすべてのデータは、この制限に算入される。 すべてのストリーム上の最終サイズの合計は、終端状態のストリームを含め、受信者によって 通知された値を超えてはならない(MUST NOT)。 エンドポイントは、自身が送信した最大データ値を超えるデータを受信した場合、 FLOW_CONTROL_ERROR型のエラーで接続を終了しなければならない(MUST)。 これにはEarly Data内の記憶された上限の違反も含まれる。Section 7.4.1を参照。¶
MAX_STREAM_DATAフレーム(type=0x11)は、ストリーム上で送信できる データ量の最大値をピアに知らせるため、フロー制御で使用される。¶
MAX_STREAM_DATAフレームは、"Recv"状態のストリームに対して送信できる。 Section 3.2を参照。 まだ作成されていないローカルで開始されたストリームに対するMAX_STREAM_DATAフレームの受信は、 STREAM_STATE_ERROR型の接続エラーとして扱われなければならない(MUST)。 受信専用ストリームに対するMAX_STREAM_DATAフレームを受信したエンドポイントは、 STREAM_STATE_ERRORエラーで接続を終了しなければならない(MUST)。¶
MAX_STREAM_DATAフレームはFigure 34に示すように形式化される。¶
MAX_STREAM_DATA Frame {
Type (i) = 0x11,
Stream ID (i),
Maximum Stream Data (i),
}
MAX_STREAM_DATAフレームは次のフィールドを含む。¶
影響を受けるストリームのストリームIDであり、可変長整数として 符号化される。¶
識別されたストリーム上で送信できるデータ量の最大値を、 バイト単位で示す可変長整数。¶
この制限に対してデータを数えるとき、エンドポイントは、そのストリーム上で 送信または受信されたデータの最大受信オフセットを考慮する。損失または並べ替えにより、 ストリーム上の最大受信オフセットが、そのストリームで受信されたデータの総サイズより 大きくなる可能性がある。STREAMフレームの受信が最大受信オフセットを増加させないこともある。¶
ストリーム上で送信されるデータは、受信者によって通知された最大の maximum stream data値を超えてはならない(MUST NOT)。 エンドポイントは、影響を受けるストリームについて自身が送信した最大のmaximum stream dataより 多くのデータを受信した場合、FLOW_CONTROL_ERROR型のエラーで接続を終了しなければならない (MUST)。これにはEarly Data内の記憶された上限の違反も含まれる。 Section 7.4.1を参照。¶
MAX_STREAMSフレーム(type=0x12または0x13)は、ピアが開くことを 許可される、与えられた型のストリームの累積数を知らせる。type 0x12のMAX_STREAMSフレームは 双方向ストリームに適用され、type 0x13のMAX_STREAMSフレームは単方向ストリームに適用される。¶
MAX_STREAMSフレームはFigure 35に示すように形式化される。¶
MAX_STREAMS Frame {
Type (i) = 0x12..0x13,
Maximum Streams (i),
}
MAX_STREAMSフレームは次のフィールドを含む。¶
接続の存続期間中に開くことができる、対応する型の ストリームの累積数。この値は260を超えることはできない。 262-1より大きいストリームIDを符号化することは不可能であるためである。 この制限より大きいストリームを開くことを許可するフレームの受信は、 FRAME_ENCODING_ERROR型の接続エラーとして扱われなければならない (MUST)。¶
損失または並べ替えにより、エンドポイントは以前に受信したものより 低いストリーム上限を持つMAX_STREAMSフレームを受信することがある。ストリーム上限を 増加させないMAX_STREAMSフレームは無視されなければならない(MUST)。¶
エンドポイントは、ピアによって設定された現在のストリーム上限で 許可される数を超えるストリームを開いてはならない(MUST NOT)。 たとえば、単方向ストリーム上限3を受信したサーバーは、ストリーム3、7、および11を 開くことを許可されるが、ストリーム15は許可されない。ピアが許可された数を超えるストリームを 開いた場合、エンドポイントはSTREAM_LIMIT_ERROR型のエラーで接続を終了しなければならない (MUST)。これにはEarly Data内の記憶された上限の違反も含まれる。 Section 7.4.1を参照。¶
これらのフレーム(および対応するトランスポートパラメーター)は、 同時に開くことができるストリームの数を記述しないことに注意すること。この上限には、 閉じられたストリームと開いているストリームの両方が含まれる。¶
送信者は、データを送信したいが接続レベルのフロー制御のために 送信できない場合、DATA_BLOCKEDフレーム(type=0x14)を送信するべきである (SHOULD)。Section 4を参照。 DATA_BLOCKEDフレームは、フロー制御アルゴリズムの調整への入力として使用できる。 Section 4.2を参照。¶
DATA_BLOCKEDフレームはFigure 36に示すように形式化される。¶
DATA_BLOCKED Frame {
Type (i) = 0x14,
Maximum Data (i),
}
DATA_BLOCKEDフレームは次のフィールドを含む。¶
ブロックが発生した接続レベルの上限を示す可変長整数。¶
送信者は、データを送信したいがストリームレベルのフロー制御のために 送信できない場合、STREAM_DATA_BLOCKEDフレーム(type=0x15)を送信するべきである (SHOULD)。このフレームはDATA_BLOCKED (Section 19.12)に類似している。¶
送信専用ストリームに対するSTREAM_DATA_BLOCKEDフレームを受信した エンドポイントは、STREAM_STATE_ERRORエラーで接続を終了しなければならない (MUST)。¶
STREAM_DATA_BLOCKEDフレームは Figure 37に示すように形式化される。¶
STREAM_DATA_BLOCKED Frame {
Type (i) = 0x15,
Stream ID (i),
Maximum Stream Data (i),
}
STREAM_DATA_BLOCKEDフレームは次のフィールドを含む。¶
送信者は、ストリームを開きたいがピアによって設定された最大ストリーム 上限のために開けない場合、STREAMS_BLOCKEDフレーム(type=0x16または0x17)を送信するべきである (SHOULD)。Section 19.11を参照。 type 0x16のSTREAMS_BLOCKEDフレームは双方向ストリーム上限に達したことを示すために 使用され、type 0x17のSTREAMS_BLOCKEDフレームは単方向ストリーム上限に達したことを示すために 使用される。¶
STREAMS_BLOCKEDフレームはストリームを開かないが、新しいストリームが 必要であり、ストリーム上限がストリーム作成を妨げたことをピアに知らせる。¶
STREAMS_BLOCKEDフレームはFigure 38に示すように形式化される。¶
STREAMS_BLOCKED Frame {
Type (i) = 0x16..0x17,
Maximum Streams (i),
}
STREAMS_BLOCKEDフレームは次のフィールドを含む。¶
フレームが送信された時点で許可されていた最大ストリーム数を 示す可変長整数。この値は260を超えることはできない。 262-1より大きいストリームIDを符号化することは不可能であるためである。 より大きいストリームIDを符号化するフレームの受信は、STREAM_LIMIT_ERRORまたは FRAME_ENCODING_ERROR型の接続エラーとして扱われなければならない (MUST)。¶
エンドポイントは、接続移行時のリンク可能性を断ち切るために使用できる 代替接続IDをピアに提供するため、NEW_CONNECTION_IDフレーム(type=0x18)を送信する。 Section 9.5を参照。¶
NEW_CONNECTION_IDフレームはFigure 39に示すように形式化される。¶
NEW_CONNECTION_ID Frame {
Type (i) = 0x18,
Sequence Number (i),
Retire Prior To (i),
Length (8),
Connection ID (8..160),
Stateless Reset Token (128),
}
NEW_CONNECTION_IDフレームは次のフィールドを含む。¶
送信者によって接続IDに割り当てられたシーケンス番号であり、 可変長整数として符号化される。Section 5.1.1を参照。¶
どの接続IDが廃止されるべきかを示す可変長整数。 Section 5.1.2を参照。¶
接続IDの長さを含む8ビット符号なし整数。 1未満および20より大きい値は無効であり、FRAME_ENCODING_ERROR型の接続エラーとして 扱われなければならない(MUST)。¶
指定された長さの接続ID。¶
関連付けられた接続IDが使用されたとき、ステートレスリセットに 使用される128ビット値。Section 10.3を参照。¶
エンドポイントは、現在ピアに長さ0のDestination Connection IDを持つ パケットの送信を要求している場合、このフレームを送信してはならない (MUST NOT)。接続IDの長さをゼロ長に変更すること、または ゼロ長から変更することは、接続IDの値がいつ変更されたかを識別することを困難にする。 長さ0のDestination Connection IDを持つパケットを送信しているエンドポイントは、 NEW_CONNECTION_IDフレームの受信をPROTOCOL_VIOLATION型の接続エラーとして扱わなければならない (MUST)。¶
送信エラー、タイムアウト、および再送信により、同じNEW_CONNECTION_ID フレームが複数回受信される可能性がある。同じフレームを複数回受信しても、接続エラーとして 扱われてはならない(MUST NOT)。受信者は、 NEW_CONNECTION_IDフレームで提供されたシーケンス番号を使用して、同じNEW_CONNECTION_IDフレームを 複数回受信することを処理できる。¶
エンドポイントが、以前に発行された接続IDを、異なるStateless Reset Token フィールド値または異なるSequence Numberフィールド値で繰り返すNEW_CONNECTION_IDフレームを 受信した場合、または1つのシーケンス番号が異なる接続IDに使用された場合、エンドポイントは その受信をPROTOCOL_VIOLATION型の接続エラーとして扱ってもよい(MAY)。¶
Retire Prior Toフィールドは、接続セットアップ中および preferred_addressトランスポートパラメーターで確立された接続IDに適用される。 Section 5.1.2を参照。Retire Prior Toフィールドの値は、 Sequence Numberフィールドの値以下でなければならない(MUST)。 Sequence Numberフィールドの値より大きいRetire Prior Toフィールドの値の受信は、 FRAME_ENCODING_ERROR型の接続エラーとして扱われなければならない(MUST)。¶
送信者がRetire Prior To値を示した後、後続のNEW_CONNECTION_IDフレームで 送信されるより小さい値は効果を持たない。受信者は、受信した最大のRetire Prior To値を 増加させない任意のRetire Prior Toフィールドを無視しなければならない(MUST)。¶
以前に受信したNEW_CONNECTION_IDフレームのRetire Prior Toフィールドより 小さいシーケンス番号を持つNEW_CONNECTION_IDフレームを受信したエンドポイントは、そのシーケンス番号について すでにそうしていない限り、新たに受信した接続IDを廃止する対応するRETIRE_CONNECTION_IDフレームを 送信しなければならない(MUST)。¶
エンドポイントは、ピアによって発行された接続IDを今後使用しないことを 示すため、RETIRE_CONNECTION_IDフレーム(type=0x19)を送信する。これには、ハンドシェイク中に 提供された接続IDが含まれる。RETIRE_CONNECTION_IDフレームの送信はまた、将来の使用のために 追加の接続IDを送信するようピアに要求する役割も果たす。Section 5.1を参照。 新しい接続IDは、NEW_CONNECTION_IDフレーム(Section 19.15)を使用してピアへ配送できる。¶
接続IDの廃止は、その接続IDに関連付けられたステートレスリセットトークンを 無効にする。¶
RETIRE_CONNECTION_IDフレームは Figure 40に示すように形式化される。¶
RETIRE_CONNECTION_ID Frame {
Type (i) = 0x19,
Sequence Number (i),
}
RETIRE_CONNECTION_IDフレームは次のフィールドを含む。¶
廃止される接続IDのシーケンス番号。 Section 5.1.2を参照。¶
以前にピアへ送信した任意の値より大きいシーケンス番号を含む RETIRE_CONNECTION_IDフレームの受信は、PROTOCOL_VIOLATION型の接続エラーとして 扱われなければならない(MUST)。¶
RETIRE_CONNECTION_IDフレームで指定されるシーケンス番号は、 そのフレームが含まれるパケットのDestination Connection IDフィールドを参照してはならない (MUST NOT)。ピアはこれをPROTOCOL_VIOLATION型の接続エラーとして 扱ってもよい(MAY)。¶
ピアから長さ0の接続IDを提供されていた場合、エンドポイントはこのフレームを 送信できない。長さ0の接続IDを提供するエンドポイントは、RETIRE_CONNECTION_IDフレームの 受信をPROTOCOL_VIOLATION型の接続エラーとして扱わなければならない(MUST)。¶
エンドポイントは、ピアへの到達可能性を確認するため、および 接続移行中のパス検証のために、PATH_CHALLENGEフレーム(type=0x1a)を使用できる。¶
PATH_CHALLENGEフレームはFigure 41に示すように形式化される。¶
PATH_CHALLENGE Frame {
Type (i) = 0x1a,
Data (64),
}
PATH_CHALLENGEフレームは次のフィールドを含む。¶
この8バイトフィールドは任意のデータを含む。¶
PATH_CHALLENGEフレームに64ビットのエントロピーを含めることで、 値を正しく推測するよりもパケットを受信する方が容易であることが保証される。¶
このフレームの受信者は、同じData値を含むPATH_RESPONSEフレーム (Section 19.18)を生成しなければならない (MUST)。¶
PATH_RESPONSEフレーム(type=0x1b)は、PATH_CHALLENGEフレームへの 応答として送信される。¶
PATH_RESPONSEフレームはFigure 42に示すように形式化される。PATH_RESPONSEフレームの形式は PATH_CHALLENGEフレームの形式と同一である。Section 19.17を参照。¶
PATH_RESPONSE Frame {
Type (i) = 0x1b,
Data (64),
}
PATH_RESPONSEフレームの内容が、エンドポイントによって以前に送信された PATH_CHALLENGEフレームの内容と一致しない場合、エンドポイントはPROTOCOL_VIOLATION型の 接続エラーを生成してもよい(MAY)。¶
エンドポイントは、接続が閉じられつつあることをピアに通知するために CONNECTION_CLOSEフレーム(type=0x1cまたは0x1d)を送信する。type 0x1cの CONNECTION_CLOSEフレームは、QUIC層のみでのエラー、またはエラーの不存在 (NO_ERRORコード)を通知するために使用される。type 0x1dのCONNECTION_CLOSEフレームは、 QUICを使用するアプリケーションのエラーを通知するために使用される。¶
明示的に閉じられていない開いたストリームがある場合、それらは 接続が閉じられるときに暗黙的に閉じられる。¶
CONNECTION_CLOSEフレームはFigure 43に示すように形式化される。¶
CONNECTION_CLOSE Frame {
Type (i) = 0x1c..0x1d,
Error Code (i),
[Frame Type (i)],
Reason Phrase Length (i),
Reason Phrase (..),
}
CONNECTION_CLOSEフレームは次のフィールドを含む。¶
この接続を閉じる理由を示す可変長整数。 type 0x1cのCONNECTION_CLOSEフレームは、Section 20.1で 定義される空間のコードを使用する。type 0x1dのCONNECTION_CLOSEフレームは、 アプリケーションプロトコルによって定義されるコードを使用する。 Section 20.2を参照。¶
エラーを引き起こしたフレームの型を符号化する可変長整数。 フレーム型が不明な場合、値0(PADDINGフレームへの言及に相当)が使用される。 CONNECTION_CLOSEのアプリケーション固有の変種(type 0x1d)はこのフィールドを含まない。¶
理由句の長さをバイト単位で指定する可変長整数。 CONNECTION_CLOSEフレームは複数のパケットに分割できないため、パケットサイズに対する 任意の制限は、理由句に利用可能な空間も制限する。¶
閉鎖に関する追加の診断情報。送信者がError Code値を超える 詳細を与えないことを選択する場合、これは長さ0であってもよい。これはUTF-8符号化文字列 [RFC3629]であるべきである(SHOULD)。 ただし、このフレームは、言語タグなど、そのテキストを作成したエンティティ以外による 理解を助ける情報を運ばない。¶
CONNECTION_CLOSEのアプリケーション固有の変種(type 0x1d)は、 0-RTTまたは1-RTTパケットを使用してのみ送信できる。Section 12.5を参照。アプリケーションがハンドシェイク中に接続を放棄したい場合、 エンドポイントはInitialまたはHandshakeパケット内で、APPLICATION_ERRORのエラーコードを持つ CONNECTION_CLOSEフレーム(type 0x1c)を送信できる。¶
サーバーは、ハンドシェイクの確認をクライアントに通知するために HANDSHAKE_DONEフレーム(type=0x1e)を使用する。¶
HANDSHAKE_DONEフレームはFigure 44に示すように形式化され、 この図はHANDSHAKE_DONEフレームが内容を持たないことを示している。¶
HANDSHAKE_DONE Frame {
Type (i) = 0x1e,
}
HANDSHAKE_DONEフレームはサーバーによってのみ送信できる。 サーバーは、ハンドシェイクを完了する前にHANDSHAKE_DONEフレームを送信してはならない (MUST NOT)。サーバーは、HANDSHAKE_DONEフレームの受信を PROTOCOL_VIOLATION型の接続エラーとして扱わなければならない(MUST)。¶
QUICフレームは自己記述的な符号化を使用しない。したがって、 エンドポイントはパケットを正常に処理できるようになる前に、すべてのフレームの構文を 理解する必要がある。これはフレームの効率的な符号化を可能にするが、エンドポイントが ピアにとって未知の型のフレームを送信できないことを意味する。¶
新しい型のフレームを使用したいQUICへの拡張は、まずピアがそのフレームを 理解できることを保証しなければならない(MUST)。 エンドポイントは、拡張フレーム型を受信する意思があることを通知するために、 トランスポートパラメーターを使用できる。1つのトランスポートパラメーターは、1つ以上の 拡張フレーム型への対応を示すことができる。¶
コアプロトコル機能(フレーム型を含む)を変更または置換する拡張は、 その組み合わせのふるまいが明示的に定義されていない限り、同じ機能を変更または置換する 他の拡張と組み合わせることが困難になる。そのような拡張は、同じプロトコルコンポーネントを 変更する以前に定義された拡張との相互作用を定義するべきである(SHOULD)。¶
拡張フレームは輻輳制御されなければならず(MUST)、 ACKフレームを送信させなければならない(MUST)。 例外は、ACKフレームを置換または補完する拡張フレームである。拡張で規定されない限り、 拡張フレームはフロー制御に含まれない。¶
フレーム型の割り当てを管理するためにIANAレジストリが使用される。 Section 22.4を参照。¶
QUICトランスポートエラーコードおよびアプリケーションエラーコードは、 62ビットの符号なし整数である。¶
本節では、type 0x1cのCONNECTION_CLOSEフレームで使用できる、 定義済みのQUICトランスポートエラーコードを列挙する。これらのエラーは接続全体に 適用される。¶
エンドポイントは、エラーがない状態で接続が突然閉じられつつ あることを通知するために、CONNECTION_CLOSEとともにこれを使用する。¶
エンドポイントが内部エラーに遭遇し、接続を継続できない。¶
サーバーが新しい接続の受け入れを拒否した。¶
エンドポイントが、対応するストリーム型について自身が 通知したストリーム上限を超えるストリーム識別子に対するフレームを受信した。¶
(1) エンドポイントが、以前に確立された最終サイズを 超えるデータを含むSTREAMフレームを受信した、(2) エンドポイントが、 すでに受信されたストリームデータのサイズより小さい最終サイズを含む STREAMフレームまたはRESET_STREAMフレームを受信した、または (3) エンドポイントが、 すでに確立されたものと異なる最終サイズを含むSTREAMフレームまたはRESET_STREAMフレームを 受信した。¶
エンドポイントが不正な形式のフレームを受信した。 たとえば、未知の型のフレーム、またはパケットの残りが運べる数より多い確認応答範囲を 持つACKフレームである。¶
エンドポイントが、不正な形式である、不正な値を含む、 必須トランスポートパラメーターを省略している、禁止されたトランスポートパラメーターを含む、 またはその他のエラーがあるトランスポートパラメーターを受信した。¶
ピアによって提供された接続IDの数が、通知された active_connection_id_limitを超えている。¶
エンドポイントが、より具体的なエラーコードでは 覆われないプロトコル準拠のエラーを検出した。¶
サーバーが、不正なTokenフィールドを含むクライアントInitialを 受信した。¶
アプリケーションまたはアプリケーションプロトコルが、 接続を閉じさせた。¶
エンドポイントが、バッファできる量を超えるデータを CRYPTOフレームで受信した。¶
エンドポイントが、与えられた接続で使用される AEADアルゴリズムの機密性または完全性の上限に達した。¶
エンドポイントが、ネットワークパスがQUICをサポートできないと 判断した。パスが十分大きなMTUをサポートしない場合を除き、エンドポイントがこのコードを 運ぶCONNECTION_CLOSEフレームを受信する可能性は低い。¶
暗号ハンドシェイクに失敗した。使用される暗号ハンドシェイクに 固有のエラーコードを運ぶために、256個の値の範囲が予約される。暗号ハンドシェイクに TLSが使用される場合に発生するエラーのコードは、Section 4.8 of [QUIC-TLS]で説明される。¶
新しいエラーコードの登録に関する詳細は、 Section 22.5を参照。¶
これらのエラーコードの定義にあたって、いくつかの原則が適用される。 受信者側で特定の処置を必要とする可能性があるエラー条件には、一意のコードが与えられる。 一般的な条件を表すエラーには、特定のコードが与えられる。これらの条件のいずれにも 該当しない場合、エラーコードは、フロー制御やトランスポートパラメーター処理のような スタックの一般的な機能を識別するために使用される。最後に、実装がより具体的なコードを 使用できない、または使用する意思がない条件に対して、汎用エラーが提供される。¶
アプリケーションエラーコードの管理は、アプリケーションプロトコルに 委ねられる。アプリケーションプロトコルエラーコードは、RESET_STREAMフレーム (Section 19.4)、STOP_SENDINGフレーム(Section 19.5)、およびtype 0x1dの CONNECTION_CLOSEフレーム(Section 19.19)で使用される。¶
QUICの目標は、安全なトランスポート接続を提供することである。 Section 21.1はこれらの性質の概要を提供し、 後続の節では、既知の攻撃と対策の説明を含め、これらの性質に関する制約および注意点を 議論する。¶
QUICの完全なセキュリティ分析は本文書の範囲外である。 本節では、実装者への助けとプロトコル分析の指針として、望まれるセキュリティ性質を 非形式的に説明する。¶
QUICは、[SEC-CONS]で説明される脅威モデルを仮定し、 そのモデルから生じる多くの攻撃に対する保護を提供する。¶
この目的のため、攻撃は受動的攻撃と能動的攻撃に分けられる。 受動的攻撃者はネットワークからパケットを読む能力を持つ一方、能動的攻撃者はさらに ネットワークへパケットを書き込む能力も持つ。ただし、受動的攻撃には、接続を構成する パケットが通る経路におけるルーティング変更またはその他の変更を引き起こす能力を持つ攻撃者が 関与する可能性がある。¶
攻撃者はさらに、オンパス攻撃者またはオフパス攻撃者のいずれかとして 分類される。オンパス攻撃者は、観測した任意のパケットを読み取り、変更し、またはその パケットが宛先へ到達しないように除去できる。一方、オフパス攻撃者はパケットを観測するが、 元のパケットが意図された宛先へ到達することを防ぐことはできない。両方の型の攻撃者は、 任意のパケットを送信することもできる。この定義は、オフパス攻撃者がパケットを観測できる点で、 Section 3.5 of [SEC-CONS]の定義とは異なる。¶
ハンドシェイク、保護されたパケット、および接続移行の性質は、 個別に考慮される。¶
QUICハンドシェイクはTLS 1.3ハンドシェイクを組み込み、 Appendix E.1 of [TLS13]で説明される暗号的性質を継承する。 QUICのセキュリティ性質の多くは、TLSハンドシェイクがこれらの性質を提供することに 依存する。TLSハンドシェイクに対する任意の攻撃はQUICに影響する可能性がある。¶
セッション鍵の秘匿性または一意性、あるいは参加するピアの認証を 危殆化させるTLSハンドシェイクへの任意の攻撃は、それらの鍵に依存するQUICによって 提供される他のセキュリティ保証に影響する。たとえば、移行(Section 9)は、 ネットワークパス間でのリンク可能性を避けるため、TLSハンドシェイクを用いた鍵の ネゴシエーションとQUICパケット保護の両方における機密性保護の有効性に依存する。¶
TLSハンドシェイクの完全性に対する攻撃は、攻撃者が アプリケーションプロトコルまたはQUICバージョンの選択に影響を与えることを 可能にする可能性がある。¶
TLSによって提供される性質に加えて、QUICハンドシェイクは ハンドシェイクに対するDoS攻撃への一定の防御を提供する。¶
アドレス検証(Section 8)は、与えられたアドレスを主張するエンティティが、 そのアドレスでパケットを受信できることを検証するために使用される。アドレス検証は、 増幅攻撃の標的を、攻撃者がパケットを観測できるアドレスに限定する。¶
アドレス検証の前は、エンドポイントが送信できるものは 制限される。エンドポイントは、未検証アドレスから受信したデータの3倍を超えるデータを、 その未検証アドレスへ送信できない。¶
完全なハンドシェイクのためのサーバーの最初のフライトを 計算することは、署名と鍵交換計算の両方を必要とするため、潜在的に高コストである。 計算DoS攻撃を防ぐため、Retryパケットは安価なトークン交換機構を提供し、 サーバーが高価な計算を行う前に、単一の往復を代償としてクライアントのIPアドレスを 検証できるようにする。ハンドシェイクが成功した後、サーバーはクライアントに 新しいトークンを発行でき、これによりこのコストを発生させずに新しい接続確立が 可能になる。¶
オンパスまたはオフパス攻撃者は、Initialパケットを 置換したり競合させたりすることで、ハンドシェイクを失敗させることができる。 有効なInitialパケットが交換された後は、後続のHandshakeパケットはHandshake鍵で 保護され、オンパス攻撃者は、エンドポイントが試行を放棄するようにパケットを ドロップする以外に、ハンドシェイク失敗を強制できない。¶
オンパス攻撃者は、いずれかの側のパケットのアドレスを 置換することもでき、そのためクライアントまたはサーバーにリモートアドレスの 誤った見方を持たせることができる。このような攻撃は、NATが実行する機能と 区別できない。¶
ハンドシェイク全体は暗号的に保護される。 Initialパケットはバージョンごとの鍵で暗号化され、Handshakeおよびそれ以降の パケットはTLS鍵交換から派生した鍵で暗号化される。さらに、パラメーター ネゴシエーションはTLSトランスクリプトに組み込まれるため、通常のTLS ネゴシエーションと同じ完全性保証を提供する。攻撃者は(バージョン固有のsaltを 知っている限り)クライアントのトランスポートパラメーターを観測できるが、 サーバーのトランスポートパラメーターを観測できず、パラメーターネゴシエーションに 影響を与えることもできない。¶
接続IDは暗号化されないが、すべてのパケットで完全性保護される。¶
このQUICバージョンはバージョンネゴシエーション機構を 組み込んでいない。互換性のないバージョンの実装は、単に接続の確立に失敗する。¶
パケット保護(Section 12.1)は、Version Negotiationパケットを除くすべてのパケットに認証付き暗号を 適用する。ただし、InitialおよびRetryパケットは、バージョン固有の鍵素材を使用するため 限定的な保護を持つ。詳細は[QUIC-TLS]を 参照。本節では、保護されたパケットに対する受動的および能動的攻撃を考慮する。¶
オンパス攻撃者とオフパス攻撃者の両方が、将来の時点で パケット保護に対するオフライン攻撃を行うため、観測したパケットを保存する 受動的攻撃を仕掛けることができる。これは、任意のネットワーク上の任意のパケットの 任意の観測者に当てはまる。¶
接続の有効なパケットを観測できずにパケットを注入する攻撃者が 成功する可能性は低い。パケット保護により、有効なパケットはハンドシェイク中に 確立された鍵素材を所有するエンドポイントによってのみ生成されることが保証されるためである。 Sections 7および 21.1.1を参照。同様に、パケットを 観測し、それらのパケットに新しいデータを挿入しようとしたり既存データを変更しようとする 任意の能動的攻撃者は、Initialパケットを除き、受信エンドポイントによって有効とみなされる パケットを生成できないはずである。¶
能動的攻撃者が、転送または注入するパケットの保護されていない部分、 たとえば送信元または宛先アドレスを書き換えるスプーフィング攻撃は、攻撃者が元の エンドポイントへパケットを転送できる場合にのみ有効である。パケット保護により、 パケットペイロードはハンドシェイクを完了したエンドポイントによってのみ処理でき、 不正なパケットはそれらのエンドポイントによって無視される。¶
攻撃者は、パケットとUDPデータグラムの間の境界を変更することもでき、 複数のパケットを単一のデータグラムへ結合したり、結合されたパケットを複数の データグラムへ分割したりする。パディングを要求するInitialパケットを含む データグラムを除き、パケットがデータグラム内でどのように配置されるかの変更は、 いくつかの性能特性を変化させる可能性はあるものの、接続に機能的な影響を及ぼさない。¶
接続移行(Section 9)は、エンドポイントに、複数のパス上のIPアドレスとポートの間で 遷移する能力を提供し、非プロービングフレームの送受信には一度に1つのパスを使用する。 パス検証(Section 8.2)は、特定のパス上で 送信されたパケットをピアが受信する意思があり、かつ受信可能であることを確立する。 これは、スプーフィングされたアドレスへ送信されるパケット数を制限することで、 アドレススプーフィングの影響を低減するのに役立つ。¶
本節では、さまざまな型のDoS攻撃の下での接続移行の意図された セキュリティ性質を説明する。¶
観測したパケットが意図された宛先に到達しなくなるように できる攻撃者は、オンパス攻撃者とみなされる。攻撃者がクライアントとサーバーの間に 存在する場合、エンドポイントは与えられたパス上で接続性を確立するために、 攻撃者を通じてパケットを送信する必要がある。¶
オンパス攻撃者は次のことができる。¶
オンパス攻撃者は次のことができない。¶
オンパス攻撃者は、観測したパケットを変更する機会を持つ。 しかし、パケットの認証された部分への任意の変更は、パケットペイロードが 認証され暗号化されているため、受信エンドポイントによって不正として ドロップされる原因となる。¶
QUICは、オンパス攻撃者の能力を次のように制約することを目指す。¶
オフパス攻撃者は、クライアントとサーバーの間のパス上に 直接存在しないが、クライアントとサーバーの間で送信される一部またはすべての パケットのコピーを取得できる可能性がある。また、それらのパケットのコピーを いずれかのエンドポイントへ送信することもできる。¶
オフパス攻撃者は次のことができる。¶
オフパス攻撃者は次のことができない。¶
オフパス攻撃者は、観測したパケットの変更されたコピーを 作成し、それらのコピーをネットワークへ注入でき、場合によっては送信元および 宛先アドレスをスプーフィングできる。¶
この議論の目的上、オフパス攻撃者は、観測した元のパケットが 到着する前に宛先エンドポイントへ到達する、変更されたパケットのコピーを ネットワークへ注入する能力を持つと仮定する。言い換えると、攻撃者は エンドポイント間の正当なパケットとの競争に一貫して「勝つ」能力を持ち、 元のパケットが受信者によって無視される原因となる可能性がある。¶
また、攻撃者はNAT状態に影響を与えるために必要なリソースを 持つと仮定する。特に、攻撃者はエンドポイントにそのNATバインディングを失わせ、 その後、自身のトラフィックに使用するため同じポートを取得できる。¶
QUICは、オフパス攻撃者の能力を次のように制約することを目指す。¶
限定的なオンパス攻撃者とは、サーバーとクライアントの間で 元のパケットを複製および転送することでパケットの改善されたルーティングを提供し、 それらのパケットを元のコピーより先に到着させ、元のパケットが宛先エンドポイントに よってドロップされる原因となるオフパス攻撃者である。¶
限定的なオンパス攻撃者は、エンドポイント間の元のパス上に いない点でオンパス攻撃者と異なり、したがってエンドポイントによって送信された 元のパケットは依然として宛先へ到達する。これは、コピーされたパケットを 元のパスより速く宛先へルーティングすることに将来失敗しても、元のパケットが 宛先へ到達することを妨げないことを意味する。¶
限定的なオンパス攻撃者は次のことができる。¶
限定的なオンパス攻撃者は次のことができない。¶
限定的なオンパス攻撃者は、元のパケットが複製パケットより 先に到着する時点までしかパケットを遅延させることができない。これは、元のパスより 悪いレイテンシのルーティングを提供できないことを意味する。限定的なオンパス攻撃者が パケットをドロップしても、元のコピーは依然として宛先エンドポイントへ到着する。¶
QUICは、限定的なオフパス攻撃者の能力を次のように制約することを目指す。¶
これらの保証は、同じ理由により、任意のNATに対して 提供される保証と同じであることに注意すること。¶
暗号化され認証されたトランスポートとして、QUICはサービス拒否に対する 一連の保護を提供する。暗号ハンドシェイクが完了すると、QUICエンドポイントは認証されていない ほとんどのパケットを破棄し、攻撃者が既存の接続へ干渉する能力を大きく制限する。¶
接続が確立された後、QUICエンドポイントは一部の未認証ICMPパケット (Section 14.2.1を参照)を受け入れる可能性があるが、 これらのパケットの使用は極めて限定される。エンドポイントが受け入れる可能性のある唯一の 他の型のパケットはステートレスリセット(Section 10.3)であり、 これはトークンが使用されるまで秘密に保たれることに依存する。¶
接続の作成中、QUICはネットワークパス外からの攻撃に対する保護のみを 提供する。すべてのQUICパケットは、受信者がそのピアからの先行パケットを見たことの証明を含む。¶
ハンドシェイク中はアドレスを変更できないため、エンドポイントは 異なるネットワークパスで受信されたパケットを破棄できる。¶
SourceおよびDestination Connection IDフィールドは、ハンドシェイク中の オフパス攻撃に対する主要な保護手段である。Section 8.1を参照。 これらはピアによって設定された値と一致することが要求される。InitialおよびStateless Resetを 除き、エンドポイントは、自身が以前に選択した値と一致するDestination Connection IDフィールドを 含むパケットのみを受け入れる。これはVersion Negotiationパケットに提供される唯一の保護である。¶
Initialパケット内のDestination Connection IDフィールドは、予測困難になるよう クライアントによって選択され、これは追加の目的を果たす。暗号ハンドシェイクを運ぶパケットは、 この接続IDとQUICバージョン固有のsaltから派生した鍵で保護される。これにより、 エンドポイントは、暗号ハンドシェイク完了後に使用するのと同じプロセスを、受信したパケットの 認証に使用できる。認証できないパケットは破棄される。このようにパケットを保護することで、 パケットの送信者がInitialパケットを見て理解したことについて強い保証を提供する。¶
これらの保護は、接続が確立される前にQUICパケットを受信できる攻撃者に 対して有効であることを意図していない。そのような攻撃者は、QUICエンドポイントに受け入れられる パケットを送信できる可能性がある。このQUICバージョンはこの種の攻撃を検出しようとするが、 回復するのではなく、エンドポイントが接続確立に失敗することを期待する。大部分については、 暗号ハンドシェイクプロトコル[QUIC-TLS]がハンドシェイク中の改ざん検出を担う。¶
エンドポイントは、ハンドシェイクへの干渉を検出し、回復を試みるために 他の方法を使用することを許可される。不正なパケットは他の方法で識別し破棄できるが、 本文書では特定の方法を義務付けない。¶
攻撃者は、サーバーからアドレス検証トークン (Section 8)を受信し、その後そのトークンを取得するために 使用したIPアドレスを解放できる可能性がある。後の時点で、攻撃者は同じアドレスを スプーフィングすることでサーバーとの0-RTT接続を開始でき、そのアドレスは現在は異なる (被害者)エンドポイントを指している可能性がある。したがって、攻撃者は、サーバーに初期輻輳 ウィンドウ分のデータを被害者へ送信させる可能性がある。¶
サーバーは、アドレス検証トークンの使用および寿命を制限することで、 この攻撃に対する緩和策を提供するべきである(SHOULD)。 Section 8.1.3を参照。¶
受信していないパケットを確認応答するエンドポイントは、輻輳制御器に、 ネットワークがサポートする範囲を超えるレートでの送信を許可させる可能性がある。 エンドポイントは、このふるまいを検出するため、パケット送信時にパケット番号をスキップしてもよい (MAY)。その後、エンドポイントはPROTOCOL_VIOLATION型の接続エラーで 接続を直ちに閉じることができる。Section 10.2を参照。¶
リクエスト偽造攻撃は、エンドポイントがピアに、エンドポイントによって 制御されるリクエストを被害者へ発行させる場合に発生する。リクエスト偽造攻撃は、 そうでなければ攻撃者が利用できない可能性のあるピアの能力へのアクセスを、攻撃者に 提供することを目的とする。ネットワークプロトコルでは、リクエスト偽造攻撃は、ネットワーク内の ピアの位置により、被害者がピアに暗黙的に付与する任意の認可を悪用するためにしばしば使用される。¶
リクエスト偽造が有効であるためには、攻撃者は、ピアがどのパケットを 送信するか、およびこれらのパケットがどこへ送信されるかに影響を与えられる必要がある。 攻撃者が制御されたペイロードで脆弱なサービスを標的にできる場合、そのサービスは、 攻撃者のピアに起因するが攻撃者によって決定された操作を実行する可能性がある。¶
たとえば、Web上のクロスサイトリクエストフォージェリ [CSRF]の悪用は、クライアントに認可Cookie [COOKIE]を含むリクエストを発行させ、 あるサイトが別のサイトに制限されるべき情報や操作にアクセスできるようにする。¶
QUICはUDP上で動作するため、懸念される主要な攻撃形態は、攻撃者が そのピアがUDPデータグラムを送信するアドレスを選択でき、それらのパケットの保護されていない 内容の一部を制御できる場合である。QUICエンドポイントによって送信されるデータの多くは 保護されるため、これには暗号文に対する制御も含まれる。攻撃者が、データグラム内の内容に 基づいて何らかの操作を実行するホストへ、ピアにUDPデータグラムを送信させることができる場合、 攻撃は成功する。¶
本節では、QUICがリクエスト偽造攻撃に使用される可能性のある方法を 議論する。¶
本節では、QUICエンドポイントによって実装できる限定的な対策も説明する。 これらの緩和策は、リクエスト偽造攻撃の潜在的標的が行動を起こさなくても、QUIC実装または 配備によって一方的に採用できる。ただし、UDPベースのサービスがリクエストを適切に認可しない場合、 これらの対策は不十分である可能性がある。¶
Section 21.5.4で説明される移行攻撃は非常に強力であり、 十分な対策を持たないため、QUICサーバー実装は、攻撃者が任意の宛先へ任意のUDPペイロードを 生成させることができると仮定するべきである。QUICサーバーは、ingress filtering [BCP38]を配備しておらず、かつ 安全性が不十分なUDPエンドポイントを持つネットワークに配備されるべきではない (SHOULD NOT)。¶
クライアントが脆弱なエンドポイントと同じ場所に配置されていないことを 一般に保証することはできないが、このQUICバージョンはサーバーの移行を許可しないため、 クライアントに対するスプーフィングされた移行攻撃を防ぐ。サーバー移行を許可する将来の任意の 拡張は、偽造攻撃に対する対策も定義しなければならない(MUST)。¶
QUICは、攻撃者がピアのUDPデータグラム送信先に影響を与えたり 制御したりする機会をいくつか提供する。¶
すべての場合において、攻撃者はピアに、QUICを理解しない可能性がある 被害者へデータグラムを送信させることができる。つまり、これらのパケットは アドレス検証の前にピアによって送信される。Section 8を参照。¶
パケットの暗号化された部分の外側では、QUICはエンドポイントに、 そのピアが送信するUDPデータグラムの内容を制御するためのいくつかのオプションを 提供する。Destination Connection IDフィールドは、ピアによって送信されるパケットの 早い位置に現れるバイトに対する直接的な制御を提供する。Section 5.1を参照。Initialパケット内のTokenフィールドは、Initialパケットの他の バイトに対する制御をサーバーに提供する。Section 17.2.2を 参照。¶
このQUICバージョンには、パケットの暗号化された部分に対する 間接的な制御を防ぐ手段はない。エンドポイントは、ピアが送信するフレーム、特に STREAMフレームのようなアプリケーションデータを伝えるフレームの内容を制御できると 仮定する必要がある。これはある程度アプリケーションプロトコルの詳細に依存するが、 多くのプロトコル利用文脈である程度の制御が可能である。攻撃者はパケット保護鍵に アクセスできるため、ピアが将来のパケットをどのように暗号化するかを予測できる可能性が高い。 その場合、データグラム内容の制御に成功するには、攻撃者が一定程度の信頼性をもって、 パケット番号とパケット内のフレーム配置を予測できることだけが必要となる。¶
本節では、データグラム内容に対する制御を制限することは実行可能ではないと 仮定する。後続の節における緩和策の焦点は、アドレス検証前に送信されるデータグラムが リクエスト偽造に使用され得る方法を制限することにある。¶
サーバーとして振る舞う攻撃者は、自身の可用性を通知するIPアドレスと ポートを選択できるため、クライアントからのInitialパケットはこの種の攻撃で利用可能であると 仮定される。ハンドシェイクに暗黙的に含まれるアドレス検証により、新しい接続について、 クライアントはQUICを理解しない、またはQUIC接続を受け入れる意思がない宛先へ、 他の型のパケットを送信しないことが保証される。¶
Initialパケット保護(Section 5.2 of [QUIC-TLS])は、 サーバーがクライアントによって送信されるInitialパケットの内容を制御することを困難にする。 クライアントが予測困難なDestination Connection IDを選択することで、サーバーは クライアントからのInitialパケットの暗号化された部分のいずれも制御できないことが保証される。¶
しかし、Tokenフィールドはサーバーによる制御に開かれており、 サーバーがクライアントを利用してリクエスト偽造攻撃を仕掛けることを可能にする。 NEW_TOKENフレーム(Section 8.1.3)で 提供されたトークンの使用は、接続確立中のリクエスト偽造に対する唯一の選択肢を提供する。¶
ただし、クライアントはNEW_TOKENフレームを使用する義務はない。 Tokenフィールドに依存するリクエスト偽造攻撃は、NEW_TOKENフレームを受信した時点から サーバーアドレスが変更されている場合に、クライアントが空のTokenフィールドを送信することで 回避できる。¶
クライアントは、サーバーアドレスが変更された場合にNEW_TOKENの使用を 避けることができる。しかし、Tokenフィールドを含めないことは性能に悪影響を及ぼす可能性がある。 サーバーは、データ送信量の3倍制限を超えるデータの送信を可能にするためにNEW_TOKENに依存する 可能性がある。Section 8.1を参照。 特に、これはクライアントが0-RTTを使用してサーバーからデータを要求する場合に影響する。¶
Retryパケット(Section 17.2.5)を送信することで、サーバーはTokenフィールドを 変更する選択肢を得る。Retryを送信した後、サーバーはクライアントからの後続のInitialパケットの Destination Connection IDフィールドも制御できる。これにより、Initialパケットの暗号化された 内容に対する間接的な制御も可能になる可能性がある。しかし、Retryパケットの交換は サーバーのアドレスを検証するため、後続のInitialパケットをリクエスト偽造に使用することを 防ぐ。¶
サーバーは優先アドレスを指定でき、クライアントはハンドシェイクを 確認した後にそこへ移行する。Section 9.6を参照。 クライアントが優先アドレスへ送信するパケットのDestination Connection IDフィールドは、 リクエスト偽造に使用される可能性がある。¶
クライアントは、そのアドレスを検証する前に、優先アドレスへ 非プロービングフレームを送信してはならない(MUST NOT)。 Section 8を参照。これは、サーバーが データグラムの暗号化された部分を制御するための選択肢を大幅に減らす。¶
本文書は、優先アドレスの使用に固有で、エンドポイントによって 実装できる追加の対策を提供しない。Section 21.5.6で 説明される汎用的な手段を、さらなる緩和策として使用できる。¶
クライアントは、見かけ上の接続移行の一部として スプーフィングされた送信元アドレスを提示し、サーバーにそのアドレスへデータグラムを 送信させることができる。¶
このスプーフィングされたアドレスへサーバーが後で送信する任意の パケット内のDestination Connection IDフィールドは、リクエスト偽造に使用される可能性がある。 クライアントは暗号文にも影響を与えられる可能性がある。¶
アドレス検証の前に、アドレスへプロービングパケット (Section 9.1)のみを送信するサーバーは、 攻撃者にデータグラムの暗号化された部分に対する限定的な制御しか提供しない。 しかし、特にNAT再バインディングでは、これは性能に悪影響を及ぼす可能性がある。 サーバーがアプリケーションデータを運ぶフレームを送信する場合、攻撃者はデータグラムの 内容の大部分を制御できる可能性がある。¶
本文書は、Section 21.5.6で説明される汎用的な手段を除き、 エンドポイントによって実装できる具体的な対策を提供しない。しかし、ネットワークレベルでの アドレススプーフィングへの対策、特にingress filtering [BCP38]は、スプーフィングを使用し 外部ネットワークから発生する攻撃に対して特に有効である。¶
パケット上でスプーフィングされた送信元アドレスを提示できる クライアントは、サーバーにそのアドレスへVersion Negotiationパケット (Section 17.2.1)を送信させることができる。¶
未知のバージョンのパケットに対する接続IDフィールドにサイズ制限が ないことは、結果として得られるデータグラムからクライアントが制御するデータ量を増加させる。 このパケットの最初のバイトはクライアントの制御下になく、次の4バイトはゼロであるが、 クライアントは5番目のバイトから最大512バイトを制御できる。¶
この攻撃に対する具体的な対策は提供されないが、汎用的な保護 (Section 21.5.6)が適用できる可能性がある。 この場合、ingress filtering [BCP38]も 有効である。¶
リクエスト偽造攻撃に対する最も効果的な防御は、脆弱なサービスを 強い認証を使用するよう変更することである。しかし、これはQUIC配備の制御範囲内に 常にあるものではない。本節では、QUICエンドポイントが一方的に実行できる他の手順を 概説する。これらの追加手順はすべて裁量的である。状況によっては、正当な使用を妨げたり 防止したりする可能性があるためである。¶
ループバックインターフェイス上で提供されるサービスは、しばしば 適切な認証を欠く。エンドポイントは、ループバックアドレスへの接続試行または移行を 防いでもよい(MAY)。同じサービスが以前に異なるインターフェイスで 利用可能であった場合、またはそのアドレスが非ループバックアドレス上のサービスによって 提供された場合、エンドポイントはループバックアドレスへの接続または移行を許可するべきではない (SHOULD NOT)。これらの機能に依存するエンドポイントは、 これらの保護を無効にするオプションを提供できる。¶
同様に、エンドポイントは、グローバル、ユニークローカル [RFC4193]、または非プライベート アドレスから、リンクローカルアドレス[RFC4291] またはプライベート利用範囲のアドレス[RFC1918]への アドレス変更を、リクエスト偽造の潜在的な試みと見なすことができる。 エンドポイントはこれらのアドレスの使用を完全に拒否できるが、それは正当な使用に 干渉する重大なリスクを伴う。エンドポイントは、与えられた範囲内の未検証アドレスへ データグラムを送信することが安全でないことを示すネットワークに関する具体的な知識を 持たない限り、アドレスの使用を拒否するべきではない(SHOULD NOT)。¶
エンドポイントは、NEW_TOKENフレームからの値をInitialパケットに 含めないこと、またはアドレス検証の完了前にパケット内でプロービングフレームのみを 送信することにより、リクエスト偽造のリスクを低減することを選択してもよい (MAY)。これは攻撃者がDestination Connection IDフィールドを 攻撃に使用することを防がないことに注意すること。¶
エンドポイントは、リクエスト偽造攻撃の脆弱な標的となり得る サーバーの場所に関する具体的な情報を持つことは期待されない。しかし、時間の経過とともに、 攻撃の一般的な標的となる特定のUDPポートや、攻撃に使用されるデータグラム内の特定の パターンを識別できる可能性がある。エンドポイントは、宛先アドレスを検証する前に、 これらのポートへデータグラムを送信しないこと、またはこれらのパターンに一致する データグラムを送信しないことを選択してもよい(MAY)。 エンドポイントは、問題があることが知られているパターンを含む接続IDを、使用せずに 廃止してもよい(MAY)。¶
一般にSlowlorisとして知られる攻撃[SLOWLORIS]は、標的エンドポイントへの多数の接続を 開いたままにし、可能な限り長く保持しようとする。これらの攻撃は、非活動のために閉じられることを 避けるために必要な最小限の活動を生成することで、QUICエンドポイントに対して実行できる。 これには、少量のデータを送信すること、送信者レートを制御するためにフロー制御ウィンドウを 徐々に開くこと、または高い損失率をシミュレートするACKフレームを生成することが含まれる可能性がある。¶
QUIC配備は、サーバーが許可するクライアントの最大数を増やすこと、 単一IPアドレスが作成を許可される接続数を制限すること、接続が持つことを許可される 最小転送速度に制限を課すこと、およびエンドポイントが接続されたままでいることを許可される 時間の長さを制限することなど、Slowloris攻撃に対する緩和策を提供するべきである (SHOULD)。¶
敵対的な送信者は、意図的にストリームデータの一部を送信せず、 受信者に未送信データのためのリソースを確保させる可能性がある。これにより、 不均衡な受信バッファメモリの確保、および/または受信者における大きく非効率なデータ構造の 作成が発生する可能性がある。¶
敵対的な受信者は、送信者に再送信のために未確認応答のストリームデータを 保存させようとして、ストリームデータを含むパケットを意図的に確認応答しない可能性がある。¶
受信者への攻撃は、フロー制御ウィンドウが利用可能なメモリに対応する場合に 緩和される。しかし、一部の受信者はメモリを過剰に確保し、実際に利用可能なメモリを超える フロー制御オフセットを集約的に通知する。過剰確保戦略は、エンドポイントが正常にふるまう場合には より良い性能につながる可能性があるが、エンドポイントをストリーム断片化攻撃に対して脆弱にする。¶
QUIC配備は、ストリーム断片化攻撃に対する緩和策を提供するべきである (SHOULD)。緩和策は、メモリの過剰確保を避けること、 追跡データ構造のサイズを制限すること、STREAMフレームの再構成を遅延させること、 再構成の欠落部分の経過時間と継続時間に基づくヒューリスティックを実装すること、 またはこれらの組み合わせで構成できる。¶
敵対的なエンドポイントは多数のストリームを開き、エンドポイント上の 状態を枯渇させることができる。敵対的なエンドポイントは、TCPにおけるSYN flooding攻撃と 類似した方法で、多数の接続上でこのプロセスを繰り返すことができる。¶
通常、クライアントはSection 2.1で説明されるように、ストリームを順番に開く。 しかし、複数のストリームが短い間隔で開始されると、損失または並べ替えにより、ストリームを 開くSTREAMフレームが順序外で受信されることがある。より大きい番号のストリームIDを受信すると、 受信者は同じ型の介在するすべてのストリームを開くことを要求される。 Section 3.2を参照。したがって、新しい接続上でストリーム4000000を 開くと、100万と1個のクライアント開始双方向ストリームが開かれる。¶
アクティブなストリーム数は、Section 4.6で 説明されるように、initial_max_streams_bidiおよびinitial_max_streams_uniトランスポート パラメーター、ならびに受信した任意のMAX_STREAMSフレームによって更新される値によって 制限される。慎重に選択されれば、これらの上限はストリームコミットメント攻撃の影響を 緩和する。しかし、上限を低く設定しすぎると、アプリケーションが多数のストリームを開くことを 期待する場合に性能に影響する可能性がある。¶
QUICとTLSはいずれも、いくつかの文脈では正当な用途を持つフレームや メッセージを含むが、これらのフレームやメッセージは、接続状態に観測可能な影響を及ぼさずに ピアに処理リソースを費やさせるために悪用される可能性がある。¶
メッセージは、フロー制御上限へ小さな増分を送信することなどにより、 小さく重要でない方法で状態を変更し、元に戻すためにも使用され得る。¶
処理コストが帯域幅消費または状態への影響と比較して不均衡に大きい場合、 悪意あるピアが処理能力を枯渇させることが可能になる可能性がある。¶
すべてのメッセージには正当な用途があるものの、実装は進行に対する 処理コストを追跡し、任意の非生産的なパケットの過剰な量を攻撃の兆候として扱うべきである (SHOULD)。エンドポイントは、この条件に対して接続エラーで 応答しても、パケットをドロップしてもよい(MAY)。¶
オンパス攻撃者は、送信者のレートに影響を与えるために、 IPヘッダー内のECNフィールドの値を操作できる。[RFC3168]は、 操作とその影響についてより詳細に議論している。¶
限定的なオンパス攻撃者は、変更されたECNフィールドを持つパケットを 複製して送信し、送信者のレートに影響を与えることができる。重複パケットが受信者によって 破棄される場合、この攻撃を成功させるには、攻撃者は重複パケットを元のパケットと競合させる 必要がある。したがって、QUICエンドポイントは、そのIPパケット内の少なくとも1つの QUICパケットが正常に処理されない限り、IPパケット内のECNフィールドを無視する。 Section 13.4を参照。¶
ステートレスリセットは、TCPリセット注入に類似したサービス拒否攻撃の 可能性を生み出す。この攻撃は、攻撃者が選択した接続IDを持つ接続について ステートレスリセットトークンを生成させることができる場合に可能である。このトークンを 生成させることができる攻撃者は、同じ接続IDを持つアクティブな接続をリセットできる。¶
静的鍵を共有する異なるインスタンスへパケットがルーティングされ得る場合、 たとえばIPアドレスまたはポートを変更することにより、攻撃者はサーバーにステートレスリセットを 送信させることができる。この形式のサービス拒否を防ぐため、ステートレスリセット用の静的鍵を 共有するエンドポイント(Section 10.3.2を参照)は、 その接続がもはやアクティブでない場合を除き、与えられた接続IDを持つパケットが常に接続状態を 持つインスタンスに到着するように配置されなければならない(MUST)。¶
より一般的には、サーバーは、同じ静的鍵を使用する任意のエンドポイント上で 対応する接続IDを持つ接続がアクティブである可能性がある場合、ステートレスリセットを 生成してはならない(MUST NOT)。¶
動的ロードバランシングを使用するクラスターの場合、アクティブな インスタンスが接続状態を保持している間にロードバランサー設定の変更が発生する可能性がある。 インスタンスが接続状態を保持していても、ルーティングの変更と結果として生じるステートレスリセットにより 接続は終了する。パケットが正しいインスタンスへルーティングされる可能性がない場合、 接続のタイムアウトを待つよりもステートレスリセットを送信する方がよい。しかし、これはルーティングが 攻撃者によって影響され得ない場合にのみ許容される。¶
本文書は、2つのエンドポイント間で使用されるQUICバージョンを ネゴシエートするために使用できるQUIC Version Negotiationパケット (Section 6)を定義する。しかし、本文書は このバージョンと後続の将来バージョンとの間で、このネゴシエーションがどのように実行されるかを 規定しない。特に、Version Negotiationパケットはバージョンダウングレード攻撃を防ぐための 機構を含まない。Version Negotiationパケットを使用する将来のQUICバージョンは、 バージョンダウングレード攻撃に対して堅牢な機構を定義しなければならない (MUST)。¶
配備は、攻撃者が新しい接続を特定のサーバーインスタンスに標的化する 能力を制限するべきである。理想的には、ルーティングの決定は、アドレスを含むクライアントが 選択した値から独立して行われる。インスタンスが選択されると、後続のパケットが同じ インスタンスへルーティングされるように接続IDを選択できる。¶
QUICパケットの長さは、それらのパケットの内容の長さに関する情報を 明らかにする可能性がある。PADDINGフレームは、エンドポイントがパケット内容の長さを ある程度不明瞭にできるよう提供される。Section 19.1を参照。¶
トラフィック解析を打ち破ることは困難であり、活発な研究対象である。 長さは情報が漏れる唯一の方法ではない。エンドポイントは、パケットのタイミングなど、 他のサイドチャネルを通じて機微な情報を明らかにする可能性もある。¶
本文書は、QUICにおけるコードポイント管理のために複数のレジストリを 確立する。これらのレジストリは、Section 22.1で 定義される共通のポリシー群に基づいて運用される。¶
すべてのQUICレジストリは、コードポイントの暫定登録と恒久登録の 両方を許可する。本節では、これらのレジストリに共通するポリシーを文書化する。¶
コードポイントの暫定登録は、QUICへの拡張について私的利用と 実験を可能にすることを意図している。暫定登録には、コードポイント値と連絡先情報を 含めることだけが要求される。ただし、暫定登録は回収され、別の目的のために再割り当て される可能性がある。¶
暫定登録には、Section 4.5 of [RFC8126]で定義されるExpert Reviewが必要である。 指定専門家は、残りのコードポイント空間の過度な割合を占める登録、または最初の 未割り当て値(Section 22.1.2を参照)の 登録のみを拒否できると助言される。¶
暫定登録には、登録が最後に更新された日時を示すDateフィールドが 含まれる。任意の暫定登録について日付の更新を要求することは、指定専門家によるレビューなしに 行うことができる。¶
すべてのQUICレジストリは、暫定登録をサポートするために次の フィールドを含む。¶
割り当てられたコードポイント。¶
"permanent"または"provisional"。¶
その値について公開利用可能な仕様への参照。¶
登録の最終更新日。¶
登録の定義に責任を持つ主体。¶
登録者の連絡先詳細。¶
登録に関する補足注記。¶
暫定登録は、SpecificationフィールドおよびNotesフィールドに加えて、 恒久登録に必要とされる可能性のある追加フィールドを省略してもよい (MAY)。Dateフィールドは、登録が作成または更新された日付に 設定されるため、登録要求の一部としては必要ない。¶
QUICレジストリからのコードポイントに対する新しい要求は、 既存の割り当てと、選択された空間内の最初の未割り当てコードポイントの両方を除外した、 ランダムに選択されたコードポイントを使用するべきである (SHOULD)。複数のコードポイントに対する要求は、 連続した範囲を使用してもよい(MAY)。これにより、 異なる実装によって同じコードポイントに異なる意味論が与えられるリスクを最小化する。¶
最初の未割り当てコードポイントの使用は、Standards Action ポリシーを用いた割り当てのために予約される。Section 4.9 of [RFC8126]を参照。 これらの値には、早期コードポイント割り当てプロセス [EARLY-ASSIGN]を 使用できる。¶
フレーム型など、可変長整数(Section 16)で 符号化されるコードポイントについては、その使用がより長い符号化を持つことに特に 敏感でない限り、4バイトまたは8バイトへ符号化されるコードポイント(すなわち 値214以上)を使用するべきである(SHOULD)。¶
QUICレジストリにコードポイントを登録する申請は、登録の一部として 要求されたコードポイントを含んでもよい(MAY)。コードポイントが 未割り当てであり、登録ポリシーの要件が満たされる場合、IANAは選択された コードポイントを割り当てなければならない(MUST)。¶
レジストリまたはレジストリの一部(可変長符号化を使用する コードポイントについての64-16383範囲など)の空間を回収するために、未使用の 暫定登録をレジストリから削除する要求が行われる可能性がある。これは、記録された日付が 最も古いコードポイントに対してのみ行われるべきであり(SHOULD)、 1年未満前に更新されたエントリは回収されるべきではない (SHOULD NOT)。¶
コードポイントを削除する要求は、指定専門家によってレビューされ なければならない(MUST)。専門家は、そのコードポイントが まだ使用中かどうかを判断しようとしなければならない(MUST)。 専門家は、そのコードポイントの使用が知られているかどうかを判断するため、登録に記載された 連絡先に加え、可能な限り広いプロトコル実装者の集合へ連絡するよう助言される。 専門家はまた、応答のために少なくとも4週間を許可するよう助言される。¶
この調査によってコードポイントの何らかの使用が特定された場合、 または登録を更新する要求が行われた場合、そのコードポイントは回収されてはならない (MUST NOT)。代わりに、登録の日付が更新される。得られた 関連情報を記録する注記が登録に追加される可能性がある。¶
コードポイントの使用が特定されず、登録更新の要求も行われなかった 場合、そのコードポイントはレジストリから削除されてもよい(MAY)。¶
このレビューおよび協議プロセスは、暫定登録を恒久登録へ変更する 要求にも適用される。ただし、その目的はコードポイントが使用されていないかどうかを 判断することではなく、登録が配備済みの任意の使用を正確に表していることを判断することである。¶
QUICレジストリにおける恒久登録は、別段の指定がない限り、 Specification Requiredポリシー (Section 4.6 of [RFC8126])を使用する。指定専門家は、仕様が存在し、 容易にアクセス可能であることを検証する。専門家は、登録が濫用的、軽率、または 積極的に有害である場合(単に美的に不快またはアーキテクチャ上疑わしいだけではない)を除き、 登録を承認する方向に偏ることが推奨される。レジストリの作成は、恒久登録に関する 追加の制約を指定してもよい(MAY)。¶
レジストリの作成は、登録が異なる登録ポリシーによって管理される コードポイント範囲を識別してもよい(MAY)。たとえば、 "QUIC Frame Types"レジストリ(Section 22.4)は、 0から63までの範囲内のコードポイントについてより厳格なポリシーを持つ。¶
恒久登録に対するより厳格な要件は、影響を受けるコードポイントに 対する暫定登録を妨げない。たとえば、フレーム型61に対する暫定登録を要求できる。¶
Standards Track出版物によって行われるすべての登録は、 恒久でなければならない(MUST)。¶
本文書におけるすべての登録には恒久ステータスが割り当てられ、 change controllerとしてIETF、contactとしてQUIC Working Group(quic@ietf.org)が 記載される。¶
IANAは、"QUIC"見出しの下に"QUIC Versions"のレジストリを追加した。¶
"QUIC Versions"レジストリは32ビット空間を管理する。 Section 15を参照。このレジストリは Section 22.1の登録ポリシーに従う。このレジストリにおける 恒久登録は、Specification Requiredポリシー (Section 4.6 of [RFC8126])を使用して割り当てられる。¶
プロトコルのコードポイント0x00000001は、本文書で定義される プロトコルに恒久ステータスで割り当てられる。コードポイント0x00000000は恒久的に 予約される。このコードポイントの注記は、このバージョンがバージョンネゴシエーションのために 予約されていることを示す。¶
パターン0x?a?a?a?aに従うすべてのコードポイントは予約され、 IANAによって割り当てられてはならず(MUST NOT)、 割り当て済み値の一覧に現れてはならない(MUST NOT)。¶
IANAは、"QUIC"見出しの下に"QUIC Transport Parameters"の レジストリを追加した。¶
"QUIC Transport Parameters"レジストリは62ビット空間を管理する。 このレジストリはSection 22.1の登録ポリシーに従う。 このレジストリにおける恒久登録は、Specification Requiredポリシー (Section 4.6 of [RFC8126])を使用して割り当てられるが、 16進数で0x00から0x3fまでの値(両端を含む)は例外であり、 [RFC8126]のSections 4.9および 4.10で 定義されるStandards ActionまたはIESG Approvalを使用して割り当てられる。¶
Section 22.1.1に列挙されたフィールドに加えて、このレジストリの 恒久登録は、次のフィールドを含まなければならない(MUST)。¶
パラメーターの短いニーモニック。¶
| 値 | パラメーター名 | 仕様 |
|---|---|---|
| 0x00 | original_destination_connection_id | Section 18.2 |
| 0x01 | max_idle_timeout | Section 18.2 |
| 0x02 | stateless_reset_token | Section 18.2 |
| 0x03 | max_udp_payload_size | Section 18.2 |
| 0x04 | initial_max_data | Section 18.2 |
| 0x05 | initial_max_stream_data_bidi_local | Section 18.2 |
| 0x06 | initial_max_stream_data_bidi_remote | Section 18.2 |
| 0x07 | initial_max_stream_data_uni | Section 18.2 |
| 0x08 | initial_max_streams_bidi | Section 18.2 |
| 0x09 | initial_max_streams_uni | Section 18.2 |
| 0x0a | ack_delay_exponent | Section 18.2 |
| 0x0b | max_ack_delay | Section 18.2 |
| 0x0c | disable_active_migration | Section 18.2 |
| 0x0d | preferred_address | Section 18.2 |
| 0x0e | active_connection_id_limit | Section 18.2 |
| 0x0f | initial_source_connection_id | Section 18.2 |
| 0x10 | retry_source_connection_id | Section 18.2 |
整数値Nについて31 * N + 27という形式の各値
(すなわち27、58、89、...)は予約される。これらの値はIANAによって割り当てられてはならず
(MUST NOT)、割り当て済み値の一覧に現れてはならない
(MUST NOT)。¶
IANAは、"QUIC"見出しの下に"QUIC Frame Types"のレジストリを追加した。¶
"QUIC Frame Types"レジストリは62ビット空間を管理する。 このレジストリはSection 22.1の登録ポリシーに従う。 このレジストリにおける恒久登録は、Specification Requiredポリシー (Section 4.6 of [RFC8126])を使用して割り当てられるが、 16進数で0x00から0x3fまでの値(両端を含む)は例外であり、 [RFC8126]のSections 4.9および 4.10で 定義されるStandards ActionまたはIESG Approvalを使用して割り当てられる。¶
Section 22.1.1に列挙されたフィールドに加えて、このレジストリの 恒久登録は、次のフィールドを含まなければならない(MUST)。¶
フレーム型の短いニーモニック。¶
Section 22.1の助言に加えて、新しい恒久登録の仕様は、エンドポイントが識別された型の フレームを送信できると判断する手段を説明するべきである(SHOULD)。 ほとんどの登録については、付随するトランスポートパラメーター登録が期待される。 Section 22.3を参照。恒久登録の仕様は、 フレーム内の任意のフィールドの形式および割り当てられた意味論も説明する必要がある。¶
このレジストリの初期内容はTable 3に表として示される。レジストリには、 Table 3の"Pkts"列および"Spec"列は含まれないことに 注意すること。¶
IANAは、"QUIC"見出しの下に"QUIC Transport Error Codes"の レジストリを追加した。¶
"QUIC Transport Error Codes"レジストリは62ビット空間を管理する。 この空間は、異なるポリシーによって管理される3つの範囲に分割される。このレジストリに おける恒久登録は、Specification Requiredポリシー (Section 4.6 of [RFC8126])を 使用して割り当てられるが、16進数で0x00から0x3fまでの値(両端を含む)は例外であり、 [RFC8126]のSections 4.9および4.10で定義されるStandards ActionまたはIESG Approvalを使用して 割り当てられる。¶
Section 22.1.1に列挙されたフィールドに加えて、このレジストリの 恒久登録は、次のフィールドを含まなければならない(MUST)。¶
| 値 | コード | 説明 | 仕様 |
|---|---|---|---|
| 0x00 | NO_ERROR | エラーなし | Section 20 |
| 0x01 | INTERNAL_ERROR | 実装エラー | Section 20 |
| 0x02 | CONNECTION_REFUSED | サーバーが接続を拒否 | Section 20 |
| 0x03 | FLOW_CONTROL_ERROR | フロー制御エラー | Section 20 |
| 0x04 | STREAM_LIMIT_ERROR | 開かれたストリームが多すぎる | Section 20 |
| 0x05 | STREAM_STATE_ERROR | 不正なストリーム状態でフレームを受信 | Section 20 |
| 0x06 | FINAL_SIZE_ERROR | 最終サイズの変更 | Section 20 |
| 0x07 | FRAME_ENCODING_ERROR | フレーム符号化エラー | Section 20 |
| 0x08 | TRANSPORT_PARAMETER_ERROR | トランスポートパラメーター内のエラー | Section 20 |
| 0x09 | CONNECTION_ID_LIMIT_ERROR | 受信した接続IDが多すぎる | Section 20 |
| 0x0a | PROTOCOL_VIOLATION | 汎用プロトコル違反 | Section 20 |
| 0x0b | INVALID_TOKEN | 不正なTokenを受信 | Section 20 |
| 0x0c | APPLICATION_ERROR | アプリケーションエラー | Section 20 |
| 0x0d | CRYPTO_BUFFER_EXCEEDED | CRYPTOデータバッファがあふれた | Section 20 |
| 0x0e | KEY_UPDATE_ERROR | 不正なパケット保護更新 | Section 20 |
| 0x0f | AEAD_LIMIT_REACHED | パケット保護鍵の過剰使用 | Section 20 |
| 0x10 | NO_VIABLE_PATH | 利用可能なネットワークパスが存在しない | Section 20 |
| 0x0100-0x01ff | CRYPTO_ERROR | TLSアラートコード | Section 20 |
本節の疑似コードは、サンプルアルゴリズムを説明する。これらの アルゴリズムは、最適な性能よりも、正確で明確であることを意図している。¶
本節の疑似コード片はCode Componentsとしてライセンスされる。 Copyright Noticeを参照。¶
Figure 45の疑似コードは、 可変長整数をバイト列のストリームから読み取る方法を示す。関数ReadVarintは単一の引数、 すなわちネットワークバイト順で読み取ることができるバイト列を取る。¶
ReadVarint(data):
// The length of variable-length integers is encoded in the
// first two bits of the first byte.
v = data.next_byte()
prefix = v >> 6
length = 1 << prefix
// Once the length is known, remove these bits and read any
// remaining bytes.
v = v & 0x3f
repeat length-1 times:
v = (v << 8) + data.next_byte()
return v
たとえば、8バイト列0xc2197c5eff14e88cは10進値 151,288,809,941,952,652へ復号される。4バイト列0x9d7f3e7dは494,878,333へ 復号される。2バイト列0x7bbdは15,293へ復号される。そして単一バイト0x25は37へ 復号される(2バイト列0x4025も同様である)。¶
Figure 46の疑似コードは、 実装がパケット番号符号化のために適切なサイズを選択する方法を示す。¶
EncodePacketNumber関数は2つの引数を取る。¶
EncodePacketNumber(full_pn, largest_acked):
// The number of bits must be at least one more
// than the base-2 logarithm of the number of contiguous
// unacknowledged packet numbers, including the new packet.
if largest_acked is None:
num_unacked = full_pn + 1
else:
num_unacked = full_pn - largest_acked
min_bits = log(num_unacked, 2) + 1
num_bytes = ceil(min_bits / 8)
// Encode the integer value and truncate to
// the num_bytes least significant bytes.
return encode(full_pn, num_bytes)
たとえば、エンドポイントがパケット0xabe8b3に対する確認応答を受信し、 番号0xac5c02のパケットを送信する場合、未処理のパケット番号は29,519個(0x734f)存在する。 この範囲の少なくとも2倍(59,038パケット、すなわち0xe69e)を表すためには、 16ビットが必要である。¶
同じ状態で、番号0xace8feのパケットを送信すると24ビット符号化が 使用される。これは、その範囲の2倍(131,222パケット、すなわち0x020096)を表すために、 少なくとも18ビットが必要であるためである。¶
Figure 47の疑似コードには、 ヘッダー保護が除去された後にパケット番号を復号するためのアルゴリズム例が含まれる。¶
DecodePacketNumber関数は3つの引数を取る。¶
DecodePacketNumber(largest_pn, truncated_pn, pn_nbits):
expected_pn = largest_pn + 1
pn_win = 1 << pn_nbits
pn_hwin = pn_win / 2
pn_mask = pn_win - 1
// The incoming packet number should be greater than
// expected_pn - pn_hwin and less than or equal to
// expected_pn + pn_hwin
//
// This means we cannot just strip the trailing bits from
// expected_pn and add the truncated_pn because that might
// yield a value outside the window.
//
// The following code calculates a candidate value and
// makes sure it's within the packet number window.
// Note the extra checks to prevent overflow and underflow.
candidate_pn = (expected_pn & ~pn_mask) | truncated_pn
if candidate_pn <= expected_pn - pn_hwin and
candidate_pn < (1 << 62) - pn_win:
return candidate_pn + pn_win
if candidate_pn > expected_pn + pn_hwin and
candidate_pn >= pn_win:
return candidate_pn - pn_win
return candidate_pn
たとえば、正常に認証された最も大きいパケットのパケット番号が 0xa82f30eaである場合、16ビット値0x9b32を含むパケットは0xa82f9b32として 復号される。¶
エンドポイントは、新しいネットワークパス上で送信を開始するたびに、 そのパスがECNをサポートするかどうかを判断する。Section 13.4を参照。 パスがECNをサポートする場合、目標はECNを使用することである。エンドポイントは、 ECNをサポートしないと判断されたパスを定期的に再評価することもある。¶
本節では、新しいパスをテストするための1つの方法を説明する。 このアルゴリズムは、パスがECN対応かどうかをテストする方法を示すことを意図している。 エンドポイントは異なる方法を実装できる。¶
パスには、"testing"、"unknown"、"failed"、または"capable"の いずれかであるECN状態が割り当てられる。"testing"または"capable"状態のパスでは、 エンドポイントはECTマーキングを持つパケットを送信する。デフォルトではECT(0)である。 それ以外の場合、エンドポイントはマーキングなしのパケットを送信する。¶
パスのテストを開始するため、ECN状態は"testing"に設定され、 既存のECNカウントがベースラインとして記憶される。¶
テスト期間は、エンドポイントによって決定されるパケット数または 限られた時間にわたって実行される。目標はテスト期間の長さを制限することではなく、 受信されたECNカウントが、パスがマーキングされたパケットをどのように扱うかについて 明確な指標を提供するのに十分な数のマーキング付きパケットが送信されることを保証することである。 Section 13.4.2は、これを10パケットまたはPTOの3倍に 制限することを提案している。¶
テスト期間が終了した後、そのパスのECN状態は"unknown"になる。 "unknown"状態から、ACKフレーム内のECNカウントの検証成功 (Section 13.4.2.1を参照)は、マーキングされたパケットが 確認応答されていない場合を除き、そのパスのECN状態を"capable"にする。¶
ECNカウントの検証が任意の時点で失敗した場合、影響を受けたパスの ECN状態は"failed"になる。エンドポイントは、マーキングされたパケットがすべて損失と 宣言された場合、またはそれらがすべてECN-CEマーキングされた場合にも、パスのECN状態を "failed"としてマークできる。¶
このアルゴリズムに従うことで、ECNを適切にサポートするパスでECNが 無効化されることはまれになる。マーキングを不正に変更する任意のパスは、ECNを無効化させる。 マーキング付きパケットがパスによって破棄されるまれな場合については、テスト期間が短いことで 発生する損失数が制限される。¶
このプロトコルの元の設計およびその根拠は、 Jim Roskindによる作業 [EARLY-DESIGN]から大きな影響を受けている。¶
IETF QUIC Working Groupは、多くの人々から非常に大きな支援を受けた。 次の人々は本文書に実質的な貢献を提供した。¶
Alessandro Ghedini¶
Alyssa Wilk¶
Antoine Delignat-Lavaud¶
Brian Trammell¶
Christian Huitema¶
Colin Perkins¶
David Schinazi¶
Dmitri Tikhonov¶
Eric Kinnear¶
Eric Rescorla¶
Gorry Fairhurst¶
Ian Swett¶
Igor Lubashev¶
奥 一穂 (Kazuho Oku)¶
Lars Eggert¶
Lucas Pardue¶
Magnus Westerlund¶
Marten Seemann¶
Martin Duke¶
Mike Bishop¶
Mikkel Fahnøe Jørgensen¶
Mirja Kühlewind¶
Nick Banks¶
Nick Harper¶
Patrick McManus¶
Roberto Peon¶
Ryan Hamilton¶
Subodh Iyengar¶
Tatsuhiro Tsujikawa¶
Ted Hardie¶
Tom Jones¶
Victor Vasiliev¶