Up | English MTU, RWIN ──TCP/IP パラメータの変更 作成: 2007-12-03
更新: 2007-12-03


http://www.no-problem.org/mandana/rwin.html

    はじめに

    ADSL や CATV などの所謂「ブロードバンド」が一般化して、常時高速接続が当たり前になってきています。しかし私たちが使っているコンピュータがネットワークとやり取りするパケットのサイズをどのように決めているかによって、せっかくの高速接続がそのパフォーマンスを十分に発揮していないケースがあります。


    GUI を具えたアプリケーション

    RMAC というアプリケーションが公開されました。GUI で様々なパラメータを変更できるもので、非常に便利だと思います。
    「オプション」タブで「起動時に値を常に変更するようにする」というチェックボックスをオンにすると、設定した値が起動スクリプトに書き込まれ、以下で説明している項目を自動的に設定できるようになります。

    システム標準のコマンド

    インターフェースの設定は /sbin/ifconfig、カーネルのチューンは /usr/sbin/sysctl です。
    細かい使い方については man ページで大概のことはカバーされています。

    MacOS X のデフォルトの値では MTU=1500、RWIN=32768 になっています。

    自分のコンピュータのパラメータがどうなっているか、ということについては、SpeedGuide.net のページにある TCP/IP Analyzer で知ることができます。アクセスするだけで値を返してくれるので便利です。

    自分のコンピュータの値を変更したい場合、まず ifconfig で自分のコンピュータのインターフェースを調べます。

    % ifconfig -a lo0: flags=8049<UP,LOOPBACK,RUNNING,MULTICAST> mtu 16384 inet 127.0.0.1 netmask 0xff000000 inet6 ::1 prefixlen 128 inet6 fe80::1%lo0 prefixlen 64 scopeid 0x1 gif0: flags=8010<POINTOPOINT,MULTICAST> mtu 1280 stf0: flags=0<> mtu 1280 en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500 inet 202.252.166.167 netmask 0xffffff00 broadcast 202.252.166.255 ether 00:03:93:ca:cb:c2 media: autoselect (100baseTX <full-duplex>) status: active supported media: none autoselect 10baseT/UTP <half-duplex> 10baseT/UTP <full-duplex> 10baseT/UTP <full-duplex,hw-loopback> 100baseTX <half-duplex> 100baseTX <full-duplex> 100baseTX <full-duplex,hw-loopback> 1000baseT <full-duplex> 1000baseT <full-duplex,hw-loopback> 1000baseT <full-duplex,flow-control> 1000baseT <full-duplex,flow-control,hw-loopback> fw0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 4078 lladdr 00:03:93:ff:fe:ca:cb:c2 media: autoselect <full-duplex> status: inactive supported media: autoselect <full-duplex>

    これで Ethernet インターフェースが en0 であることがわかります。そこで

    sudo ifconfig en0 mtu 1460

    などとすることによってインターフェースの MTU を変更することができます (1460 という値は適当です。自分の環境に応じて適宜変更します)。

    一方 RWIN についてですが、これは sysctl で変更します。sysctl では色々なパラメータを設定することができます。たとえば

    % sudo sysctl -w net.inet.tcp.rfc1323=1
    Password:
    net.inet.tcp.rfc1323: 0 -> 1

    などとすることによって、RWIN のスケールファクタを変更することができます。
    端的には RWIN の値をより大きくとれるようになる他、Timestamp などの拡張 TCP ヘッダを付加することになります。

    では、ここで問題の RWIN 値、つまり Receive Window Space を変更するにはどうするかというと、

    % sudo sysctl -w net.inet.tcp.recvspace=64240
    net.inet.tcp.recvspace: 32768 -> 64240

    などとします。sysctl で値を指定すると、どのように変更されたかを返してくれているのがわかります。

    この他、udp の recvspace なども同様に変更することができます。 このときにどのような値を設定すればよいか、という点についてはまだよくわからないというところが多く、正直さほど劇的な効果があるわけでもありません。

    一般的には、RWIN は MSS (MTU ー 40) の整数倍が適切であるとされていて、たとえば MTU=1500 であれば RWIN = (1500 ー 40) × 44=64240 あたりが妥当ではないかと思われますが、ここに拡張ヘッダが消費する数ビットがからんできたりもしますので、それぞれの環境に応じた試行錯誤が必要になってくるゆえんでもあります。

    起動時に自動的に設定する

    起動スクリプトの編集

    前節で示した sysctl で値の変更は確かに可能なのですが、再起動するとデフォルトに戻ってしまいます。そこで起動時に自動的に設定する方法がないかを考えてみます。
    MacOS X では、起動時のさまざまなパラメータの設定を /etc/rc および /System/Library/StartupItems/SystemTuning/SystemTunig といったシェルスクリプトから自動的にコマンドを実行することによって行っています。したがって、これらのファイルに sysctl で設定したい項目を書き込んでしまえばいいということになります。
    たとえば /System/Library/StartupItems/SystemTuning/SystemTunig の末尾に

    sysctl -w net.inet.tcp.rfc1323=1
    sysctl -w net.inet.tcp.recvspace=64240
    

    などと書き込んでしまえばおっけーです。

    起動項目への追加

    しかしこの方法は、本来システムだけが利用するファイルをユーザが書き換えることになり、何らかのトラブルの原因になる可能性がないとはいえません。*BSD の流儀でも余り推奨されていません。
    では MacOS X で安全な手段は、というと、/Library フォルダに StartupItems というフォルダを作ると、その中にある項目が起動時に実行されるという仕組みがあります。 (RMAC は、設定内容にこの StartupItem を利用している旨ドキュメントに明記してあります)。 ので、/Library/StartupItems/SetRWIN というフォルダを作成し (これはユーザ権限で可能です) そこにシェルスクリプトを置けばいい、ということになります。
    ただし MacOS X では、シェルスクリプトを実行する際の初期設定を plist という拡張子のついた XML 書類で指定するのが普通です。そんなのわからないや、と私も思ったのですが、親切な方がちゃんとそれをつくってくれています。ありみかさとみさん作成になる「起動時に RWIN を設定する Startup Item」がそれです:


    例えば私は以下のようにしています。

    sysctl -w net.inet.tcp.rfc1323=1
    sysctl -w net.inet.tcp.sendspace=32768
    sysctl -w net.inet.tcp.recvspace=64240
    sysctl -w net.inet.udp.recvspace=166400
    sysctl -w net.inet.raw.recvspace=8192

    ありみかさんによるこの起動項目にはJapanese.lproj がありますので、起動時にちゃんと「RWIN サイズを設定中」というメッセージが一瞬表示されます。カコイイ!

    おわりに

    現状で私が把握している TCP パラメータの変更や設定の方法はこれくらいです。おそらく近い将来 IPNetTuner のような詳細な設定を GUI から可能にするアプリケーションが出てくるとは思いますが、現状ここに述べたような方法で設定が可能です。

    (追記)

    RMAC を使えば以上説明してきたようなことは BSD なコマンドに触ることなく可能になります。現状では RMAC を使うのがもっとも安全で簡単な方法であろうと思います。このようなアプリケーションを作ってくださった Hi6 さんに感謝。