|||||||||||||||||||||

なんぶ電子

- 更新: 

MTU/MSS値について

なんかおかしくない?

インターネットの記事を読んでいたら、MTUを表示してくれるサイトがあるというので何の気なしにアクセスしてみたらMTUが1374だと表示された。

「なんかおかしくない?(意訳)」とかブラウザに表示されていた。確かに。自分はルータにフレッツ光接続時に案内されたMTU値である1454を設定しているつもりだった。

再度ルータの設定を確認してみたけど確かに1454に設定されていた。なぜだろう、と考える前に、そもそもMTUについてよく理解していない事に気づき、あたらめて調べてみることにした。

Ethernetフレーム

まずLAN回線であるEthernetについて理解しておく必要があった。ネットワークスペシャリストの資格を取った時に覚えたはずだけどすっかり忘れてた。

Ethernetフレームは最大で1518バイト。それにプリアンブルという8バイトの物理ヘッダがつく。

1518バイトの内訳は、Ethernetヘッダが14バイト(宛先MAC:6、送信元MAC:6、タイプ:2)と4バイトのファイルチェックシーケンスがつき残りがデータ部。

データ部は最大1500バイトまでとなる。この中には上位の階層のヘッダも含まれる。例えばTCPで通信する際は、IPヘッダとTCPヘッダがともに20バイトあるので、実際のデータの最大値は1460バイトとなる。

現実世界ではPPPoEでデータをやり取りすることが多い。この場合はIPヘッダの前にさらにPPPoEヘッダが6バイト、PPPヘッダが2バイト入る。その分取り扱えるデータ量が減り1452バイトとなる。

ちなみに規格によりフレームサイズの最小値も決められており、それは64バイトとなっている。これに満たない場合は空のデータが挿入される。これはコリジョンを不都合なく検知するためらしい。

MTU/MSS

MTUやMSSの説明にPDUという言葉が含まれていることがあるので、先にPDUという言葉が意味する内容を確認する。PDUとはProtocol Data Unitの略でひとまとまりのデータを意味する。

OSIの階層によりPDUの呼称はおおむね決まっていて、EthernetやPPPが所属する第2階層ではフレーム、IPが所属する第3階層ではパケット、TCP/UDPが所属する第4階層ではセグメントと呼ぶ。

MTUは、Maximun Transmission Unitの略で、ネットワークにおいて1度の転送で送信できるデータの最大値のことをいう。(PDUの最大値となる)

MTU値は通信メディアやプロトコルによって違う。Ethernet環境でいえば1500(Ethenetのデータ部最大長)、PPPoE環境なら1492(Ehternetデータ最大長からさらにPPPoEヘッダを差し引いた分)となる。

MSSはMaximum Segment Sizeの略でTCPにおける1セグメントで転送可能なデータ最大サイズを指す。セグメントなので第4階層で考える。

例えば先のTCP通信におけるPPPoEフレームでは、1492のデータ部の中に20バイトのIPヘッダと20バイトのTCPヘッダがある。このデータが第4階層にまで到達した際、使えるデータ領域の最大サイズはIPとTCPヘッダ分をさし引いた1452バイトとなるので、MSSは1452となる。

MTUの制限を超えるとどうなるか

IPv4の世界ではフラグメンテーションと呼ばれる機構により、最大転送サイズを超えたパケットは分割される。これが発生するとデータ送信の効率は落ちる。

IPv6では通過できる経路を探す(最大転送サイズは経路により違うので)が、基本的にはフラグメンテーションを行わない。

フラグメンテーションが起きるとファイアウォールに引っかかってデータが正常に通信できないこともある。

MTUの自動調整

MTUはルータやOSに値を設定できるが、ICMPプロトコルの「Path MTU Discovery」によりMTUが自動決定されることもある。

Path MTU Discoveryプロトコルは経路上の最小MTUを検出して送信元へ送る。送信元はその情報を元にMTUを調整する。これはICMPプロトコルが稼働していないと機能しない。

OS上での確認と修正

MTUはネットワークインターフェース毎に設定されている。

Windowsでそれを確認する場合はコマンドプロンプトから次のコマンドを実行する。

netsh interface ipv4 show interface

変更する場合は、先のコマンドで表示されたインターフェスインデックスを指定して行う。例えば、インターフェースインデックスが10で、MTUを1444にしたいの場合は次のようにする。

netsh interface ipv4 set interface 10 mtu=1444

linux(Debian)の場合は次の方法で確認できる。こちらはネットワークインタフェース名を指定して変更を行う。

ip a

例えば、インターフェース名enp1s0のmtuを1400にする場合は次のように指定する。

ip link set dev enp1s0 mtu 1400

最適値の調べ方

Windowsの場合でもLinux(Debian)の場合でも、Pingにフラグメンテーションを禁止してどのサイズまで送信できるかを確認する。

ただし、それぞれの環境でオプションの指定が違う。Windowsでは、フラグメント禁止オプションが-f、サイズ指定オプションが-l。

ping -f -l 1454 www.google.co.jp
...
ping -f -l 1455 www.google.co.jp
...
ping -f -l 1456 www.google.co.jp
...

Linux(Debian)ではフラグメント禁止オプションが-M do、サイズ指定オプションが-s。さらに-cオプションをつけることで試行回数を指定。

ping -s 1425 -M do -c 5 www.google.co.jp
...
ping -s 1426 -M do -c 5 www.google.co.jp
...
ping -s 1427 -M do -c 5 www.google.co.jp
...

どちらの場合も、ICMPヘッダとIPヘッダ分を考慮する必要がある。実際にPingが通った最大サイズ+28(ICMPヘッダ8+IPヘッダ20)が最適MTU値となる。

途中でトンネルを通るとさらにMTUは小さくなる、例えばl2tpでは10バイトのヘッダがある。

異常の原因は?

上記の方法で調べてみたらpingでの通信はサイズを1454に固定した状態でgoogleにも、先のMTU測定再度にも接続可能だった。ということはhttpsの転送経路中にトンネリング等が発生しているのではないかと予想される。


参考にさせていただいたサイト

WikiPedia MTU MSS等
イーサネット(Ethernet)のしくみ(3)

筆者紹介


自分の写真
がーふぁ、とか、ふぃんてっく、とか世の中すっかりハイテクになってしまいました。プログラムのコーディングに触れることもある筆者ですが、自分の作業は硯と筆で文字をかいているみたいな古臭いものだと思っています。 今やこんな風にブログを書くことすらAIにとって代わられそうなほど技術は進んでいます。 生活やビジネスでPCを活用しようとするとき、そんな第一線の技術と比べてしまうとやる気が失せてしまいがちですが、おいしいお惣菜をネットで注文できる時代でも、手作りの味はすたれていません。 提示されたもの(アプリ)に自分を合わせるのでなく、自分の活動にあったアプリを作る。それがPC活用の基本なんじゃなかと思います。 そんな意見に同調していただける方向けにLinuxのDebianOSをはじめとした基本無料のアプリの使い方を紹介できたらなと考えています。

広告