quicに関するgriefworkerのブックマーク (17)
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 お久しぶりです。一家の引っ越しでバタバタしておりました。ようやく落ち着いてきましたので、﹁硬直化﹂をテーマとしてQUICに関して3つほど記事を書いてみようと思います。 硬直化 硬直化とは、中間装置が想定外の動作をすることによって、新しい機能の普及が困難になることです。硬直化の例としては、TCP Fast Openが完全に普及できないことが挙げられます。 TCPでは、コネクションを確立するために、いわゆる3WAYハンドシェイクが実行されます。通常は、クライアントがSYNパケットを送信し、サーバがSYN/ACKパケットを返し、その後クライアントがACKを返す際に初めてデータを送信できます。 もし最初のSYNパケットにデータを乗せることがで
-
たとえば、メソッドの値がGETという擬似フィールドを表現するには、2というインデックスを指示すればよいわけです。フィールドの表現として存在するのは以下の3つです。1つのインデックスでフィールド名とフィールド値の両方を指示する インデックスでフィールド名を指示し、フィールド値は文字列で指示する フィールド名とフィールド値の両方とも文字列で指示する2)と3)の文字列の部分では、Huffman符号を使って圧縮するか否かを選べます。また、2)と3)には、それぞれ以下3つの版があります。 動的表に登録する 動的表に登録しない 動的表に登録しない。加えてセキュリティのため、中継装置で伸長後、再圧縮される場合も、常に文字列による指示を使用する制約を付ける 動的表には大きさの制限があり、エントリでいっぱいになると、古いエントリが削除されていきます。動的表にはデフォルトの大きさがありますが、復号側がS
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。QUICは汎用的なトランスポート層プロトコルですので、様々なアプリケーションプロトコルのやりとりに使えます。みなさんがよく知っているHTTP/1.1を乗せることも可能です。実際、開発者の間では、HTTP/1.1の前身の前身であるHTTP/0.9がテスト用に使われていました。 しかし、QUIC上のHTTPの本命は、第一回目の記事で説明したようにHTTP/3です。QUICは、﹁HTTP/2のストリームによる多重化の機能﹂を取り込んでいます。QUICに取り込まれなかったHTTP/2の残りの部分をQUIC用に再定義したのがHTTP/3です。 今回は、HTTPの標準化状況とHTTP/3について説明します。 HTTPの標準化状況 現在よく使われて
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 ﹁フロー制御﹂の回で説明したように、輻輳制御とは途中のネットワークが溢れないようにするための仕組みです。QUICは、正確なRTT計測や、前回説明した簡潔なロス検知の機能を提供しています。このため輻輳制御としては、パケット欠落や遅延といったシグナルを使うアルゴリズムが利用可能です。RFC9002では、デフォルトの輻輳制御アルゴリズムとしてNewRenoを採用しています。 1990年に現れたRenoは、1995年に出されたアイディアに基づいて改良されNewRenoとなりました。2008年に提案されたCUBICや、2016年に現れたBBRに比べると、NewRenoは古い輻輳制御アルゴリズムです。QUICのデフォルトの輻輳制御に古いNewRe
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。QUICは、信頼性を提供するトランスポート層です。そのため、パケットが配送中に欠落した場合、その欠落を判定し、パケット内の情報を再送する必要があります。QUICは、前回の記事で紹介した確認応答を利用して、パケットの欠落を判定します。 送信者にとって、あるパケットに対する確認応答が返ってこない場合、欠落したのか、遅延しているのかはっきりとは判断できません。 遅延しているのに欠落したと判断した場合は、誤った再送(spurious retransmission)を引き起こしてしまいます 欠落したのに遅延していると判断した場合は、必要な再送が実行されません パケットのロス検知は一般的に難しい問題です。TCPでは、さらに確認応答の曖昧性もあるの
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 この連載も12回目を迎え、トランスポート層の魔境であるロス検知と輻輳制御に踏み入る時期が来たようです。私はこの分野の専門家ではないため、表面的な説明になってしまうと思うのですが、ご容赦ください。今回は、ロス検知と輻輳制御の前哨戦として、QUICの確認応答について説明します。 TCPのACK ご存知のようにTCPでは、アプリケーションデータが送信者の送った順番どおりに再構成され、受信者のアプリケーションに渡されます。アプリケーションデータのそれぞれのバイトには、シーケンス番号(通し番号)がつきます。 先頭のシーケンス番号は安全性のために、3-Wayハンドシェイクの際に、乱数的に値が決まります。ここでは、仮想的に先頭のシーケンス番号を0と
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。QUICと﹁TCP上のTLS 1.3﹂との決定的な違いに、トランスポート層に関連する情報が保護されているか否かが挙げられます。TLS 1.3では情報が格納されるTCPヘッダは保護できません。一方QUICでは、トランスポート層に関する情報の多くがペイロードに暗号化されて格納されます。またヘッダの一部のフィールドも保護されます。今回は、ヘッダの保護について解説します。 TCP Fast Openのジレンマ ﹁ハンドシェイク﹂の記事で説明したように、QUICと﹁TCP上のTLS 1.3﹂を比較すると、前者の方がハンドシェイクが1RTT分早く終わります(下図)。2回目以降のハンドシェイクで0-RTTを使う場合も、前者の方が1RTT分早く終わり
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 通信の途中で、クライアントのIPアドレスやポート番号が変更されることがあります。以下の2つが典型例です。 利用するネットワークが携帯網からWi-Fiに変わった (または、その逆) 中間のNATが、別のポート番号を割り当てた TCPでは、コネクションの識別子として両端のIPアドレスとポート番号を使っています。そのため、上記のような場面では、既存のコネクションは維持できなくなり、アプリケーションが通信を続けるには新たにコネクションを作成する必要があります。 一方QUICでは、コネクションの識別子としてコネクションIDを使います。コネクションIDは、IPアドレスやポート番号から独立した名前です。そこで、上記のような場面でもコネクションを継続
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 今回は、QUICのコネクションを終了させる手順について説明します。 正常な終了QUICのコネクションを正常に終了させるには、CONNECTION_CLOSEフレーム(フレーム型の値は0x1c)を送信します。CONNECTION_CLOSEフレームの構造を以下に示します。 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 +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ | Error Code (i) ... +-+-+-+-+-+-+-+-+-+-+-+-+
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 前回、QUICのストリームについて説明しました。今回は、ストリームのフロー制御についてお話しします。フロー制御はそれほど難しい機能ではないので、今回はほとんど用語整理のような内容になっております。 フロー制御と輻輳制御 ネットワーク通信の勉強をしていると、フロー制御と輻輳制御という用語を目にすることがあるかと思います。この2つは同一視されがちです。かくゆう僕も、長い間両者は同じ機能だと間違って理解していました。フロー制御と輻輳制御は、以下のように異なる仕組みです。 フロー制御‥受信者の受信バッファが溢れないようにするための仕組みです。受信者が送信者に何らかの指示をし、送信者はその指示にしたがって送信するデータ量を調整します。 輻輳制御
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 これまでの記事で、QUICのコネクションを確立する手順について説明しました。今回は、いよいよコネクションを使って、アプリケーションデータをやりとりします。 ストリーム ストリームとは、QUICコネクションの中で、順番を守って配送されるバイト列のことです。アプリケーションのデータが、ストリームとして運ばれます。たとえば、あるHTTPの要求とそれに対する応答は、QUICでは1つのストリームとして扱われます。QUICコネクションの中では、複数のストリームが利用できます。ストリーム間ではタイミングを気にする必要はありません。HTTP/1.1のように応答が返ってきた後に次の要求を出すのではなく、複数の要求をあたかも同時に送り、それぞれの応答を
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 増幅攻撃(amplification attack)とは、攻撃者が第三者の管理するサーバにデータの量を増幅させて標的に送りつけるDoS攻撃の一種です。 攻撃者は、小さなデータをサーバに送りつけます。このとき、IPパケットの始点アドレスに標的のIPアドレスを詐称して入れます。プロトコルによっては、サーバは大きな応答を返します。返答先は、標的のIPアドレスになります。 この攻撃にたくさんのサーバを利用すれば、攻撃者の回線には余裕があるが、標的の回線はパンクさせるという状況を実現できます。 攻撃者にとって、TCPには増幅効果を期待できません。攻撃者が送信するSYNのTCPセグメントと、サーバが返すSYN+ACKのTCPセグメントは大きさがほ
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 前回はクライアントとサーバが初めてコネクションを確立する際に実行されるハンドシェイクについて説明しました。まだ、コネクションの切り方を説明してないので恐縮ですが、今回は1回目のコネクションが終了した後の2回目以降のハンドシェイクについてお話しします。 事前共有鍵 前回使ったQUICのハンドシェイク図を少し修正して以下に示します。 色の意味はこうでした。 薄い灰色‥イニシャル鍵で暗号化されている 濃い灰色‥ハンドシェイク鍵で暗号化されている 黒色‥アプリケーションデータ鍵で暗号化されている イニシャル鍵は、クライアントが乱数的に作ったサーバのコネクションIDから生成されました。 ハンドシェイク鍵やアプリケーションデータ鍵は、鍵交換で共有
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 前回は、QUICパケットとフレームの構造について説明しました。準備が整いましたので、今回はコネクションの確立時に実行されるハンドシェイクについて説明します。 トランスポート層を実装する場合、コネクションを確立する部分を作らないと何も通信できませんが、QUICはこのハンドシェイクの実装が結構難しく、実装者泣かせの仕様となっています。 TLS 1.3のハンドシェイク まずTCP上のTLS 1.3のハンドシェイクを以下の図を使って説明します。 最初にTCPのコネクションを張る必要があるので、お馴染みの TCP 3-way ハンドシェイクから始まります。 次にクライアントは、(楕円曲線)Diffie-Hellmanの系統を用いて、使い捨ての公
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 前回の説明では、﹁Initial パケット﹂や﹁Version Negotiation パケット﹂といった用語を未定義で使いました。今回は、こういった﹁パケット﹂や﹁フレーム﹂が、どのような構造を持っているかについて説明します。 古典的なパケットIP、UDP、およびTCPでデータをやり取りする基本単位は、すべて﹁ヘッダ+ペイロード﹂という構造を持っています。このヘッダ+ペイロードという単位は、それぞれ以下のように呼ぶのが慣習です。 IP – パケット UDP – データグラム TCP – セグメント すべてパケットと呼んでも間違いではありません。UDPの場合、IPペイロードが﹁UDPデータグラム(UDPヘッダ+UDPペイロード)﹂に
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。QUICへの誘導 前回のブログで、ブラウザが HTTP/3 (HTTP over QUIC) に対応したサーバにアクセスしたときに、最初は HTTP/2 を使い、2回目の通信からHTTP/3を使うようになると説明しました。今回は、この過程でクライアントとサーバが何を折衝しているか、以下の順で解説します。 TLSのバージョン HTTPのバージョン HTTP/2からHTTP/3への誘導QUICのバージョン TLSのバージョン あるURLで指定されたサーバにクライアントがアクセスすることを考えます。URLは、httpsで始まっていたとしましょう。つまり、TLSの中でHTTPが使われます。現在推奨されているTLSのバージョンは、1.2と1.
-
Haskellコミュニティでは、ネットワーク関連を担当。4児の父であり、家庭では子供たちと、ジョギング、サッカー、スキー、釣り、クワガタ採集をして過ごす。 不定期連載を始めます IIJ-II 技術研究所 技術開発室の山本です。私はプログラミング言語HaskellでHTTP/2とTLS 1.3を実装した後、もっぱらQUICを実装することに時間を費やしてきました。 ご存知の方もいらっしゃると思いますが、今年の5月にQUICの仕様がRFC9000として公開されました。このRFCは実によく書かれているので、読みこなせばQUICの全容が掴めるでしょう。 しかし仕様は膨大ですし、実際に実装してみて初めて腑に落ちることもあります。そこでこの機会に、実際にQUICを実装した経験者目線で、QUICの解説をしていきたいと思います。なんとなくTCP/IPを分かっている方が、ある程度QUICの理解ができることを
-
1