ネットワーク●●○○○

UDP

UDP ・ ゆーでぃーぴー

到達や順序の保証を捨て、IP にポート番号だけを足した軽いトランスポート。DNS・通話・QUIC の土台。

✦ 30秒で試す — 航海届いたか確かめもしない雑な通信が、通話やゲームの主役だTCP で受けている聞き手の音声は、どうなる?予想してみる

概要

UDP(User Datagram Protocol)は、TCP/IP の TCP と対をなす、もう1つのトランスポート層のプロトコルです。TCP が「順序どおり・欠けずに届ける」仕組みを一通り備えるのに対し、UDP は事前の接続の確立も、届いたかどうかの確認も、再送もしません。データを1つの小包(データグラム)に詰めて、宛先の IPアドレスとポート番号へ投げる。やることはほぼそれだけです。

一見頼りない仕様ですが、そのぶん速くて軽く、自由です。音声通話や動画のライブ配信、オンラインゲーム、そして DNS の問い合わせなど、「多少欠けても遅れるよりまし」「1往復で終わるから準備の手順はいらない」という通信の主役です。近年は、HTTP/3 の土台である QUIC も UDP の上に作られています。

なぜ生まれたか

TCP/IP の TCP が提供する信頼性は、ただではありません。通信の前に3ウェイハンドシェイクの往復が要り、パケットが1つ失われると、再送が終わるまで後ろのデータも足止めされます。ところが音声通話では、0.2秒前の音声を再送してもらっても、もう再生する時刻を過ぎていて役に立ちません。古いデータを律儀に届け直す TCP の生真面目さが、リアルタイムの用途ではかえって品質を下げてしまうのです。

また、DNS のように「1つ質問して1つ答えをもらう」だけの通信では、そのためにコネクションを確立して閉じる手間のほうが本体より重くなります。当初の TCP の設計はトランスポートとネットワークの機能を1つにまとめていましたが、こうした用途のために、1978年ごろに TCP と IP が分けられ、IP の「ベストエフォートで運ぶ」機能に、ポート番号による振り分けとチェックサム(データの破損の検出)だけを足した最小限のプロトコルとして、1980年に UDP が定義されました(RFC 768)。信頼性が必要なら、アプリケーションが自分で作ればよい、という割り切りです。

詳細

仕組み: ほとんど「何もしない」設計

UDP のヘッダは、送信元ポート・宛先ポート・長さ・チェックサムのわずか8バイトです。最低20バイトある TCP のヘッダと並べると、TCP が番号・確認応答・ウィンドウ・制御フラグのために何を持っているかがよく分かります。

TCP(最低20バイト)送信元ポート宛先ポートシーケンス番号(順序と欠落の検出)確認応答番号(届いた範囲)フラグ SYN・ACK・FINウィンドウチェックサム緊急ポインタ・オプション…金の欄が「信頼性」のための道具UDP(8バイト)送信元ポート宛先ポート長さチェックサム番号も確認応答もない→ 順序・欠落・混雑への対処はアプリの設計しだいどちらも行の幅は32ビット(4バイト)。UDP はちょうど2行分
TCP と UDP のヘッダ。UDP にはポート番号と長さとチェックサムしかない

コネクションという概念がないので、送信側は相手の状態を気にせず、いつでもデータグラムを送れます。TCP と往復を並べて比べると、その身軽さがよく分かります。

受信側送信側受信側送信側TCP の場合 まず接続を確立してから送るUDP の場合 いきなり本題を投げる確認応答なし 欠落や順序の扱いはアプリの設計しだいSYNSYN+ACKACK とデータ確認応答データグラム

この「何もしなさ」は欠点であると同時に自由度です。TCP では1つの通信が1本のコネクションに縛られますが、UDP なら1つのソケットで不特定多数とやり取りできます。同じネットワークの全員に送るブロードキャストや、参加しているグループに送るマルチキャストも UDP の領分です。また、TCP のデータは切れ目のないバイトの流れですが、UDP は送った1回分が1つのデータグラムとしてそのまま届く(届くなら)ので、メッセージの区切りをアプリが自分で付ける必要がありません。

遅れるより欠けるほうがまし

UDP が選ばれる典型が、リアルタイムの音声や映像です。受信側は少しだけ先読みの余裕(ジッタバッファ)を持って再生しますが、再生の時刻を過ぎたパケットには価値がありません。TCP で運ぶと、1つのパケットが失われただけで、再送が届くまで後ろのパケットも受け取れず、再生が止まります。UDP で運べば、失われた一瞬だけ音が欠けて、再生はそのまま先へ進みます。欠けた部分は、前後から補ったり、あらかじめ冗長なデータを混ぜておいて復元したりする工夫(誤り訂正)で目立たなくできます。

下の部品で確かめてください。同じ音声のパケットを TCP と UDP の2本の回線で同時に流し、回線の上のパケットを押すと、同じパケットが両方で失われます。TCP の再生が止まるのか、UDP の再生が欠けるのかを見比べてください。

