HTTP/3のパケットを読む
はじめに
はじめまして。 2022年4月にSHIFTに新卒入社し、7月よりITインフラソリューション部配属となった三好と申します。
2022年6月にRFC 9114が発表され、その中で 「HTTP/3」 が正式に標準化されました。初耳の方もいらっしゃるかと存じますが、実はGoogle Chrome等の一部のブラウザで既に実用が始まっております。そんな知らずのうちに使っているHTTP/3について、その通信パケットをキャプチャし、従来のバージョン(HTTP/2)と比較する形でご紹介します。
HTTP/3のパケットをキャプチャする前に
HTTP/3はTCP/IPプロトコル4階層におけるアプリケーション層のプロトコルです。したがって、その下にはトランスポート層やネットワーク層といったのプロトコルが存在します。その中から、HTTP/3の要件に含まれ、HTTP/3の機能を理解するうえで必須のプロトコルを2つご紹介します。
QUIC
Google社によって開発された新しいトランスポート層プロトコル、それが 「QUIC」 です。トランスポート層とは言いましたが、実際はHTTPの領域の一部や、TLS1.3(後述)を要件として内部に含みます。
通信におけるトランスポート層プロトコルといえば、 TCP(Transport Control Protocol) と UDP(User Datagram Protocol) でした。前者ではハンドシェイクにより通信の信頼性が担保されるため、コンテンツの正確性を重視する通信で使われるのに対し、後者は多少の信頼性を欠いてでもリアルタイム性が重視される通信で主に採用されています。
HTTP/3ではUDPをベースにしたQUICを採用しているので、TCP採用のHTTP/2に比べ通信速度の向上が期待されます。また信頼性の部分についてもTCPとは異なる形で、つまりハンドシェイクを多用しない方法で実現されています。
TLS1.3
TLS(Transport Layer Security) は、クライアントとサーバの暗号化通信に関するプロトコルです。その最新版がTLS1.3というわけです。部分的にではありますが、実はHTTP/2でも利用されています。ページやブラウザ等の条件で1.2と1.3のいずれかが使用されるようです。
TLS1.2と比較した際のTLS1.3の主な改善点は、
暗号化方式の切り替え
Client Hello以降すべての通信の暗号化
ハンドシェイクにかかるRTTの削減
などです。上述のQUICの内部要件にTLS1.3が含まれているため、HTTP/3による通信は必ずTLS1.3による暗号化がなされることになります。
HTTP/3の概要
では本題のHTTP/3に移りましょう。まずはこちらの図をご覧ください。
これは、TCP/IPの考え方に当てはめた場合のHTTP/2およびHTTP/3の概念図です。HTTP/2は各階層にきれいにプロトコルが対応しているのに対し、QUICはかなり欲張りで、トランスポート層とアプリケーション層の一部にまで範囲を伸ばしています。また、HTTP/2では独立していた暗号化プロトコル(TLS)が、HTTP/3ではQUICの中にすっぽり入ってしまっています。
パケットをキャプチャしてみる
さて、HTTP/3の概要をお話ししましたが、やたらと文字ばかりで実感が湧きにくかったのではないでしょうか。どのような通信が行われているのか、やはり実際に見てみた方がよさそうです。
というわけで、今回はパケットキャプチャツールというものを使用し、通信の様子を見ていきます。インターネットを介した通信が「パケット」と呼ばれる単位に分割して行われることはご存じかと思います。パケットキャプチャツールを使うことで、それぞれのパケットの持つ情報を分析することができます。コンピューターたちが行うやり取りの内容を垣間見ることができるわけです。
今回利用したツールおよびサイトは以下の通りです。
Google Chrome(HTTP/3で接続するためのWebブラウザ)
Internet Explorer(HTTP/2で接続するためのWebブラウザ)
www.android.com (HTTP/3に対応済みのWebサイト)
Wireshark(パケットキャプチャツール)
なお、世のWebページには既にHTTP/3通信に対応しているものと、そうでないものがあります。QUICがGoogle社によって開発されたこともあり、Google系のWebページはおおかたHTTP/3による接続ができるようになっているようです。
まずは比較対象として、従来のHTTP/2版パケットから覗いてみましょう。
HTTP/2の場合
各行が送受信されたパケットひとつひとつに相当します。順を追って見ていきましょう。
最初の3行は、「SYN(クライアント→サーバ)」「SYN, ACK(サーバ、クライアント)」「ACK(クライアント→サーバ)」という流れになっています。これが、TCP接続でデータの転送に先立って行われる「3-Way Handshake」で、通信の信頼性を担保しているわけです。
その後、「Client Hello/Server Hello」の交換、「Certificate(サーバ証明書)」の発行、「Key Exchange(公開鍵の交換)」を経てようやくTLS接続が確立され、はじめてWebページのデータ本体である「Application Data」をやり取りすることができるようになります。
このように、TCPの特長である通信の信頼性は、データ本体の送受信に先立つ入念なパケット交換により担保されています。しかしそれは同時に、データ通信のたびにオーバーヘッドが増えるということを意味しています。今回の例では、サーバ側がApplicationデータを送るのは最初から数えて16パケット目、やり取りでは4往復目の復路になっています。
HTTP/3の場合
続いて本命のHTTP/3です。最初にクライアントがサーバーに「Initial」パケットを送っていますが、これはHTTP/2で言うところの「Client hello」に当たります。前半で述べたように、HTTP/3要件のQUICはUDPベースですから、TCPの3-Way Handshakeは行われません。
そして、「Initial(≒Server Hello)」が返ってくる前に、クライアントはさらに「0-RTT」という名のついたパケットを送り付けています。RTT(Round-Trip Time)とは、こちらがパケットを送信する+相手から対応するパケットを受信するという一往復のやり取りにかかる時間のことを指します。そのRTTが0ということなので、相手の返信を待たずに送るパケットという意味になります。まずはHelloに対するACKを待ってから次のデータを送るHTTP/2に比べると、少々不躾な印象を受けるほど初動が速いですね。
では、データ本体がどこから送信されているか見てみましょう。HTTP/3では、データ本体をSTREAMという種類のフレーム(=パケットに収められるデータのひとまとまり)に格納されています。キャプチャではなんと5パケット目、最初の往復の復路にもう「STREAM(3)」の文字が確認できます。これは速い。
HTTP/3の機能
今回のキャプチャ画像からすべて見て取ることはできませんが、HTTP/3にはHTTP/2に比べて改良された部分が多々あります。詳細は割愛しますが、以下が代表的なものです。
各ストリームが独立 (HTTP/2ではストリームがHTTPの、パケットがTCPの管轄であったが、HTTP/3では双方QUICの管轄となったため)
パケットの再送が不要(オフセット値から再構成できるため、パケットを順番通りに受け取る必要がない。ロスしたパケットの中から、必要な情報のみが別パケットとして送られる)
トランスポート層情報の保護(トランスポート層(QUIC)と暗号化層(TLS1.3)が一体化しているため)
コネクションのマイグレーション(コネクションIDという値でのみ通信を識別しているため、自分/相手のIPアドレスやポート番号が途中で変更されても通信を継続できる)
ヘッダの圧縮方法の改善
クライアント側からのサーバープッシュキャンセル
ヘッダ内の値を用いた優先度制御
おわりに
今回はHTTP/3のパケットをキャプチャして、そのやり取りの迅速さを見てきました。紙幅(?)の都合上、今回はHTTPそのものの説明は割愛したことをご容赦ください。
__________________________________
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/