Windows上でローカル開発環境上のサーバーを使ったWEBシステムの開発やデバッグを行う際に、パケットの遅延/ロス/帯域制限/切断といった不安定なネットワーク環境をエミュレーションした検証を行う方法。
WEBシステム開発のみならず、ソケットを使ったローレベルなパケット制御を行うプログラム開発に便利そうです。
方法
WinDivert(Windowsのユーザーモードパケットインターセプトライブラリ)を利用してパケットに対して様々な操作を行えるOSSツールのclumsy
を利用する。
使い方
公式サイトからダウンロードしたZIPファイルを解凍してclumsy.exe
を起動すると以下のような画面が表示されます(管理者権限が必要)。
Filtering
ではPresets
のプリセット設定を選択するか、以下のネットワークのフィルタリング項目を組み合わせて処理対象パケットの条件を定義することができます。
詳細なフィルタ記述方法については、WinDivertのドキュメントを参照してください。
フィルタリング項目 | 説明 |
---|---|
loopback | ループバックパケットかどうか |
outbound | アウトバウンド(送信)パケットかどうか |
inbound | インバウンド(受信)パケットかどうか |
ifIdx | インターフェースインデックス |
subIfIdx | サブインターフェースインデックス |
ip | IPv4パケットかどうか |
ipv6 | IPv6パケットかどうか |
icmp | ICMP(インターネット制御メッセージプロトコル)パケットかどうか |
icmpv6 | ICMPv6パケットかどうか |
tcp | TCP(伝送制御プロトコル)パケットかどうか |
udp | UDP(ユーザーデータグラムプロトコル)パケットかどうか |
ip.* | IPv4の詳細フィールド(DIVERT_IPHDR参照) |
ipv6.* | IPv6の詳細フィールド(DIVERT_IPV6HDR参照) |
icmp.* | ICMPの詳細フィールド(DIVERT_ICMPHDR参照) |
icmpv6.* | ICMPv6の詳細フィールド(DIVERT_ICMPV6HDR参照) |
tcp.* | TCPの詳細フィールド(DIVERT_TCPHDR参照) |
tcp.PayloadLength | TCPペイロードの長さ |
udp.* | UDPの詳細フィールド(DIVERT_UDPHDR参照) |
udp.PayloadLength | UDPペイロードの長さ |
フィルタリング項目はブール式の形で表され、以下の条件式が使えます。
演算子 | 説明 |
---|---|
&& または and | 論理積 |
|| または or | 論理和 |
! または not | 否定 |
!= | 等しくない |
< | より小さい |
> | より大きい |
<= | 以下 |
>= | 以上 |
Functions
ではエミュレーションする機能の選択、および設定を行います。
機能名 | 説明 |
---|---|
Lag(遅延) | 指定された時間だけパケットの送信を遅らせ、高レイテンシ状態をシミュレートします。 |
Drop(ドロップ) | 設定した確率でネットワークパケットを無作為に破棄し、不安定な状況を作り出します。 |
Throttle(制限) | パケットの流量を制限し、帯域が限られた状況をエミュレートします。 |
Duplicate(重複) | パケットを複製し、同じパケットを複数回送信します。 |
Out Of Order(順序不同) | パケットの順序を意図的に入れ替え、順序保証されていない環境をシミュレートします。 |
Tamper(改ざん) | パケットの内容を意図的に変更し、データ転送中の改ざん影響を調査します。 |
Set TCP RST(TCP RST設定) | TCP接続に対してRSTパケットを送信し、接続を強制的に切断します。 |
Bandwidth(帯域幅) | ネットワークの帯域幅を制限し、低帯域幅環境でのアプリケーションパフォーマンスを評価します。 |
上記設定後にStart
を押下するとパケットのフィルタリングが開始されます。
ちなみにclumsyをループバック環境で利用する場合、解決困難な以下の技術的制約に留意する必要があるとのことです。
ループバックの入力パケットはキャプチャまたは再注入できません。
考えてみれば、コンピューター自身にパケットを送信するときに、入力パケットか出力パケットかを判別するのは本当に難しいです。実際、基盤となるWindows Filtering Platformは、すべてのループバックパケットを出力パケットとして分類しているようです。ループバックパケットを処理するときは、フィルターに「入力」を含めないことが重要です。また、コンピューターには127.0.0.1以外のIP、例えばルーターによって割り当てられたイントラネットIPが存在するかもしれません。これらもループバックパケットと見なされます。ループバックパケットは2回キャプチャされます。
入力ループバックパケットがないため、すべてのループバックパケットは出力とみなされます。したがって、clumsyはそれらを2回処理します:1回目は送信時、2回目は受信時です。単純な例としては、フィルターを「出力のみ」とし、500msの遅延を適用した場合、localhostにpingを送ると1000msの遅延が発生します。これは、宛先ポートなどを指定することで回避できますが、パラメータを設定する際にはこの点を心に留めて注意する方が簡単です。入力パケットのキャプチャが常に機能するわけではありません。
前述のように、ループバックの入力パケットは再注入できません。問題は、宛先IPがあなたのコンピューターのものでない場合でも、時折、いくつかのパケットが入力パケットとして分類されることがあるということです。これは非ループバックパケットにのみ影響します。localhost上のみで作業している場合は問題ありません。将来のリリースの目標は、この原因を診断し、解決策を提供することです。プロセスに基づいてフィルタリングすることはできません
システム全体のネットワークキャプチャは機能として挙げられていますが、実際には堅牢な解決策を提供する簡単な方法はありません。システム全体のネットワークキャプチャは機能として挙げられていますが、実際には堅牢な解決策を提供する簡単な方法はありません。
参考ウェブサイトなど
以上です。