Open9

QUIC輪読会

QUIC INVARIANTS

QUICにはRFCにあるもの以外にもいくつかの流儀があるが、それをINVARIANTSと表現している。

  • customized framing Frameの仕様について?あとで分かると思われる。
    QUICでは
  • TLS+TCPの2ラウンドでやってたのを1ラウンドで行える。
  • UDPデータグラム(1つ以上のQUICパケットを含む)を使うことで既存ネットワークに導入しやすくしている。
  • 双方向ストリームと片方向ストリームが使える。
  • コネクションマイグレーション、マルチパスが可能。
  • IPバージョン、IPアドレス、UDPポート番号を指定する。
  • 並列化のために、接続IDを使う。TCPはポート番号、アドレス、プロトコル番号で識別していたのでIDはなかった。
  • QUICはUDPより上のレイヤにある。
  • Ack-eliciting packetは受信側のACKを催促するっぽい

Reference

https://http3-explained.haxx.se/ja
https://tex2e.github.io/rfc-translater/html/rfc9000.html
https://www.rfc-editor.org/rfc/rfc9000.html#name-streams

QUICまでの背景

QUICはトランスポート層のプロトコルの1つで、

  • googleが使用していたgQUIC
  • QUICの上で動くHTTP/3.0

とは区別されRFC9000に規定されているQUICv2(iQUIC) のことを指す。

HTTP over QUIC(HTTP/3.0)により解決する課題

HoLブロッキング

HoLブロッキングをQUICが解消するまでを解説する。

HTTP/2.0以前ではHoLブロッキング、つまり1つのパケットが遅れた時、後続のパケットの送信がブロックしてしまう問題があった。対策として複数のTCPコネクションを確立して対策していたが帯域の効率がとても悪い。そこで

  • HTTP/2.0では一つのTCPコネクション複数のリクエストを並列に行うことを可能にした。これを通信の多重化、ストリームと呼んでいる。これにより、複数の通信を並行に行えるようになり、効率化された。

しかし、HoLブロッキングはHTTP/2でも解消されなかった。HTTP2はTCPを使っていたので、パケットロスすると再送制御をしてしまうのでブロックしてしまう。そこで

  • HTTP/3.0ではUDPを使って、再送制御が起きないようにした。ストリームやフロー制御はQUICで行うように変更することでHoLブロッキングを解消した。

複数のストリームハンドリング

HTTP/2.0と同様に複数のストリームで、通信を管理する。 QUICではHoLブロッキングの通り、複数のリクエストを1つのコネクションで処理できるようにした。QUICではTCPとは異なり、コネクションをIDで管理することで並列化している。

コネクションのマイグレーション

Wifiから無線に変わった時などにコネクションを維持したままにできるようになる。 TCPでは

  • 宛先ポート番号
  • 送信元ポート番号
  • プロトコル番号
  • 宛先IPアドレス
  • 送信元IPアドレス

でコネクションを管理していた。この5つの情報でコネクションを管理すると、

  • 5つの情報が変わることによるコネクションのやり直し

  • ネットワークを跨いだユーザートラッキング(Parking lot problem)
    という問題がある。

  • QUICではIDで管理しているので、IDの複数保持の工夫をすれば2つの問題を解消し、コネクションのマイグレーションが可能になる!

ストリーム管理方式の変更

HTTP2の双方向&片方向ストリームをQUICではストリームIDによってクライアントかサーバーかを判定する方式に変更した。 以下のような4パターンで表現する

片方向 双方向
クライアント 00 01
サーバ 10 11

クライアント、サーバーのどちらからでも通信を開始できる。

0-RTTと1-RTT

サーバーとクライアントの通信回数が減る。

  • HTTP/2.0ではTLSとTCP、それぞれのハンドシェイクで2ラウンドでやってたのを、TLSのハンドシェイクを飛ばして1ラウンドで行える1-RTT (TLS 1.3) を導入して解決した。
  • 更にコネクションがすでに確立されている場合に限って接続確立のハンドシェイクもしない0-RTTもサポートしている。

その他

  • 簡単な優先度制御(クライアントがサーバーにデータの処理方法の希望を伝えること。)。HTTP/2.0では複雑な木を送って制御していた。HTTP/3.0ではサーバーとクライントで簡単なパラメタでやりとりをする。
  • ヘッダ圧縮方式の変更をした。HTTP/2.0以前で使われていたヘッダ圧縮方式がHPACKだったが、これはパケットロスなどでHoLを誘発する欠点があった。なので辞書を一緒に送るQPACKを採用した、これにより符号化の選択幅が広がる。

TCPについて

詳しくはマスタリングTCP/IPを参考にする。TCPとは信頼性の高いストリームで片方向通信に向いている。ここの説明では送信側をS、受信側をRと表記する。

順序制御(sequence control)

パケットを受信する順序をRで並べ変えられるようにし、データが全て受け取れたことを確認する。TCPシーケンス番号と確認応答(ACK)を使って実現する。例えば、SがTCPシーケンス番号0番から1000番までのデータを送ったら、RはSに「次は1001だ」とACKし、Sが1001番から2000番までのデータを送ったら、「次は2001だ」とACKする。

再送制御(retransmission control)

パケットロスが起きた場合にパケットを再送する。TCPシーケンス番号と確認応答(ACK)を使って実現する。しかし、1セグメントごとの再送制御では効率が悪いのでスライディングウィンドウによって、ACKを待たずにパケットを送れるようにし効率を高めている。これをウィンドウ制御という。

流量制御(flow control)

Rの処理能力に合わせてSがデータ量を調節する。RがSに受け入れ可能なデータ量(ウィンドウサイズ)を通知することで制御を行う。

輻輳制御(congestion control)

輻輳、つまり通信路の混雑が発生しないように制御する。具体的にはスロースタートを使って行う。スロースタートというのはウィンドウ制御によって通信されるパケット量を最初は小さく設定し、少しずつ増加させていく方法のことである。

UDPではコネクションレスであり、以上の輻輳・再送・順序の制御は行わない。信頼性の低いが最低限の機能を提供しているので、通話などリアルタイム性が重要な場合に力を発揮する。

10/27 Stream メモ

ストリームはデータを送信するによって作成される。特徴は以下の通り

  • 単方向または両方向になりうるバイトストリームの抽象化である
  • 複数のストリームが同時に動作する
    ストリームはコネクションに複数存在する。各識別のためにはストリームIDという一意の値を利用する。ストリームIDの下位2ビットは以下の意味を持つ。ストリームIDの持つ意味をストリームタイプという。
  • コネクションIDの最下位ビットはコネクション開始者を表す。
  • コネクションIDの最下位から二番目のビットは単方向ストリームかどうかを表す。

ストリームにおける順序

データの送受信はストリームフレームにアプリケーションデータをカプセル化して行う。
順序制御は

  • オフセットフィールド(多分シーケンス番号みたいなもの)
  • ストリームID
    を用いて行う。

各エンドポイントは順序制御ができる必要があるので、バッファを保持する必要がある。バッファによって、順序が間違っていた場合も、順序をバッファで制御する。

ストリームフレームは再送発生時などにフレームの境界が保たれるかどうか分からない欠点がある。

ストリームにおける優先度

QUIC自体は優先度制御に関する情報交換のAPIを持たない。

  • アプリケーション層から提供されることを期待する。
  • QUICを実装する際のAPIには優先度制御に関する情報を与える方法を明確にする。アプリケーション層からの情報に基づき、 active streams?にリソースを割り当てる方法を決定する。
ログインするとコメントできます