PMTUDはいつ実行されますか?(パスMTUディスカバリー)


21

拍車をかけてきた議論では他の質問、このサイト、私はをしっかりと理解していないことに気付きました際にパスMTUディスカバリ(PMTUD)が実行されています。

私はそれがをするか知っています-クライアントからサーバーへのパスで最も低いMTUを発見してください。
私が知っているどのように彼らの「ないフラグメント」ビットセットで徐々に大きなパケットを送信すると、エラー「フラグメントにICMPの必要性」取得せずに介して取得することができますどのようにパケットの大きな見る-それはそれをしません。

私の質問は具体的は、ホストがPMTUDを実行するのはいつですか?

特定のケースを探しています。「ホストがパスMTUを発見したいとき」のような一般的なものだけではありません。ボーナスは、それを行うホストのパケットキャプチャを提供できる場合、またはそのようなパケットキャプチャを生成するための指示を提供できる場合にポイントします。

また、特にIPv4について言及しています。IPv6では、一時的なルーターはフラグメンテーションの原因ではないことを知っています。PMTUDがより一般的に発生することは想像できます。しかし、今のところ、IPv4でのPMTUDの特定の例を探しています。 (PMTUDを組み合わせることができる唯一のパケットキャプチャがIPv6である場合でも、私はそれを見たいと思っています)


PMTUDは、サポートされている最低のMTUから最高のMTUまで実行されますか?または、PMTUDを実行するデバイスは、最初に最大のMTUを試し、次にパケットが通過するまで大きな増分でステップダウンし、次に小さな増分でステップアップし、最終決定が行われるまで前後に交互に切り替えますか?
cpt_fink 14

@cpt_fink、いくつかの戦略があります。ICMP Fragmentation Neededメッセージの最新の実装には、ICMPペイロード自体に、フラグメンテーションが必要なリンクのMTUが含まれています。開始ホストはパスMTUが何であるかをすぐに知っているため、これは簡単です。古い実装では、使用する適切なMTUを「検索」するためにさまざまな戦略を使用する必要があります。これらの戦略は、セクション5のRFC1191で概説されています。それらは、自動的にデフォルトのIP最小(576)から、「共通」MTUのテーブルを使用してより効率的に検索するまでの範囲です(RFC1191セクション7.1を参照)。
エディ14

2
これは興味深い質問です。私はPMTUDを掘り下げていたところ、これを見つけました。それは古いものですが、まったく同じ質問があり、数時間の調査の後、かなりまともな答えを思い付くことができたので、答えることにしました(推測)。可能であれば、明日、パケットキャプチャを使用して回答を更新およびサポートしようとします。
フィリペゴンサル

回答:


15

答えは簡単です。ホストが喜んでいつでも。本当に。とても簡単です。

以下の説明はIPv4のみの環境を想定しています。これは、IPv6がルーターのフラグメンテーションをなくすためです(ホストは常にフラグメンテーションとMTUディスカバリーを処理するように強制します)。

ホストがPath MTU Discoveryを実行するタイミング(または実行する場合でも)を管理する厳密なルールはありません。PMTUDが表面化した理由、さまざまな理由でフラグメンテーションが有害あると考えられるためです。パケットの断片化を回避するために、回避策としてPMTUDの概念が実現されました。もちろん、優れたオペレーティングシステムで、PMTUDを使用して断片化を最小限に抑える必要があります。

したがって、当然、PMTUDが使用される正確なセマンティクスは、送信者のオペレーティングシステム、特にソケットの実装に依存します。私はLinuxの特定のケースについてのみ話すことができますが、他のUNIXバリアントはおそらくそれほど違いはありません。

Linuxでは、PMTUDはIP_MTU_DISCOVERソケットオプションによって制御されます。getsockopt(2)レベルIPPROTO_IPIP_MTU_DISCOVERオプションを指定して、現在のステータスを取得できます。このオプションはSOCK_STREAMソケットに対してのみ有効です(SOCK_STREAMソケットは双方向の接続指向の信頼できるソケットです。実際にはTCPソケットですが、他のプロトコルも可能です)。設定すると、LinuxはRFCで定義されたとおりにPMTUDを実行します1191。

実際には、PMTUDは継続的なプロセスであることに注意してください。パケットは、3ビットハンドシェイクパケットを含むDFビットセットで送信されます-接続プロパティと考えることができます(ただし、実装は、ある時点である程度の断片化を受け入れ、DFでのパケット送信を停止する場合があります)ビットセット)。したがって、PMTUDは、その接続上のすべてがDFで送信されているという事実の結果にすぎません。

設定しないとどうなりますIP_MTU_DISCOVERか?

デフォルト値があります。デフォルトでIP_MTU_DISCOVERは、SOCK_STREAMソケットで有効になっています。これは、readによって読み取ったり変更したりできます/proc/sys/net/ipv4/ip_no_pmtu_disc。ゼロの値はIP_MTU_DISCOVER、新しいソケットでデフォルトで有効になっていることを意味します。ゼロ以外は反対を意味します。

コネクションレスソケットはどうですか?

