『ハイパフォーマンスブラウザネットワーキング』メモその3

メモの続き。本日はUDPで、TCPに比べると分量は少なめ。

しかし、読めば読むほど、良い本だなあと思います。自分のこれまで曖昧になっていたところや、疑問に思っていたところをしっかり解説してくれている感じです。

要約は自分がこのサイトに載せていっていますが、Webに関わる人はぜひ原本を読んでみることをオススメしておきます。しっかり図とかも入っていますので。

3章 UDPの構成要素

  • UDP (User Datagram Protocol)の主な特徴は、その機能に存在するのではなく、あえて機能を除外したというところに存在する。
  • データグラムとは、自己完結し、独立した存在としてのデータであり、送信元と宛先のノード間や、そのネットワークにおける過去の通信内容に依存することなく、ノード間のルーティングを行うための十分な情報を持っているもの。
  • 「パケット」はフォーマットされたデータブロック全般に対して使われ、「データグラム」はパケットの中でも信頼性の低いサービスによって配信されるものを指す。配信される保証はなく、失敗の通知もない。
  • 最もよく知られたUDPの用途であり、すべてのブラウザとインターネットアプリケーションが依存するものが、 DNS (Domain Name Service)
  • WebRTC (Web Real-Time Commuication)は、UDPを使用し、音声や動画を始めとしたP2Pのリアルタイム通信をブラウザ内でネイティブに実行できる。
  • UDPは、IPパケットに、送信ポート番号宛先ポート番号パケット長チェックサムの4つの追加フィールドをつけて、ユーザメッセージをカプセル化したもの。
    • 送信元ポート番号とチェックサムは、実はオプション。UDPは通信しているホストアプリケーションの送信元と宛先のポート番号を埋め込むことで、IPに「アプリケーション多重化」を提供している。
  • UDPが提供しないサービスは以下。
    • メッセージ配信の保証なし
    • 順序通りの配信の保証なし
    • 状態追跡なし
    • 輻輳制御なし
  • TCPはバイトストリーム指向のプロトコルである。つまり、パケット自体は明確なメッセージ境界を持たず、複数のパケットにまたがったアプリケーションメッセージを転送できる。接続状態は接続の両側に割り当てられていて、パケットは順序づけられ、パケットロスの際には再送信され、そして順序通りに配信される。
  • これに対して、UDPデータグラムは明確な境界を持っている。各々のデータグラムは単一のIPパケットで運ばれ、アプリケーションは一度の読み込みで完全なメッセージを取得する。データグラムは分割できない。
  • IPv4のアドレス枯渇に対して提案された解決法が、ネットワークの末端に「NATデバイス」を配置し、IPアドレスを再利用するというもの。各NATデバイスは、ローカルIPとポート番号の組を、グローバルで一意となるパプリックIPとポート番号の組にマッピングする変換テーブルを管理する。そして、NATデバイスの先にあるローカルIPアドレス空間は、異なるネットワークで再利用することが可能となり、アドレスの枯渇問題を解決する。
  • NATは接続状態に依存するが、UDPにはそもそも状態がない。これが、UDPデータグラムを配信する際に発生する多くの問題の原因となる。
  • 外向けのUDPトラフィックを配信するためには、送信元ホストのIPアドレスとポートを知り、返信経路を指定するために、NAT変換テーブルにエントリを持っている必要がある。したがって、自身では状態を持たないUDPの状態を、NATが保持する必要がある。
  • UDPのルーティングレコードは、タイマによって失効する。タイマの長さは、NATデバイスのベンダ、製品、バージョンや設定に依存する。結果として、UDPで長期間続くセッションのための事実上のベストプラクティスの1つは、経路上のNAT装置の変換レコード削除タイマを定期的にリセットするために、双方向のキープアライブパケットを導入することである。
  • NAT装置の多くは、TCPとUDPの両方のセッションに同じタイムアウトロジックを用いる。その結果、場合によってはTCPも双方向のキープアライブパケットが要求される。 TCP接続が切れる場合は、中間にあるNATのタイムアウトが原因の可能性がある。
  • 状態処理の話もあるが、NATを使うと、そもそもUDP接続を全く確立できない
  • 最初の問題は、NAT背後にある内部ネットワークのクライアントが、自身のパブリックIPを認識できないことである。NATデバイスが、UDPパケットに含まれる送信元ポート番号と、IPパケットの送信元IPアドレスを書き換えるが、クライアントが自身のプライベートIPアドレスをアプリケーションデータに含めて通知し、外部ネットワークに存在するピアと通信を行おうとすると、接続は必然的に失敗する。自身のパブリックIPアドレスをプライベートネットワークの外側にあるピアと共有する必要があれば、アプリケーションは自身のパブリックIPアドレスをあらかじめ認識しておかなければならない。
  • さらに、NATデバイスのパブリックIPに到達するパケットは、宛先ポート番号を持っていなければならない。そのポート番号をプライベートネットワークの宛先IPアドレス/ポート番号に変換するためには、そのポート番号を持つNATテーブルのエントリが存在しなければならないが、パブリックネットワークからプライベートネットワークのマシンにデータを送信しようとする場合、このエントリが存在していることがほぼない。エントリが存在しなければ、パケットは単にそこで破棄されてしまう。
  • このようなUDPとNATの相性の悪さに対処するには、様々なトラバース技術(TURN, STUN, ICE)を用いて、両UDPピア間のエンドツーエンド接続を確立しなければならない。
  • STUN (Session Traversal Utilities for NAT, RFC 5389)は、自身のネットワーク上のNATデバイスの存在を発見し、NATが存在する場合は現在の接続に割り当てられているパブリックIPとポート番号の組(自分自身のパブリックIPとポート番号)を取得するためのプロトコル。これを行うために、STUNプロトコルはパブリックネットワークに存在するSTUNサーバの助けを借りる必要がある。
  • STUNサーバのIPアドレスが既知である場合、クライアントアプリケーションはまずSTUNサーバにバインディングリクエストを送信する。STUNサーバはそのレスポンスとして、そのクライアントのパブリックネットワークから見たIPアドレスとポート番号を返す。これによって、以下の問題が解決される。
    • アプリケーションはパブリックIPとポート番号の組を発見する。この情報をピアとの通信の際にアプリケーションデータの一部として使用できる。
    • STUNサーバへの外向きのバインディングリクエストは、サーバに到達する際にNATを通過し、内向きのパケットがクライアントアプリケーションに到達できるルーティングエントリ(IPアドレスとポート番号の組)を作成する。
    • STUNプロトコルには単純なキープアライブのメカニズムが定義されており、NATルーティングエントリのタイムアウトを防止する。
  • 上記のメカニズムを利用して2つのピアがUDP通信を行う場合は、最初にそれぞれのSTUNサーバにバインディングリクエストを送信する。パブリックIPとポート番号を伴った成功レスポンスが両者に返されると、これらをピア間のデータ通信に使用できる。
  • ファイアウォールなどによってSTUNが機能しない場合、TURN (Traversal Using Relays around NAT, RFC5766)プロトコルをフォールバックとして利用できる。
    • 双方のクライアントが同一のTURNサーバに割り当て要求を送信し、続けてパーミッションのネゴシエーションを行うことで接続を開始する。
    • 一度交渉が完了すると、双方のピアはデータをTURNサーバに送信することで通信を行う。TURNサーバがもう一方のピアにそのデータを送信する。
  • TURNを使う場合、明らかに、P2P通信ではなくなる。さらに、TURNサーバを運用しなければならないという、非常に高いコストを伴う。TURNは直接接続できない場合の最終手段として使用するのがベスト。
  • NATトラバーサルの構築作業は、ICE (Iteractive Connectivity Establishment, RFC 5245)プロトコルにヘルプを頼むことができる。ICEは参加者の間の最も効率的な経路を確立するためのプロトコルであり、メソッドの集合体である。可能な限り直接接続を行い、必要ならばSTUNを活用し、それらが動作しない場合は最後にTURNを使用する。
  • UDPを用いた新たなトランスポートプロトコルの設計には多くの注意深い検討、計画、そして調査が必要である。可能な場合は、NATトラバーサルを備え、さらに同時に存在する他のネットワークトラフィックと問題なく動作する、既存のライブラリやフレームワークを活用する。WebRTCが、まさにそのようなフレームワークとなっている。

以上。WebRTCも絡めた解説記事は初めて読みました。

次はややこしそうでかつ、それゆえに最もちゃんと勉強しなくてはいけない、TLSのお話です。