人為的に接続タイムアウトエラーを発生させる
-
01-07-2019 - |
質問
ソフトウェアにバグがあり、接続タイムアウトが発生したときに発生します。このようなエラーは非常にまれです (通常は、内部ネットワークによって接続が切断された場合です)。ソフトウェアをテストできるように、この種のエフェクトを人工的に生成するにはどうすればよいですか?
重要な場合、アプリは CAsyncSocket クラスを使用して C++/MFC で記述されます。
編集:
存在しないホストを使用しようとしましたが、ソケット エラーが発生しました。
WSAEINVAL (10022) 引数が無効です
私の次の試みは使用することでした アレクサンダー別のポートに接続するという提案。81 (ただし、自分のサーバー上)。それはうまくいきました。接続が切断された場合とまったく同じです (60 秒待機してからエラーになります)。ありがとう!
解決
既存のホストに接続しますが、TCP SYN パケットをドロップするだけのファイアウォールによってブロックされているポートに接続します。たとえば、www.google.com:81。
他のヒント
10.255.255.1 などのルーティング不可能な IP アドレスに接続します。
UNIX マシンを使用している場合は、netcat を使用してポート リスニングを開始できます。
nc -l 8099
次に、そのポートに対して通常行うことをすべて呼び出すようにサービスを変更します。 http://localhost:8099/some/sort/of/endpoint
その後、サービスは接続を開いてデータを書き込みますが、応答が得られないため、(接続が拒否されるのではなく) 読み取りタイムアウトが発生します。
次の URL は常にタイムアウトを提供し、上記の @Alexander と @Emu の回答の最良の部分を組み合わせたものです。
使用する example.com:81
example.com は DNS 標準によって予約されているため、常にアクセスできなくなります。 google.com:81
, 、Googleがその気になれば変更される可能性があります。また、なぜなら、 example.com
が到達不能であると定義されている場合、Google のサーバーに負荷がかかることはありません。
@emuの回答よりもはるかに覚えやすいため、これは改善されていると思います。
Python REPL を使用すると、データ受信中のタイムアウトをシミュレートできます (つまり、接続が正常に確立された後)。標準の Python インストール以外は何も必要ありません。
Python 2.7.4 (default, Apr 6 2013, 19:54:46) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
>>> s.bind(('localhost', 9000))
>>> s.listen(0)
>>> (clientsocket, address) = s.accept()
ここで、着信接続を待機します。テストしたいものを何でも接続します localhost:9000
. 。これを実行すると、Python は接続を受け入れ、 accept()
返します。経由でデータを送信しない限り、 clientsocket
, 、呼び出し側のソケットは次の実行中にタイムアウトするはずです。 recv()
.
- 10.0.0.0
- 10.255.255.255
- 172.16.0.0
- 172.31.255.255
- 192.168.0.0
- 192.168.255.255
これらはすべてルーティング不可能です。
皆さんに注目していただきたいのは、 病理
(サンプルから抜粋した) 構成を使用すると、 200:b@100:dr
接続がランダムに切断されます。
ソフトウェア ソリューションについてはどうでしょうか。
アプリケーションサーバーにSSHサーバーをインストールします。次に、ソケット トンネルを使用して、ローカル ポートとアプリケーション サーバー上のリモート ポートの間にリンクを作成します。これを行うには、ssh クライアント ツールを使用できます。代わりに、クライアント アプリケーションをマップされたローカル ポートに接続します。その後、ソケット トンネルを自由に切断して、接続タイムアウトをシミュレートできます。
アクティブな接続を使用したい場合は、以下を使用することもできます http://httpbin.org/delay/#, # は、サーバーが応答を送信するまで待機する時間です。タイムアウトが遅延より短い限り...効果をシミュレートする必要があります。Pythonリクエストパッケージで正常に使用できました。
機密性の高いものを送信する場合、送信されたデータがどうなるかわからない場合は、リクエストを変更することをお勧めします。
サーバーの応答にかかる時間を指定する API を呼び出して、オリジン タイムアウトを人為的に作成できるサービスが利用可能です。macgyver のサーバー タイムアウトは、そのようなサービスの例です。
たとえば、応答に 15 秒かかるリクエストをテストしたい場合は、単純に macgyver API にポストリクエストを作成します。
JSON ペイロード:
{
"timeout_length": 15000
}
API 応答 (15 秒後):
{
"response": "ok"
}
マクガイバーのサーバータイムアウトプログラム
https://askmacgyver.com/explore/program/server-timeout/3U4s6g6u
別のインターフェイスを作成する Microsoft ループバック ドライバーをインストールすることもできます。その後、その上で自分のサービス (自分のホスト) に接続できます。次に、ネットワーク接続で、そのようなインターフェイスを無効/有効にすることができます...
OP がどれをテストしたいのかは完全には明らかではありませんが、存在しないホスト/ポートへの接続を試行することと、すでに確立されている接続がタイムアウトになることには違いがあります。私はロブと一緒に行き、接続が機能するまで待ってからケーブルを抜きます。または、便宜上、仮想マシンをテスト サーバー (ブリッジ ネットワークを使用) として動作させ、接続が確立されたら仮想ネットワーク インターフェイスを非アクティブ化するだけです。
ランダムな接続タイムアウトをシミュレートするために私が頻繁に使用する手法は、ssh ローカル ポート転送を使用することです。
ssh -L 12345:realserver.com:80 localhost
これにより、localhost:12345にトラフィックをrealserver.com:80に転送します。
ssh -L 12345:localhost:8080 localhost
したがって、アプリケーションをローカルホストとカスタム ポートに向けることができ、トラフィックはターゲットのホスト:ポートにルーティングされます。その後、このシェルを終了することができます (終了後にシェルを Ctrl+C にする必要がある場合もあります)。これにより転送が強制終了され、アプリで接続損失が発生します。
他の接続/ケーブルがないスイッチにネットワーク ケーブルを差し込みます。それは私見ではうまくいくはずです。
ネットワークの問題をシミュレートするために私が過去に使用した戦術がいくつかあります。
- ネットワークケーブルを抜きます
- 自分のマシンと「ターゲット」マシンの間のスイッチをオフにします (マシンが「ネットワーク接続」を維持できるように、コンピュータが接続されているスイッチの電源が入っているのが理想的です)。
- 受信したデータをサイレントにドロップするファイアウォール ソフトウェアをターゲット マシン上で実行する
これらのアイデアの 1 つにより、必要なシナリオを人為的に生成する手段が得られるかもしれません。
インストール/利用可能なファイアウォール ソフトウェアに応じて、発信ポートをブロックできるはずです。ファイアウォールの設定方法に応じて、接続要求パケットをドロップするだけです。接続要求がない、接続がない、タイムアウトが発生する。これはルーターレベルで実装されればおそらくよりうまく機能するでしょう(ルーターはリセットを送信する代わりにパケットをドロップする傾向があります、または状況に応じて同等のものは何でも)が、そのトリックを実行するソフトウェアパッケージも必ず存在します。
最も簡単な方法は、次を使用して接続を切断することです 現在のポート.
ただし、例外処理コードを単体テストするには、ネットワーク接続コードを抽象化し、オンデマンドで例外をスローするスタブ、モック、またはデコレーターを作成することを検討する必要があるかもしれません。これにより、実際にネットワークを使用せずにアプリケーションのエラー処理ロジックをテストできるようになります。
私もあなたと同じような問題を抱えていました。ソフトウェアの動作をテストするために、適切なタイミングでネットワーク ケーブルを抜きました。ケーブルを抜く直前にブレークポイントを設定する必要がありました。
もう一度同じことをやるなら、ネットワーク ケーブルにスイッチ (通常は閉じている瞬間的な押しボタンのスイッチ) を挿入するでしょう。
物理的な切断により異なる動作が発生する場合は、コンピュータを安価なハブに接続し、ハブとメイン ネットワークの間に上記のスイッチを置くことができます。
- 編集 - 多くの場合、プログラムの特定のポイントに到達するまでネットワーク接続を動作させる必要があります。その後、提供される多くの提案のいずれかを使用して切断する必要があります。
私にとって最も簡単な方法は、宛先ネットワークに基づいてオフィスのルーターに静的ルートを追加することでした。トラフィックを応答しないホストにルーティングするだけです (例:あなたのコンピュータ)、リクエストタイムアウトが発生します。
私にとって最も良かったのは、静的ルートを Web インターフェイス経由で管理でき、簡単に有効/無効にできることです。
良い答えはたくさんありますが、最もクリーンな解決策は次のとおりです このサービス
http://httpstat.us/504?sleep=60000
タイムアウト期間 (最大 230 秒) と最終的なリターン コードを構成できます。
外部からは利用できない可能性があるポート (たとえば、200) で、既知の Web サイトの 1 つに接続を試みることができます。ほとんどのファイアウォールは DROP モードで動作し、タイムアウトをシミュレートします。