コネクションレスで信頼性の低いソケットは失われたセグメントを再送信しないため、これは注意が必要です。MTUサイズのチャンクでデータをパケット化するのは、ユーザーの責任になります。また、ユーザーは、メッセージが大きすぎるエラーの場合に必要な再送信を行うことが期待されます。したがって、基本的にユーザーコードはPMTUDを再実装する必要があります。それでも、あなたが挑戦に立ち向かうなら、IP_PMTUDISC_DOフラグをに渡すことでDFビットを強制できますsetsockopt(2)

ボトムライン

  • ホストは、PMTUDをいつ(そしていつ)使用するかを決定します
  • PMTUDを使用する場合、接続属性のようなものであり、継続的に発生します(ただし、実装はいつでも自由に停止できます)
  • 異なるオペレーティングシステムは異なるアプローチを使用しますが、通常、信頼性の高い接続指向のソケットはデフォルトでPMTUDを実行しますが、信頼性の低いコネクションレスソケットはそうではありません

4

通常、パスの最大伝送単位の検出(PMTUD)は、ホストが大きすぎるためにパケットがドロップされたと判断した場合に発生します。

これは、パケットがドロップされたことを明示的に示すICMPフラグメンテーション要求(タイプ3、コード4)応答への応答である可能性があります。通常、すべてのIPv4パケットは「do n't fragment」(DF)フラグが設定された状態で設定されるため、MTUを超えるパケットはそのような応答を誘発します。IPv6はフラグメンテーションをまったくサポートしていません。

素朴な管理者はICMPがセキュリティリスクであると考えているため、一部のルーターまたはホストファイアウォールはすべてのICMPを頻繁にドロップします。または、一部のリンク集約スキームがICMP配信を中断する場合がありますRFC4821では、ICMPに依存しないMTUを発見するための代替メカニズムが提案されています

tracepathMTUを調べるための私のお気に入りのLinuxツールです。以下は、LAN上に9001 MTUを持つホストからの例ですが、IPsec VPNを通過して10.33.32.157に到達する必要があります。

$ tracepath -n 10.33.32.157
 1?: [LOCALHOST]                                         pmtu 9001
 1:  10.1.22.1                                             0.122ms pmtu 1500
 1:  169.254.3.1                                           1.343ms pmtu 1422
 1:  10.255.254.61                                        23.790ms 
 2:  no reply
^C [this host won't return an ICMP port unreachable, so tracepath won't terminate]

ICMPエラーは次の方法で確認できますtcpdump

$ sudo tcpdump -p -ni eth0 'icmp and icmp[0] == 3 and icmp[1] == 4'
14:46:57.313690 IP 10.1.22.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1500), length 36
14:46:57.315080 IP 169.254.3.1 > 10.1.22.194: ICMP 10.33.32.157 unreachable - need to frag (mtu 1422), length 556

MTUディスカバリーはキャッシュされます。Linuxでは、これを観察してフラッシュできますipLinux 3.6以降変更に注意してください)。

$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache  expires 591sec mtu 1422
$ sudo ip route flush cache
$ ip route get 10.33.32.157
10.33.32.157 via 10.1.22.1 dev eth0  src 10.1.22.194 
    cache

TCPの場合、接続設定の一部としてMTUを超えることを避けることができます。各エンドから送信されるSYNには、最大セグメントサイズ(MSS)が含まれます。TCPヘッダー(オプションを除く 20バイト)とIPヘッダー(20バイト)は、MSSとMTUが40バイトの差で関連付けられていることを意味します。

以下に、大きなファイルを転送するときのこれら2つのホスト間の接続設定の例を示しますscp

$ sudo tcpdump -p -ni eth0 'host 10.33.32.157 and tcp[13]&2 == 2'
IP 10.1.22.194.45853 > 10.33.32.157.22: Flags [S], seq 634040018, win 26883, options [mss 8961,sackOK,TS val 10952240 ecr 0,nop,wscale 7], length 0
IP 10.33.32.157.22 > 10.1.22.194.45853: Flags [S.], seq 1371736848, ack 634040019, win 26847, options [mss 1379,sackOK,TS val 10824267 ecr 10952240,nop,wscale 7], length 0

最初のパケットで、ローカルホストは8961のMSSを提案します。これは、設定された9001 MTUで、40バイト未満です。返されたSYN / ACKのMSSは1379で、MTUは1419です。このネットワークでは、リモートホストも8961を送信したことがわかりますが、パスにインターネットパスが含まれていることがわかっているため、ルーターによって値が変更されています( MTU 1500)IPsecトンネルからのオーバーヘッド。このルーターは、送信された8961のMSSを変更して、他のホストで1419として表示します。これはMSSクランプと呼ばれます。

ある意味で、PMTUDは常に発生しています。実際には、MSSクランプが設定されており、すべてのトラフィックがTCPを介して発生している場合、またはエンドポイントで設定されたものよりもMTUが小さいルーターが存在しない場合、実際に発生することはありません。MSSクランプがなくても、キャッシュの有効期限が切れる場合、まれにしか発生しません。


弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.