320 likes | 636 Views
UDP ユーザー・データグラムプロトコル. 2002/07/19 miyu. introduction. UDP ( User Datagram Protocol ) トランスポート層プロトコル 信頼性を提供しない 送りっぱなし あて先に到着するかの保証なし IP データグラムとして送信 正式仕様 RFC768. UDP のカプセル化. IP データグラム. UDP データグラム. IP ヘッダ 20bytes. UDP ヘッダ 8bytes. UDP データ. ポート番号. 送り手と受け手のプロセスの識別
E N D
UDP ユーザー・データグラムプロトコル 2002/07/19 miyu
introduction • UDP(UserDatagramProtocol) • トランスポート層プロトコル • 信頼性を提供しない • 送りっぱなし あて先に到着するかの保証なし • IPデータグラムとして送信 • 正式仕様 RFC768
UDPのカプセル化 IPデータグラム UDPデータグラム IPヘッダ 20bytes UDPヘッダ 8bytes UDPデータ
ポート番号 • 送り手と受け手のプロセスの識別 • IPから受け取ったデータを、宛先ポート番号を利用してデマルチプレクス 0 15 16 31 16ビット発信元ポート番号 16ビット宛先ポート番号 8bytes 16ビットUDPデータ長 16ビットUDPチェックサム データ
UDPデータ長フィールド • UDPヘッダとUDPデータの長さをバイト単位で表記 • 最小値8byte (0byteのデータでUDPデータグラムを送ってもOK) (データグラムのデータ長)ー(IPヘッダ長)=UDPデータ長 16ビット発信元ポート番号 16ビット宛先ポート番号 8bytes 16ビットUDPデータ長 16ビットUDPチェックサム データ
UDPチェックサム • UDPヘッダとデータをカバー • IPヘッダのチェックサムはIPヘッダのみ • UDPチェックサムはオプション • でも常に有効にしておくべき • バグで転送中に内容が変わるかもしれない 16ビット発信元ポート番号 16ビット宛先ポート番号 8bytes 16ビットUDPデータ長 16ビットUDPチェックサム データ
32ビット発信元IPアドレス 32ビット宛先IPアドレス UDP擬似ヘッダ ゼロ 8ビットプロトコル 16ビットUDPデータ長 16ビット発信元ポート番号 16ビット宛先ポート番号 UDPヘッダ 16ビットUDPデータ長 16ビットUDPチェックサム データ UDPチェックサムの計算用フィールド (12byte) データ長が2回 出てくることに注意 奇数データ長の ときに必要 パッド・バイト(0)
UDPチェックサムの計算方法 • 16ビットずつに分割して加算 (IPヘッダのチェックサムと似ている) • データ長が奇数バイトの場合 • 8ビット余る • 計算用のパッド・バイトを足す • 転送はされない • UDP擬似ヘッダ • 20バイトのIPヘッダ • 宛先IPアドレスを検証 • IPヘッダは削除されてUDPに渡されるから
tcpdumpの結果 Checksumの 同一性 UDPチェックサムを 無効にしていた • 改造版tcpdump • UDPのチェックサムを入手 1 0.0 sun.1900 > gemini.echo:udp 9(UDP cksum=6e90) 2 0.303755 (0.30389) gemini.echo > sun.1900:udp 9(UDP cksum=0) 3 17.392480(17.0887) sun.1904 >aix.echo:udp 9(UDP cksum=6e3b) 4 17.614371(0.2219) aix.echo >sun.1904:udp 9(UDP cksum=6e3b) 5 32.092454(14.4781) sun.1907 > solaris.echo:udp 9(UDP cksum=6e74) 6.32.314378(0.2219) solaris.echo > sun.1907:udp 9(UDP cksum=6e74) 16bit値の入れ替わりは検出されていない
チェックサムによるエラー検出 • 負荷の高いNFSサーバを40日監視 • データリンク層やネットワーク層でもエラー検出を実施 • ARPもEthernet上で利用されるため、全てのEthernetフレームはIPデータグラムというわけではない • ICMPもIPを利用するため、全てのIPデータグラムがTCPorUDPというわけではない • TCPの方がUDPよりエラー確率が高い • このときUDPトラフィックはローカルに用いられていた? • TCPトラフィックは多くのルータを経由する傾向があった? • UDP、TCPチェックサムも完全に信頼することはできない • 単純…全てのエラーを検出できない
UDPデータグラムの流れ • 最初のデータグラムが送られるまで、コネクションをはらない • いきなりトラフィックを流す • 確認応答もない • データを受け取ったかどうか分からない • プログラムが実行される度に発信元ポート番号が変わる • エフェメラル・ポート • ポート番号1024~5000
IP Fragmentation • Physical network層では転送できるフレームサイズに上限 • インターフェース毎にMTU(Maximum Transmit Unit)が異なる • フラグメンテーション • データグラムの大きさによる • 最終のあて先に到着するまで再構築されない • データグラムのフラグメントが再びフラグメント化されることも • フラグメント化とリアセンブリに必要な情報はIPヘッダに記載 • 宛先のIP層でリアセンブリされる
(復習)IPヘッダ • IPデータグラムに対して一意 • データグラムのフラグメントの全てにコピーされる • 元データグラムの先頭からどの位置なのか 4ビット バージョン 4ビット ヘッダ長 8ビットTOS 16ビット全長(バイト) 16ビット識別子 ビット フラグ 13ビット・フラグメントオフセット 20バイト 8ビット生存時間(TTL) 8ビット・プロトコル 16ビット・ヘッダチェックサム 32ビット発信元IPアドレス • 立っている時は、最後のフラグメントでない • もっとフラグメントがある フラグメントのサイズで変更される 32ビット宛先IPアドレス オプション(任意) データ
フラグメント化されると • 別々のパケット 別々にルーティング • 受け手がIPヘッダからリアセンブリ • フラグメントが欠けた場合 • 全データグラムを破棄 • 中継ルータでフラグメントされた場合、再構成が困難 • IPレイヤーではタイムアウトも再転送もしない • TCPならトランスポート層でTCPセグメント全体を再送 • UDPは再送しない
フラグメンテーションのtcpdump 1 0.0 bsdi.1112 > svr4.discard: udp 1471 2 21.008303(21.0083) bsdi.1114 > srv4.discard: udp 1472 3 50.449704(29.4414) bsdi.1116> svr4.discard: udp1473 (frag 26304: 1480@0+) 4 50.450040(0.0003)bsdi > svr4:(frag26304:1@1480) 5 75.328650(24.8786) bsdi.1118>svr4.discard: udp 1474 (frag 26313:1480@0+) 6 75.328982(0.0003) bsdi > svr4: (frag 26313:2@1480)
フラグメンテーションの例 • ethernetフレームの最大データ量は1500バイト • ヘッダを引くとデータは最大1472バイト IPデータグラム IPヘッダ 20bytes UDPヘッダ 8bytes UDPデータ(1473bytes) IPヘッダ 20bytes UDPヘッダ 8bytes UDPデータ(1473bytes) IPヘッダ 20bytes 1byte パケット 1 パケット 2
ICMP Unreachable Error(Fragmentation Required) • フラグメントが必要なデータグラム • フラグ・フィールドの「フラグメント禁止」ビットが立っている フラグメント化せず、データグラムを破棄 ICMPエラーを返す • 宛先パスまでの最小MTUの発見に応用 • パスMTUディスカバリ・メカニズム
ICMP Unreachable Error ネクストホップのMTU記述あり(未サポート時は0) タイプ(3) コード(3) チェックサム 8バイト 未使用(0) ネクストホップのMTU IPヘッダ(オプションを含む) +オリジナルIPデータグラムの最初の8バイト
TracerouteでパスMTUを決定してみよう! • ほとんどのシステムはパスMTUディスカバリメカニズムをサポートしていない • 改造tracerouteを使用 • フラグメント化禁止ビットを立てたパケットを送る • 最初は送信インターフェースのMTUで • ICMP Unreachable Errorを受け取ったら • パケットサイズを縮小して再送
TracerouteによるパスMTU決定 %traceroute.pmtu slip Traceroute to slip(140.252.13.65),30 hops max Outgoing MTU=1500 1 bsdi(140.252.13.35) 53ms 6ms 6ms 2 bsdi (140.252.13.35) 6ms Fragmentation required DF set, next hop MTU =296 2 slip (140.252.13.65) 377ms 378ms 377ms
UDPによるパスMTUディスカバリ • アプリケーションが中継回線にとって大きすぎるデータグラムを作成するとどうなる? • MTUの異なる複数のインターフェイスの存在する環境で検証 • DFビット(フラグメント化禁止)で送信開始 • エラーが起きるとフラグメント化する • エラーICMPメッセージにMTU記述があれば、それに従いフラグメントの設定をする • 30秒に一度、再びDFビットを設定して送信 • MTUが増加したか試す
UDPによるパスMTUディスカバリ ここでtcpdumpを実行 MTU=1500 MTU=1500 MTU=1500 MTU=1500 bsdi netb slip SLIP sun SLIP solaris MTU=296 MTU=296 MTU=1500 MTU=552 DFビットが設定された650byteのUDPデータグラム ICMP Can’t fragment error
パスMTUディスカバリ tcpdump 1. 0.0 solaris.38196> slip.discard:udp 650(DF) 2. 0.04199(0.0042)bsdi>solaris:icmp: slip unreachable – need to frag mtu = 296(DF) 3. 4.950193(4.9460) solaris.38196>slip.discard:udp 650(DF) 4. 4.954325(0.0041) bsdi>solaris:icmp: slip unreachable – need to frag mtu = 296(DF) 5. 9.779855(4.8255) solaris.37974>slip.discard:udp 650(frag 35278:272@0+) 6. 9.930018(0.1502)solaris>slip: (frag 35278:272@272+) 7. 9.990170(0.0602) solaris>slip: (frag 35278:114@544)
Interaction Between UDP and ARP • ARPキャッシュを空にしてUDPデータグラムを生成 • 最初のフラグメントが送信される前にARP requestとARP replyが交換されるはず • フラグメント化された全パケットがARP requestを出す • ARPの実装は1秒あたり1 requestにするべきとされている • 応答を待つ間、最後のパケットだけが保持される • 他のフラグメントは破棄される
Interaction Between UDP and ARP • 最後のARP replyから5分間、 ICMP”time exceeded during reassembly”error を待ち続けている…..エラーは返されず • 最初のフラグメントが届いてからタイマーをスタート • Timeoutしたら全フラグメントを破棄 • フラグメントの断片を破棄してバッファをクリア • オフセット0のパケットが届かなかったら返さない • トランスポート層ヘッダがないのてプロセスが識別できない
UDPデータグラムサイズの最大値 • 理論的には65535バイトがIPデータグラムの最大値 • IPヘッダの全長値(16ビット)から • UDPは65535 – 20(IP header)– 8(UDP header) = 65507バイト • 実際はこれより最大値小さい • アプリケーションの読み書きできるデータグラムサイズに依存(8192バイト以上) • TCP/IPカーネルの実装上のバグ • IPデータグラムで576バイトまでは必須 • 許容サイズより大きいときは? →これも実装依存
タイプ(4) コード(0) チェックサム 8バイト 未使用(0) IPヘッダ(オプションを含む) +オリジナルIPデータグラムの最初の8バイト ICMP Source Quench Error • UDPトラフィックが処理できない速さの時発生
ICMP Source Quench Error • 送るのことは任意 • 受け取るのも任意 • 通常UDPの場合、発信元抑制を受信しても無視される • TCPと違ってあまり効果的でない • プロセスは既に送信を完了 • バッファから溢れたデータグラムは捨てられる • UDPは信頼できない • End-to-Endでのフロー制御が必要
UDPサーバの設計 • 発信元のIPアドレスと宛先ポート番号を見て処理 • 複数のクライアントを処理できる • ブロードキャストアドレス宛てのパケットは捨てられる事もある • destination IP addressを必要とするUDPアプリケーションなど • 全てのクライアントからの要求を単一ポートで受ける • 到着した順にアプリケーションに受け渡される • データグラムはqueingされ、溢れたら破棄 • ICMP Source Quench Error のようなものは全く返されない • FIFO(先入れ先出し)
UDPサーバの設計 • ローカルIPアドレスの制限 • ワイルドカード化 • エンド・ポイント作成のとき、ホストのローカルIPアドレスの1つをエンドポイントのローカルIPアドレスとして指定することが可能。 • 外部から接続してくるIPアドレスの制限 • 特定のIPアドレス+UDPポートあたり1サーバの制限 • マルチキャストは例外
まとめ • UDPは単純なプロトコル • IP以上はポート番号とオプショナルなチェックサムだけ。 • IPフラグメンテーション • ICMP到達不可エラー • UDPとARPのやりとり • ICMP発信元抑制エラー