⚡ 体験: 同じ音声を TCP と UDP で流して、パケットを落とす
TCP(順番どおり・欠けたら再送)UDP(届いた順・再送しない)話し手0.25秒ごとに1パケットTCP で受けて再生待機中UDP で受けて再生待機中再生のタイムライン(横軸 = 時刻。青緑 = 再生した断片 / 金 = 止まった時間 / 朱 = 欠けた断片)0秒2秒4秒6秒8秒TCPUDP
落としたパケット0TCP の停止(合計)0.0 秒TCP の遅れ0.0 秒UDP の欠け0

「送信開始」を押すと、話し手の声が 0.25秒ごとのパケットになって、TCP と UDP の2本の回線を同時に流れます。飛んでいるパケットを押して落としてみてください(同じ番号が両方の回線で失われます)。

代表的な使いどころ

DNS の問い合わせは典型例で、1往復で完結する小さなやり取りに最適です(応答が大きすぎる場合は TCP でやり直します)。音声・ビデオ通話(WebRTC など)やライブ配信、オンラインゲームでは、「最新の状態」だけが価値を持つので、失われた古いパケットを諦めて先へ進む UDP の性質がそのまま利点になります。ほかにも、時刻同期の NTP、IP アドレスを配る DHCP、ログを転送する syslog、VPN の WireGuard など、インフラの足回りにも広く使われています。

「信頼性はアプリの層で作る」— QUIC へ

UDP の設計思想がいちばん大きく花開いたのが、HTTP/3 の土台である QUIC です(HTTP/3とQUIC)。TCP は OS のカーネルに実装され、途中の機器も TCP の中身を覗いて処理するものが多いため、改良を広めるのに何十年もかかっていました。QUIC は UDP の上に、再送制御・輻輳制御・TLS による暗号化をまとめて作り直し、ブラウザやアプリと一緒に更新できるようにしました(2021年に RFC 9000)。1つのコネクションの中で複数のストリームを独立に扱うので、TCP の「1つのパケットが欠けると全部が止まる」問題(ヘッドオブラインブロッキング)も避けられます。「土管は UDP に任せ、賢さは差し替えられる形で上に載せる」というやり方です。

実務での落とし穴

UDP を選ぶときの落とし穴は、まさに「何もしてくれない」ことから来ます。第一に、欠落・重複・順序の入れ替わりへの対処は、すべて自分の設計の課題になります。「手元では動くが本番でときどきおかしい」という UDP のアプリの不具合は、パケットロスを想定していないことが原因の定番です。第二に、輻輳制御がないので、無配慮に送り続けるとネットワークを圧迫します。送るペースの調整もアプリの責任です。

第三に、送信元の IP アドレスを偽れる性質から、リフレクション(反射)型の DDoS攻撃に悪用されてきました。攻撃者は、送信元を被害者の IP に偽った小さな問い合わせを、公開されている DNS や NTP、memcached などのサーバに大量に送ります。サーバは律儀に大きな応答を「送信元」、つまり被害者へ返すので、攻撃者の送った量の何十倍・何万倍もの通信が被害者に集中します。TCP ではハンドシェイクで送信元が確かめられるので、この手口は成り立ちにくいのです。

攻撃者送信元を偽る公開 DNS公開 NTPmemcached被害者頼んでいない応答小さな問い合わせ送信元=被害者大きな応答が集中増幅率は DNS で数十倍、memcached では数万倍になった例もある
リフレクション型の DDoS 攻撃。送信元を偽った小さな問い合わせが、何倍もの応答になって被害者に跳ね返る

対策として、ネットワークの出口で送信元を偽ったパケットを捨てる(送信元アドレスの検証)、公開サーバの応答のペースや大きさを制限する、といった手が取られています。QUIC も、相手のアドレスを確かめるまでは受け取った量の3倍までしか送らない、という制限を仕様に組み込んでいます。

最後に、企業のネットワークのファイアウォールや家庭のルータの NAT は、UDP に厳しめなことがよくあります。コネクションがないので「いつ通信が終わったか」が分からず、NAT の対応表の記録は数十秒〜数分で消えてしまいます。そのため UDP のアプリは定期的に小さなパケットを送って記録を保ち、「UDP が通らない環境では TCP に切り替える」二段構えを用意するのが実務の定石です。

試問

通信には、届いたかを確かめて欠けたら送り直し、必ず順番どおりに渡す TCP と、確かめも送り直しもせず小包を投げるだけの UDP があります。下の7つの通信が、それぞれどちらの上で運ばれるのが普通かを考えます。遅れと欠けのどちらが困るかが手がかりです。

✦ 命題挑戦中

7つの通信を、TCP の上で運ぶものと UDP の上で運ぶものに仕分けよ

TCP で運ぶ欠けたら送り直し、順番どおりに渡す
UDP で運ぶ確かめず送り直さず、投げるだけ

項目を選んでから、入れる箱を選びます