新しい仕様の翻訳を公開しました(2018/10/31)
QUICの仕様を翻訳していく
http://d.hatena.ne.jp/ASnoKaze/20160725/1469374715
QUICの仕様(ドラフト)
5月頃に、Googleのブログでも「Google の試験的トランスポート、QUIC のアップデート」という記事で紹介されたように、QUICというUDPを用いたプロトコルが注目を集めています。
幾つかのドキュメントは存在していたものの、仕様としては未公開でした。
しかし、6/17に2つのInternet-Draftが公開されました
- 「QUIC: A UDP-Based Secure and Reliable Transport for HTTP/2」
- 「QUIC Loss Recovery And Congestion Control」
7月に行われるIETFミーティングでも議論が行われるようで非常に楽しみです
今回は、簡単に概要の部分について軽く読んでみる(仕様の4章)
(TCPやMPTCPとの対比して利点を述べる部分が多く、TCPの理解が足らず大分辛い。また、英語の解釈ミスも多分に含まれてるかと思います。)
QUIC Overview
QUICは機能的にはTCP+TLS+HTTP/2と同じであるが、QUICはUDPの上に実装される。QUICのTCP+TLS+HTTP/2より優れてる点は以下のとおりです
- コネクション確立のレイテンシ
- 柔軟な輻輳制御
- ヘッドオブラインブロッキングの無い多重化
- ヘッダとペイロードの認証及び暗号化
- ストリーム及びコネクションのフロー制御
- 前方誤り訂正
- 接続のマイグレーション
コネクション確立のレイテンシ
コネクション確立に関する詳細については「QUIC Crypto design」をお読み下さい。
簡潔に述べると、TCP+TLSでは1〜3回のラウンドトリップが必要ですが、QUICのハンドシェイクはペイロードを送信する前のラウンドトリップはしばしば0回です。
QUICクライアントがサーバに初めて接続する際、クライアントはハンドシェイクを完了するのに必要な情報を得るために1ラウンドトリップが必要になります。
クライアントが初期(空の)のclient hello (CHLO)を送信すると、サーバは後の処理に必要な情報をrejection (REJ)で送信します。この情報はsource address tokenと、サーバの証明書です。source address tokenは後続のCHLOにおいてクライアントのIPを検証するのに使用されます。
柔軟な輻輳制御
QUICはプラガブルな輻輳制御を持ち、TCPよりもリッチなシグナリングは、TCPの輻輳制御アルゴリズムよりも多くの情報を提供できます。現在GoogleのQUIC実装は、TCP Cubicの再実装を使用しています。私たち(Google)は、別のアプローチの実験も行っています。
より多くの情報の一例としては、オリジナルパケットと再送パケットの各パケットににおいて新しいシーケン番号を転送することです。これにより、QUICの送信者はオリジナルパケットへのAckと再送パケットへのAckとを区別でき、TCPの再送における曖昧さを回避できます。
QUICのACKは、パケットの受信と応答が送信されるまでの間の遅延を明示的に転送することもできます。これによりラウンドトリップタイム(RTT)を正確に計算できます。
さらに、QUICのACKフレームは256までのNACK(Negative ACKnowledgement) rangeをサポートし、これによりTCPよりもパケット並び替えに強くなります(TCPは3つまでのSACK range)。
ストリームとコネクションのフロー制御
QUICはストリームレベル、コネクションレベルのフロー制御を実現しています。
QUICのストリームレベルフロー制御は以下のように動作します。
QUICの受信者は各ストリームで受信したいデータ量までのバイトオフセットを告知します。あるストリーム上でデータが送られ、受信されると、受信者はそのストリーム上での上限増加分のオフセットをWINDOW_UPDATEフレームで送信します。これにより、相手はそのストリーム上でさらなるデータを送信できるようになります。
ストリーム毎のフロー制御に加えて、QUICは、受信者が接続に対して予約したバッファ領域への制限のためにコネクションレベルのフロー制御も実現します。コネクションフロー制御はストリームフロー制御と同じように動作するが、ストリーム全てを合わせてオフセットまでのデータ転送になります。
多重化
TCP上のTHTP/2は、TCPのヘッドオブラインブロッキングの影響を受けます。HTTP/2は多くのストリームをTCPの単一バイトストリーム上に構成するため、TCPセグメントの損失は再送が届くまで多くの後続の処理に影響を与えます。
QUICは多重処理のためにゼロから設計されているため、損失したパケットは、そのパケットが転送していたストリームにしか影響しません。それぞれのストリームにおいてフレームが届いた順に処理ができ、損失のないストリームはそのまま処理を進められます。
ヘッダとペイロードの(完全性の)認証及び暗号化
TCPヘッダは通信経路上プレインテキストで表現され、(完全性の)認証もされません。そのため、受信ウィンドウ操作やシーケンスナンバーの上書きといったインジェクションやヘッダ操作といった多くの問題を引き起こします。これらのうち一部は攻撃ですが、ミドルボックスによりTCPの性能を改善するために透過的に使用されるメカニズムでもあります。
しかし、MPTCPの設計とそれに続くデプロイ性を見るに、"パフォーマンス改善"においてもミドルボックスはトランスポートの発展可能性を制限しています。(通信を詐害したりしうる)
QUICパケットは常に暗号化されます。パケットヘッダの一部は暗号化されませんが、第三者によって任意のパケットのインジェクションや操作が出来ないようにパケットは認証されます。QUICはミドルボックスによる故意・無意識の通信操作からコネクションを保護します。
前方誤り訂正
再送を待たずして損失したパケットを回復するために、QUICは現在XOR-based FEC schemeを使用します。FECパケットはそのFECグループのパケットのパリティを含んでいます。もしグループの中の一つのパケットを損失した場合、そのパケットのデータはFECパケットとそのグループの残りのパケットからリカバリすることが出来ます。
送信者は状況に合わせてFECパケットを送信するかを決定できます。
接続のマイグレーション
TCPコネクションは送信元アドレス・送信元ポート・送信先アドレス・送信先ポートの4つの値で識別されます。TCPのよく知られている問題として、IPアドレスやポート番号が変更されるとコネクションが切断される事です。(例えば、WiFIからCellularに変えたり、クライアントの使用しているNATのポート紐付けが期限切れしたりした場合)。
MPTCPは問題を解決するためにTCPコネクションのマイグレーションを行うが、依然としてミドルボックスのサポートがないことや、OSの普及が問題になっている。
QUICコネクションは、クライアントによってランダムに生成される64bitのコネクションIDで識別されます。QUICコネクションはIPアドレスの変更やNATによるポート再割当てが発生しても生き続けます。コネクションIDはこれらの変更があっても変わらないためです。
マイグレーションしたクライアントは、同じセッション鍵をでパケットの暗号化と復号を行うため、マイグレーションしたクライアントは暗号的に正しいことが確認されます。