QUICをゆっくり解説(18):QUICバージョン2

2022年07月20日 水曜日


【この記事を書いた人】
山本 和彦

Haskellコミュニティでは、ネットワーク関連を担当。 4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。

「QUICをゆっくり解説(18):QUICバージョン2」のイメージ

2021年5月にQUICバージョン1が策定されたというのに、もうバージョン2が議論されています。QUICバージョン1に問題があったわけではなく、バージョン2は以下の2つを目的としています。

  • 硬直化の回避
  • バージョン・ネゴシエーションの練習

バージョン・ネゴシエーションのためには複数のバージョンが必要なわけです。バージョン・ネゴシエーションについては、次回説明します。今回は、バージョン2がどのようにして、硬直化に対抗しようとしているのか解説します。

ロングヘッダパケットでの相違

もうお馴染みだと思いますが、再びロングヘッダパケットの構造を以下に示します。

 0                   1                   2                   3
 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+
|1|1|T T|X X X X|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                         Version (32)                          |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| DCID Len (8)  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|               Destination Connection ID (0..160)            ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| SCID Len (8)  |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|                 Source Connection ID (0..160)               ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+

「Version (32)」の箇所に格納されるQUICバージョン1を示す値は、0x00000001です。一方で、バージョン2を表す値は、0x00000002ではなく、0x709a50c4となる予定です。

1バイト目はフラグで、TTはパケットの型を表します。以下の表に、それぞれのバージョンの値の意味を示します。

TT バージョン1 バージョン2
00 Initial Retry
01 0-RTT Initial
10 Handshake 0-RTT
11 Retry Handshake

Wiresharkの開発版であるバージョン3.7ではQUICバージョン2に対応しています。対応していないWiresharkバージョン3.6でパケットダンプを表示すると、バージョン2のInitialパケットが0-RTTパケットとして表示されて、硬直化に対抗しているなぁという感じです。

暗号鍵の生成の相違

ハンドシェイク」では、イニシャル用の鍵が、クライアントが乱数的に生成したコネクションIDを元に作られると説明しました。QUICバージョン2では、生成過程のパラメータの値をバージョン1の値から変更しています。そのため、同じコネクションIDを入力しても、バージョン1とバージョン2では異なる鍵が生成されます。

硬直化への効果

QUICバージョン1のパケットの中身を覗いて動作する中間装置に対して、バージョン2はどれくらい効果があるでしょうか?

QUICバージョン1では、中継したパケットの内、そのパケットの情報のみから中身を覗けるのは、クライアントが生成する最初のInitialパケットだけです。ファイアーウォールなど、多くの中間装置はこのInitialパケットに対して何らかの動作をし、その他のパケットは素通りさせると思われます。

バージョン2のInitialパケットは、バージョン1の0-RTTパケットに擬態しています。ですので、バージョン2のInitialパケットを素通りさせる実装が多いのではないかと予想できます。ただ、こういった効果に対する調査はまだ実施されていないので、実際にどれくらい効果があるか断言はできません。

互換性の問題からクライアントはサーバに対して、最初はバージョン1で接続を試みるでしょう。そして、バージョン2が利用可能なら、バージョン2へアップグレードします。2回目以降のコネクションでは、サーバがバージョン2をサポートしていることが分かっているので、最初からバージョン2での接続を試みればよいわけです。

あるコネクションで得た情報が次のコネクションでどのように活かされるかは、「2回目以降のハンドシェイクと0-RTT」を読んで思い出してください。

次回

次回は、バージョン1からバージョン2へアップグレードするためのバージョン・ネゴシエーションについて説明します。

こちらの記事もおすすめ

QUICを実装した経験を持つ IIJ技術研究所の 山本 和彦 が、経験者目線でQUICを解説する連載記事です

すべての記事をみる

山本 和彦

2022年07月20日 水曜日

Haskellコミュニティでは、ネットワーク関連を担当。 4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。

Related
関連記事