![]() 若手部員 宇田くん |
pingコマンドのオプションをいろいろ試していたら,見慣れないエラーが表示されたんだ。オプションを指定しないときは問題がなかったのに,どこが違うんだろうか。 | ||
![]() 若手部員 貴子さん |
そのエラーって,回線が一度にやりとりできる最大サイズに関係するって聞いたことがあるわ。どこまで大きなデータをやりとりできるか実験してみましょう。 |
貴子:宇田くん,何しているの?
宇田:先輩からpingコマンド*には,いろんなオプションがあるって聞いたので試しているんだ。
貴子:面白そうね。私にも教えてよ。
宇田:それが,どうもうまく動かないことがあるんだ。ほら,-fオプションと-lオプションを指定すると,見慣れないエラーが表示されるだろ(図1)。オプションを指定しないときは,問題なく応答が返ってきているのに,変だとは思わない?
貴子:本当だ。初めて見るエラーだわ。ところで,指定したオプションにはどんな意味があるの?
宇田:-fオプションはデータを分割しないでパケットを送信する指定で,-lオプションはそのあとに続く数値でデータ・サイズを指定しているんだ。
貴子:データ・サイズは2000バイトに指定したのね。
宇田:そうだよ。LANではもっと大きなファイルをやりとりすることもあるから,大丈夫だよね。
貴子:もしかしたら,-fオプションで分割禁止にしているからじゃないかしら。回線によってパケットの最大データ・サイズが決まっているって聞いたことがあるわ。たしか,MTU*とかいう値よ。
宇田:そうなのか。じゃあ,貴子さん,もう少し詳しく調べておいてよ。先輩から用事を頼まれていたんだ。
貴子:調子いいわねぇ。
見慣れないエラーが出た理由
pingコマンドには,いろいろなオプションがある。通常,pingコマンドを使うとき,ping IPアドレスのように打ち込んで実行する。オプションを指定するときは,
ping オプション IPアドレスのような書式になる。今回,宇田くんが-fオプションと-lオプションを使って試したのは,
ping -f -l 2000 192.168.0.2のようなコマンド。これは,「IPアドレスが192.168.0.2の端末に対して,2000バイトのデータが入ったpingパケットを分割せずに送信せよ」という意味になる。
ところが,このコマンドを実行すると,「Packet needs to be fragmented but DF set」という見慣れないエラーが表示された。これは,「パケットの分割が必要だが,分割禁止になっている」という意味。つまり,-lオプションで指定したデータ・サイズのパケットは大きすぎて分割しないと回線に流せないのに,-fオプションによって分割が禁止されていたためにエラーが表示されたのである。
回線ごとにMTUが決まっている
宇田:ただいま。貴子さん,調べてみてくれたかな。貴子:仕方がないから調べたわ。MTUっていうのは,イーサネットや無線LANといった伝送規格ごとに決まっているみたいよ。要するに,回線が一度にやりとりできるひとかたまりのデータの最大値よ。イーサネットのMTUは1500バイト*だったわ。
宇田:なるほど。それで-lオプションでデータを2000バイトに指定したとき,エラーになったんだな。それじゃあ,1500で試してみよう。
貴子:どう?
宇田:おかしいな。さっきと同じエラーが表示されたよ。
貴子:変ね。もう少し値を小さくして,1450くらいならどう?
宇田:今度はうまく行った。
貴子:ということは,MTUは1450と1500の間ということね。順番にやってみれば,最大値がわかるはずだわ。試してみてよ。
宇田:何回も同じようなことをやるのは面倒だけど,やってみるよ。
(しばらくして・・・)
宇田:1472は大丈夫だけど,1473だとエラーになったよ(図2)。
貴子:ということは,1472バイトがイーサネットのMTUサイズになるのかしら。でも,本には1500バイトって書いてあったわよ。
pingパケットにはヘッダーが付く
実は,2人の実験結果は正しい。どういうカラクリになのか,確認しておこう。 pingコマンドは,ICMP*というプロトコルを利用している。このとき,イーサネットのデータ部分には,実際のデータのほかにIPヘッダーとICMPヘッダーが加わった形で入る。MTUサイズは,この点を考慮して考える必要がある。つまり図3のように,IPヘッダーは通常20バイト(オプション未使用時),ICMPヘッダーは8バイトなので,イーサネットのMTUが1500バイトだとすると,最大データ・サイズは1500−(20+8)=1472になる*。
宇田:先輩に聞いたら,IPヘッダーやICMPヘッダーの部分を考慮する必要があると教えてくれたよ。計算すると,pingコマンドで指定できる最大データ・サイズは1472バイトになったよ。
貴子:IPヘッダーやICMPヘッダーは,イーサネットから見るとデータの一部ってことなのね。だから,イーサネットのMTUは1500で正しいんだわ。
MTUを変えると速度はどうなる?
宇田:先輩は,「MTUサイズを変えると実効スループットが変わる」とも言っていたよ。今度は,それを実験で確かめてみようよ。貴子:イーサネットのMTUサイズは1500と決まっているでしょう。それを変更できるの?
宇田:Windowsなら,設定情報が書かれているレジストリ*を編集することでMTUサイズを変更できるみたいだよ。
貴子:それなら,やってみましょう。宇田くんはどうなると思う?
宇田:ヘッダーの大きさは一定だから,MTUサイズを小さくすると実際に転送したいデータの割合が小さくなって,スループットが落ちるんじゃないかな。
貴子:私も,そうなると思うわ。でも。MTUサイズを1500バイト以上にできるのかしら。
宇田:規格上は1500バイトと決まっているからダメかも知れないね。とりあえず,実験してみよう。
実験は,パソコンを2台用意して10Mイーサネットでつないだ(図4)。そして,片側をWebサーバーにして,もう1台のパソコンから10Mバイトのファイルをダウンロードする時間を計測した。この実験をクライアント側のパソコンのレジストリを書き換えることでMTUを変えて繰り返した。
では,実験結果を見ていこう。
MTUを小さくすると遅くなる
貴子:MTUサイズを500~2500まで変えたけれど,どれでもファイルはダウンロードできたわね。実験結果を検証してみましょう。宇田:MTUサイズを500,1000,1500と大きくしていくと,ダウンロード速度も向上しているよ。でも,1500以上にしたときは,あまり速くなっていないな(図5)。
貴子:予想は,半分だけ的中していたわけね。でも,どうしてMTUサイズを1500以上にしても速くならなかったのかしら。本当に,1500バイト以上のパケットをやりとりしていた?
宇田:きちんとレジストリは設定したし,エラーも出なかったよ。
貴子:それはそうなんだけれど,やっぱりパケットをキャプチャ*して,やりとりされたパケットを調べてみましょうよ。
MTUサイズが1500バイト以下の場合は,MTUを大きくすればダウンロード速度は向上した。これは,2人の推測にもあったように,MTUサイズが大きいほどヘッダーなどの余分なデータの割合が小さくなり,オーバーヘッドが減るためである。
しかし,1500バイトを超えるMTUサイズに設定したときは,ダウンロード速度にあまり変化がなかった。これは,どうしてなのだろうか。
1500バイト超にはならない
宇田:MTUサイズを2000バイトに設定してダウンロードしたときのパケットをキャプチャしたよ。中身を見てみよう(図6)。貴子:きちんと,ファイルをダウンロードしているみたいね。あ,WebサーバーからテストPCへ送られているパケットのパケット長がずっと1514になっているわ。
宇田:本当だ。MTUサイズを2000バイトにしたんだから,本来ならイーサネットのヘッダーを加えた2014(2000+14)になるはずだよね。
貴子:ということは,レジストリを変更しても実際のMTUは1500バイトのままだったのよ。キャプチャ結果にある1514というのは,イーサネット・ヘッダー分の14バイトを加えた値と一致するから,間違っていないはずよ。
宇田:そうみたいだね。
レジストリでMTUサイズを1500バイト以上に設定しても,実際に流れるデータの最大サイズは1500バイト以上にならなかった。これは,LANカードやカードのドライバ・ソフトの方で,自動的にデータを分割してMTUサイズが1500バイトを超えないように調整したためだと考えられる。
そもそも,1500バイトを超えるデータを一度に流そうとしても,途中のLANスイッチなどの機器*が転送できないので,エラーになるだろう。
寄稿者:ネットワークエンジニア集団 みずおか組●水岡 祥二 NPOアイタック代表理事●出口 雄一 株式会社タケキ IT教育事業部 ●久保 幸夫 情報・通信エンジニア |