Using QUIC Datagrams with HTTP/3
Using QUIC Datagrams with HTTP/3
2021-05-17 時点での DeepL Pro による翻訳。
QUICデータグラムとHTTP/3の併用
概要
QUIC DATAGRAMエクステンションは、QUIC上で動作するアプリケーションプロトコルに、QUICのセキュリティと輻輳制御の特性を利用しながら、信頼性の低いデータを送信するメカニズムを提供します。しかし、QUIC DATAGRAMフレームは、アプリケーションコンテキストをデマルチプレクスする手段を提供していません。本ドキュメントでは、QUIC上で動作するアプリケーションプロトコルがHTTP/3の場合のQUICデータグラムフレームの使用方法について説明します。このドキュメントは、データグラムをクライアント主導の双方向ストリームに関連付け、オプションで追加のデマルチプレクス層を定義しています。
1. はじめに
QUIC DATAGRAM extension [DGRAM]は、QUIC [QUIC]上で動作するアプリケーションプロトコルに、QUICのセキュリティと輻輳制御の特性を利用しながら、信頼性の低いデータを送信するメカニズムを提供します。しかし、QUIC DATAGRAMフレームは、アプリケーションのコンテキストをデマルチプレクスする手段を提供していません。本ドキュメントでは、QUIC上で動作するアプリケーションプロトコルがHTTP/3[H3]の場合のQUICデータグラムフレームの使用方法について説明します。このドキュメントは、データグラムをクライアント主導の双方向ストリームに関連付け、オプションで追加のデマルチプレクス層を定義しています。
2. 多重化
1つのQUICコネクションで複数のデータグラムのやり取りを可能にするために、HTTPデータグラムには2つの多重化が施されています。まず、QUICデータグラムフレームのペイロードは、データグラムを特定のQUICストリームに関連付ける符号化されたストリーム識別子で始まります。第二に、データグラムにはコンテキスト識別子(セクション2.1参照)が含まれており、これにより、あるHTTPリクエストに関連する複数のデータグラム・コンテキストを多重化することができる。概念的には、第1層の多重化はホップ単位であり、第2層はエンド・ツー・エンドである。
2.1. データグラムコンテクスト
与えられたHTTPリクエストの範囲内で、コンテクストは追加の多重化レイヤーを提供します。コンテクストはデータグラムのエンコーディングを決定し、暗黙のうちにメタデータを伝えるために使用することができます。例えば、コンテキストはデータグラムの一部を省略するための圧縮に使用することができます。コンテキスト識別子は圧縮コンテキストにマップされ、受信者は省略されたデータを再構築するために使用することができます。
コンテキストは、あるリクエストの範囲内で、コンテキストIDと呼ばれる数値によって識別されます。コンテキストIDは、62ビットの整数(0~2^62-1)です。
ストリームIDがホップごとの概念であるのに対し、コンテキストIDはエンド・ツー・エンドの概念です。言い換えれば、データグラムがクライアントからサーバーまでの間に1つ以上の仲介者を経由する場合、ストリームIDはホップごとに変更される可能性が高いが、コンテキストIDは同じままである。コンテキストIDは、仲介者にとっては不透明です。
2.2. コンテキストIDの割り当て
DATAGRAM 拡張をサポートする HTTP/3 の実装は、コンテキスト ID 割り当てサービスを提供しなければなりません (MUST)。そのサービスは、HTTP/3と一緒に配置されたアプリケーションが、彼ら自身の目的のためにその後使用することができるユニークなコンテキストIDを要求することを可能にします。HTTP/3 の実装は、受信する DATAGRAM フレームのコンテキスト ID を解析し、それを使用してフレームを適切なアプリケーション・コンテキストに配信します。
偶数番号のコンテキストIDはクライアント主導型で、奇数番号のコンテキストIDはサーバー主導型です。これは、コンテキストID割り当てサービスのHTTP/3クライアントの実装は偶数番号のIDのみを提供しなければならず(MUST)、一方、サーバーの実装は奇数番号のIDのみを提供しなければならない(MUST)ことを意味します。いったん割り当てられると、どのコンテキスト ID もクライアントとサーバの両方で使用できることに注意してください。さらに、コンテキストIDの名前空間は、特定のHTTPリクエストに関連付けられていることに注意してください。つまり、同じ数字のコンテキストIDが異なるリクエストで同時に使用される可能性があります。
3. HTTP/3 データグラムフレームのフォーマット
HTTP/3で使用する場合、QUIC DATAGRAMフレームのDatagram Dataフィールドは以下のフォーマットを使用します([QUIC]の「Notational Conventions」セクションの表記を使用)。
HTTP/3 Datagram {
Quarter Stream ID (i),
Context ID (i),
HTTP/3 Datagram Payload (..),
}
図1:HTTP/3 データグラム・フレーム・フォーマット
クォーター・ストリームID:
このデータグラムが関連付けられているクライアント主導の双方向ストリームの値を4で割った可変長整数です。(4で割るのは、HTTPリクエストはクライアント主導の双方向ストリームで送信され、それらは4で割り切れるストリームIDを持っていることに由来します)
コンテキストID:
データグラムのコンテキストIDを示す可変長整数(2.1項参照)。
HTTP/3 データグラムのペイロード:
データグラムのペイロードで、そのセマンティクスは個々のアプリケーションによって定義されます。なお、このフィールドは空でもよい。
仲介者は、QUIC DATAGRAMフレームをストリームと関連付けるために、Quarter Stream IDフィールドを解析します。ペイロードが短すぎてQuarter Stream IDフィールドの解析ができないQUIC DATAGRAMフレームを仲介業者が受信した場合、仲介業者はH3_GENERAL_PROTOCOL_ERROR型のHTTP/3接続エラーとして扱わなければなりません(MUST)。仲介者は、Quarter Stream ID以降のHTTP/3 Datagramフィールドをすべて無視しなければなりません(MUST)。
エンドポイントは、QUICデータグラムフレームをストリームとそのストリーム内のコンテキストに関連付けるために、Quarter Stream IDフィールドとContext IDフィールドの両方を解析します。エンドポイントが、ペイロードが短すぎてQuarter Stream IDフィールドの解析ができないQUIC DATAGRAMフレームを受信した場合、エンドポイントは、H3_GENERAL_PROTOCOL_ERRORタイプのHTTP/3コネクションエラーとして扱わなければなりません(MUST)。エンドポイントがQUIC DATAGRAMフレームを受信し、そのペイロードがQuarter Stream IDフィールドの解析を可能にするのに十分な長さであるが、Context IDフィールドの解析を可能にするには短すぎる場合、エンドポイントはH3_GENERAL_PROTOCOL_ERRORタイプのストリームエラーで対応するストリームを突然終了しなければなりません(MUST)。
DATAGRAM フレームを受信し、その Quarter Stream ID が既に閉じられたストリームにマップされている場合、受信者はそのフレームを静かにドロップしなければなりません (MUST)。DATAGRAM フレームを受信し、その Quarter Stream ID がまだ生成されていないストリームに対応している場合、受信者はそのフレームを静かにドロップするか、対応するストリームの生成を待つ間に一時的にバッファリングする必要があります。
4. CAPSULE HTTP/3 フレームの定義
CAPSULE は,HTTP 仲介者が存在する場合でも,リクエストに関連する情報をエンドツーエンドで確実に送信できます。
CAPSULE は HTTP/3 フレーム (QUIC フレームとは異なります) で、クライアント主導の双方向ストリームでのみ送信されなければなりません。仲介者は、受信したすべての CAPSULE フレームを、DATA フレームを転送するのと同じストリーム上に、変更されていない全体で転送しなければなりません (MUST)。仲介者は、転送しているフレーム以外のCAPSULEフレームを送信してはなりません(MUST NOT)。
CAPSULE の本仕様では、現在 HTTP/3 フレームタイプ 0xffcab5 を使用しています。本文書が承認された場合、より低い番号をIANAに要求する予定です。
CAPSULE HTTP/3 Frame {
Type (i) = 0xffcab5,
Length (i),
Capsule Type (i),
Capsule Data (..),
}
図2:CAPSULE HTTP/3フレームフォーマット
TypeとLengthのフィールドは、[H3]のHTTP/3フレームの定義に従っています。ペイロードは以下のように構成されています。
カプセル・タイプ:
このカプセルのタイプ。
カプセル・データ:
セマンティクスが「カプセルタイプ」に依存するデータ。
カプセルタイプが不明なカプセルを受信したエンドポイントは、そのカプセルを静かにドロップしなければなりません(MUST)。仲介者は、カプセルタイプがわからなかったり、カプセルデータを解析できなかったりしても、カプセルを転送しなければなりません(MUST)。
4.1. REGISTER_DATAGRAM_CONTEXTカプセル
REGISTER_DATAGRAM_CONTEXTカプセル(type=0x00)は、エンドポイントが、与えられたコンテキストIDに関連するデータグラムのエンコーディングとセマンティクスを相手に知らせるためのものです。そのカプセル・データ・フィールドは次のように構成されています。
REGISTER_DATAGRAM_CONTEXT Capsule {
Context ID (i),
Extension String (..),
}
図3:REGISTER_DATAGRAM_CONTEXTカプセルフォーマット
コンテキストID:
登録するコンテキストIDです。
拡張文字列。
拡張性を持たせるための,コンマで区切られたキーと値のペアの文字列。キーはIANAに登録されています(8.4項参照)。
Extension StringフィールドのABNFは以下のとおりです([RFC7230]の3.2.6項の構文を使用)。
extension-string = [ ext-member *( "," ext-member ) ]
ext-member = ext-member-key "=" ext-member-value
ext-member-key = token
ext-member-value = token
フレームの送信者は、このコンテキストIDを使って送受信するデータグラムに適用するセマンティクスを一方的に定義することになります。一度登録されたコンテキストIDは、両方向で使用することができます。
エンドポイントは、同じコンテキスト ID を持つ REGISTER_DATAGRAM_CONTEXT カプセルを送受信するまで、そのコンテキスト ID を使用した DATAGRAM フレームを送信してはなりません (MUST NOT)。エンドポイントは、同じ Context ID を持つ REGISTER_DATAGRAM_CONTEXT カプセルを送受信するまで、Context ID を使用して DATAGRAM フレームを送信してはなりません (MUST NOT)。しかし、順序変更のため、未知の Context ID を持つ DATAGRAM フレームを受信したエンドポイントは、それをエラーとして扱ってはなりません (MUST NOT)。
エンドポイントは、同じストリーム上で同じContext IDを2回登録してはいけません(MUST NOT)。これは、CLOSE_DATAGRAM_CONTEXTカプセルを使って閉じられたContext IDにも適用されます。クライアントは、サーバーが起動したContext IDを登録してはならず(MUST NOT)、サーバーは、クライアントが起動したContext IDを登録してはならない(MUST NOT)。エンドポイントがこれらの要件の1つ以上に違反するREGISTER_DATAGRAM_CONTEXTカプセルを受信した場合、エンドポイントは対応するストリームをH3_GENERAL_PROTOCOL_ERROR型のストリームエラーで突然終了させなければなりません(MUST)。
4.2. CLOSE_DATAGRAM_CONTEXTカプセル
CLOSE_DATAGRAM_CONTEXTカプセル(type=0x01)は、エンドポイントがピアに対して、指定されたコンテキストIDに関連するデータグラムの送信や受信したデータグラムの解析を終了することを通知するためのカプセルです。そのカプセル・データ・フィールドは以下で構成されます。
CLOSE_DATAGRAM_CONTEXT Capsule {
Context ID (i),
Extension String (..),
}
図4:CLOSE_DATAGRAM_CONTEXT カプセルフォーマット
コンテキストID:
クローズするコンテキストIDです。
拡張文字列:
拡張性を持たせるためのカンマ区切りのキーと値のペアの文字列で、詳細は4.1節の同フィールドの定義を参照のこと。
このクローズは、一方的かつ双方向であることに注意してください:フレームの送信者は、一方的に相手にクローズを通知します。エンドポイントは CLOSE_DATAGRAM_CONTEXT カプセルを使用して、自分自身または相手によって最初に登録されたコンテキストを閉じることができます。エンドポイントは、REGISTER_DATAGRAM_CONTEXTカプセルを使って登録されたばかりのコンテキストを、その拡張文字列が受け入れられないと判断した場合、直ちに拒否するために、CLOSE_DATAGRAM_CONTEXTカプセルを使用してもよい(MAY)。
エンドポイントが CLOSE_DATAGRAM_CONTEXT フレームを送信または受信した後、そのコンテキスト ID を持つ DATAGRAM フレームを送信してはいけません (MUST NOT)。しかし、並び替えのために、閉じたContext IDを持つDATAGRAMフレームを受信したエンドポイントは、それをエラーとして扱ってはならず、代わりにそのDATAGRAMフレームを静かにドロップしなければなりません。
エンドポイントは、以前に登録されていないContext IDを閉じてはいけません(MUST NOT)。エンドポイントは、すでにクローズされたContext IDをクローズしてはなりません(MUST NOT)。エンドポイントがこれらの要件の1つ以上に違反するCLOSE_DATAGRAM_CONTEXTカプセルを受け取った場合、エンドポイントはH3_GENERAL_PROTOCOL_ERRORタイプのストリームエラーで対応するストリームを突然終了しなければなりません(MUST)。
4.3. データグラム・カプセル
DATAGRAM カプセル(type=0x02)は、エンドポイントが HTTP ストリーム上でデータグラム・フレームを送信することを可能にします。これは、QUIC DATAGRAMフレームをサポートしていないHTTPバージョンを使用している場合に特に有効です。そのカプセル・データ・フィールドは以下で構成されます。
DATAGRAM Capsule {
Context ID (i),
HTTP/3 Datagram Payload (..),
}
図5:DATAGRAMカプセルのフォーマット
コンテキストID:
データグラムのコンテキストIDを示す可変長整数(セクション2.1参照)。
HTTP/3 データグラムのペイロード:
データグラムのペイロードで、その意味は個々のアプリケーションによって定義される。このフィールドは空でもよいことに注意してください。
DATAGRAM Capsuleを使用して送信されたデータグラムは、QUIC DATAGRAMフレームで送信されたデータグラムと全く同じセマンティクスを持ちます。
5. H3_DATAGRAM HTTP/3 SETTINGSパラメータ
このメカニズムをサポートするHTTP/3の実装は、1の値を持つH3_DATAGRAM SETTINGSパラメータを送信することで、相手にそれを示すことができます。 H3_DATAGRAM SETTINGSパラメータの値は、0または1のいずれかでなければなりません(MUST)。0の値は、このメカニズムがサポートされていないことを示します。値が0でも1でもないH3_DATAGRAM SETTINGSパラメータを受信したエンドポイントは、エラーH3_SETTINGS_ERRORで接続を終了しなければなりません。
値が1のH3_DATAGRAM SETTINGSパラメータを送信するエンドポイントは、max_datagram_frame_size QUICトランスポートパラメータ[DGRAM]を送信しなければなりません。値が1のH3_DATAGRAM SETTINGSパラメータを、max_datagram_frame_size QUICトランスポートパラメータも受信していないQUICコネクション上で受信したエンドポイントは、エラーH3_SETTINGS_ERRORでコネクションを終了しなければなりません(MUST)。
クライアントが0-RTTを使用する場合、クライアントはサーバーのH3_DATAGRAM SETTINGSパラメータの値を保存してもよい(MAY)。これにより、クライアントは 0-RTT パケットで HTTP/3 データグラムを使用することができます。サーバーが0-RTTデータの受け入れを決定した場合、サーバーは、クライアントにNewSessionTicketメッセージを送った接続でクライアントに送った値以上のH3_DATAGRAM SETTINGSパラメータを送らなければなりません(MUST)。クライアントが0-RTT状態でH3_DATAGRAM SETTINGSパラメータの値を保存している場合、ハンドシェイクでサーバーから送信されたH3_DATAGRAM SETTINGSパラメータの新しい値が保存されている値以上であることを検証しなければならず(MUST)、そうでない場合、クライアントはエラーH3_SETTINGS_ERRORで接続を終了しなければなりません(MUST)。いずれの場合も,H3_DATAGRAM SETTINGSパラメータの最大許容値は1です。
6. HTTP/1.xとHTTP/2のサポート
HTTP/2 の CAPSULE フレームを定義することで、HTTP/2 におけるデータグラムのサポートを提供することができます。
HTTP/1.x では、データストリームのフォーマットを長さと値のカプセルのシーケンスに定義することで、データグラムをサポートすることができます。
TODO このドキュメントを、HTTP/1.x、HTTP/2、HTTP/3 の定義を含む "HTTP Datagrams" にリファクタリングします。
7. セキュリティに関する考察
この機能は、HTTP/3 の設定パラメータを送信する必要があるため、「目立ちます」。言い換えれば、プローブするクライアントは、サーバーがこの機能をサポートしているかどうかを知ることができます。この機能をサポートする実装は、このエンドポイントで有効なHTTP/3データグラムを使用するアプリケーションがあるという事実を漏らさないように、常にこの設定パラメータを送信すべきです。
8. IANAに関する検討事項
8.1. HTTP/3 CAPSULE フレーム
本文書では、IANA に対し、「HTTP/3 Frames」レジストリに以下のエントリを登録するよう要求します。
+------------+----------+---------------+
| Frame Type | Value | Specification |
+============+==========+===============+
| CAPSULE | 0xffcab5 | This Document |
+------------+----------+---------------+
8.2. HTTP SETTINGSパラメータ
本文書では、IANAに対し、「HTTP/3 Settings」レジストリに以下のエントリを登録するよう要求します。
+--------------+----------+---------------+---------+
| Setting Name | Value | Specification | Default |
+==============+==========+===============+=========+
| H3_DATAGRAM | 0xffd276 | This Document | 0 |
+--------------+----------+---------------+---------+
8.3. カプセルタイプ
本文書は,HTTP/3 フレームタイプコードのレジストリを確立する。HTTP カプセルタイプ」レジストリは 62 ビットの空間を管理する。このレジストリへの登録は、以下のフィールドを含まなければならない(MUST)。
タイプ。
カプセルタイプの名前またはラベル。
値。
カプセルタイプフィールド(セクション4参照)の値は、62ビットの整数です。
リファレンス。
タイプの仕様に対するオプションの参照。このフィールドは空でもよい。
登録は "First Come First Served "ポリシー([IANA-POLICY]のセクション4.4参照)に従っており、2つの登録が同じTypeを持ってはならない(MUST NOT)。
このレジストリには、当初、以下のエントリが含まれています。
+---------------------------+-------+---------------+
| Capsule Type | Value | Specification |
+---------------------------+-------+---------------+
| REGISTER_DATAGRAM_CONTEXT | 0x00 | This Document |
+---------------------------+-------+---------------+
| CLOSE_DATAGRAM_CONTEXT | 0x01 | This Document |
+---------------------------+-------+---------------+
| DATAGRAM | 0x02 | This Document |
+---------------------------+-------+---------------+
8.4. コンテキスト拡張キー
REGISTER_DATAGRAM_CONTEXTカプセルは、セクション4.1を参照して、キーと値のペアを運ぶ。本文書は、IANAに「HTTP Datagram Context Extension Keys」レジストリの作成を要求する。このレジストリへの登録は、以下のフィールドを含まなければならない(MUST)。
キー。
Key: キー(セクション4.1参照)。キーは[RFC7230]のセクション3.2.6で定義された有効なトークンでなければならない(MUST)。
Description: キーのセマンティクスの簡単な説明。
キーのセマンティクスを簡単に説明したもので、仕様書の参照がある場合は要約してもよい(MAY)。
リファレンス
パラメーターの仕様に対するオプションの参照です。このフィールドは空でもよい。
登録は "First Come First Served "ポリシー([IANA-POLICY]のセクション4.4参照)に従い、2つの登録が同じKeyを持ってはならない(MUST NOT)。このレジストリは初期状態では空です。