Erstellen Sie künstlich einen Verbindungszeitüberschreitungsfehler

291

Ich habe einen Fehler in unserer Software, der auftritt, wenn ich ein Verbindungszeitlimit erhalte. Diese Fehler sind sehr selten (normalerweise, wenn meine Verbindung von unserem internen Netzwerk getrennt wird). Wie kann ich diese Art von Effekt künstlich erzeugen, um unsere Software zu testen?

Wenn es darauf ankommt, wird die App mithilfe von CAsyncSocket-Klassen in C ++ / MFC geschrieben.

Bearbeiten:

Ich habe versucht, einen nicht vorhandenen Host zu verwenden, und erhalte den Socket-Fehler:

WSAEINVAL (10022) Ungültiges Argument

Mein nächster Versuch war, Alexanders Vorschlag zu verwenden, eine Verbindung zu einem anderen Port herzustellen, z. B. 81 (allerdings auf meinem eigenen Server). Das hat super geklappt. Genau das gleiche wie eine unterbrochene Verbindung (60 Sekunden warten, dann Fehler). Danke dir!

Mark Ingram
quelle
Hallo Markus, ich habe eine Lösung ausprobiert, die für Sie funktioniert, aber ich erhalte die Nummer 503 (Service nicht verfügbar). Dies sollte nicht einer der folgenden Werte sein: # 504 (Gateway Timeout), # 599 (Fehler beim Timeout der Netzwerkverbindung), # 598 (Fehler beim Lesen des Netzwerks).
CoDe

Antworten:

297

Stellen Sie eine Verbindung zu einem vorhandenen Host her, aber zu einem Port, der von der Firewall blockiert wird, die einfach TCP-SYN-Pakete verwirft. Zum Beispiel www.google.com:81.

Alexander
quelle
6
Diese Antwort ist einfach und funktioniert genau wie die Antwort von @ emu unten. Ich verstehe, dass diese Antwort nicht die Verwendung von google.com:81 vorschlagen wollte, aber hier geht es darum, einen anderen Port zu verwenden, der blockiert ist. Sie können also immer <Ihr-Eigen-IP> verwenden: <Blockierter-Port>.
James Selvakumar
6
Wenn es nicht Ihr eigener Server ist, ist es unhöflich, andere Server für Ihre Tests zu treffen. Verwenden Sie eine zivilisierte Lösung wie die unten erwähnte Emu, indem Sie eine nicht routbare IP-Adresse wie 10.255.255.1 eingeben, oder richten Sie zu Testzwecken einen eigenen virtuellen Server ein.
Zeeshan
2
Ich denke, dass Google diesen Port möglicherweise blockiert hat. Wenn ich dies mit Chrome teste, ist nur "Server nicht verfügbar". Wenn ich den folgenden Trick von @ emu verwende, hängt die Verbindung wie erwartet. Vermisse ich etwas
Entpnerd
Das OP sagt, er habe auf seinem eigenen Server eine Verbindung zu Port 81 hergestellt und das Timeout erhalten. Das hat auch bei mir funktioniert. Die Lösung von emu gab mir eine UnknownHostException für Android.
Barry Fruitman
2
Dies gibt eine Verbindung verweigert nicht Timeout.
Mehdi
425

Stellen Sie eine Verbindung zu einer nicht routbaren IP-Adresse her, z. B. 10.255.255.1.

Emu
quelle
12
Idem, und ich denke, dies ist eine bessere Antwort, da google.com:81 eines Tages erreichbar sein könnte.
Gui13
138
... und weil das Senden von zufälligen Paketen von Ihren Unit-Tests an die Server anderer Leute unhöflich ist.
Glenn Maynard
15
Das wird nicht immer funktionieren. Bei Python wird beispielsweise die urllibAusnahme "Keine Route zum Host" zurückgegeben. Zu Ihrer Information
Mike Shultz
8
10.0.0.0, 10.255.255.255, 172.16.0.0, 172.31.255.255, 192.168.0.0, 192.168.255.255 Alle diese sind nicht routingfähig.
Rajesh_kw
4
Der von @FHI erwähnte Fehler "Keine Route zum Host" tritt im Allgemeinen unter zwei Bedingungen auf: (a) Wenn Sie versuchen, eine Verbindung zu einem nicht erreichbaren Host in Ihrem lokalen LAN herzustellen (dh, es werden keine ARP-Anfragen beantwortet, es handelt sich also im Grunde genommen um einen " ARP-Timeout "). Und (b) wenn ein Router den entsprechenden ICMP-Fehler zurückgibt. Der erste Fall tritt auf, wenn Sie sich im selben Subnetz wie die von Ihnen getestete private IP befinden. Der zweite Fall, wenn ein Router nicht weiß, wie er Ihr Paket an sein Ziel weiterleiten soll, aber in einigen Fällen das Paket einfach verwirft, ohne den ICMP-Fehler zu senden.
Ale
47

Wenn Sie sich auf einem Unix-Computer befinden, können Sie mit netcat einen Port starten, der überwacht:

nc -l 8099

Ändern Sie dann Ihren Dienst so, dass er alles aufruft, was er normalerweise an diesem Port tut, z. B. http: // localhost: 8099 / some / sort / of / endpoint

Dann öffnet Ihr Dienst die Verbindung und schreibt Daten, erhält jedoch nie eine Antwort und gibt Ihnen eine Lesezeitüberschreitung (anstatt Verbindung verweigert).

Tom Chamberlain
quelle
1
Dies ist nützlich, da Sie sehen können, welche Daten Ihre Anwendung pusht. Sie können überprüfen, ob Ihre Anwendung nach einer Antwort fragt.
Paul
Dies gilt für das Navigieren zu einem Endpunkt, wie bereits erwähnt. Wenn ich jedoch versuche, eine andere Verbindung herzustellen, wird die Verbindung schnell abgelehnt. Dies ist nicht das Verhalten, über das ich mich gerade lustig machen möchte.
AlanSE
@AlanSE - was meinst du anders? Sie können alles nach der Portnummer haben; Netcat ist das egal, da es nichts mit URLs
Tom Chamberlain
@ TomChamberlain Oh warte, ich könnte wissen, was ich falsch gemacht habe. Ich versuche, ein SSH-Verbindungszeitlimit zu simulieren. Also gebe ich es localhost, Port 8099, aber vorher habe ich keinen Benutzernamen angegeben. Wenn ich also nur etwas ssh alanse@localhost -p 8099eingebe, sieht es so aus.
AlanSE
7
Um ein Verbindungszeitlimit auf Socket-Ebene zu testen, frieren Sie den nc-Prozess mit a ein kill -STOP <pid>(oder drücken Sie einfach STRG-Z, ohne Hintergrund zu setzen). Das System verhält sich so, als würde der Server ausgeführt, wartet jedoch darauf, dass der Server die Verbindung akzeptiert, was zu einem Verbindungszeitlimit führt (Errno 110).
Philant
27

Die folgende URL gibt immer eine Zeitüberschreitung an und kombiniert die besten Antworten von @Alexander und @ Emu oben:

http://example.com:81

Die Verwendung example.com:81ist eine Verbesserung gegenüber Alexanders Antwort, da example.com vom DNS-Standard reserviert ist und daher im Gegensatz zu google.com:81Google immer nicht erreichbar ist. Dies kann sich ändern, wenn Google dies wünscht. Da example.comdie Definition nicht erreichbar ist, werden die Server von Google nicht überflutet.

Ich würde sagen, es ist eine Verbesserung gegenüber der Antwort von @ emu, weil es viel einfacher ist, sich daran zu erinnern.

Geschwindigkeitsflugzeug
quelle
2
Derzeit wird eine example.comAuflösung in 93.184.216.34 angezeigt, und es wird ein kurzer HTML-Code bereitgestellt, der erklärt, dass es sich um eine Beispieldomäne handelt. Port 81 antwortet immer noch nicht.
Beni Cherniavsky-Paskin
Die Frage ist wirklich, ob example.com auf diese Weise verwendet werden soll. Nur wenn sie es offiziell kostenlos machen, mit Testpaketen überflutet zu werden, ist diese Domain besser als jede andere kommerzielle Domain. Die Verwendung von Domains für einen solchen Zweck ohne Erlaubnis ist, gelinde gesagt, unethisch, wenn nicht sogar illegal, da die Bearbeitung dieser Pakete jemanden Geld kostet. httpstat.usErwägen Sie die Verwendung als @AndyTheEntity, auf die in seiner Antwort hingewiesen wird.
Manuel
@Manuel Sie verpassen den Punkt ... example.comist keine kommerzielle Domain, sondern einer der wenigen Domainnamen, die ausdrücklich als unbrauchbar angegeben werden. Niemand kann besitzen example.comund DNS-Router wissen, dass sie niemals an eine echte Adresse weitergeleitet werden. Es kostet also niemanden Serverzeit, es ist nichts Falsches daran, es zu benutzen
Speedplane
@speedplane Die IANA besitzt die Domain gemäß den Bestimmungen und unterhält einen Webserver, der eine Webseite bereitstellt, auf der der Zweck von erläutert wird example.com. Hinter der Domain befindet sich eine Infrastruktur, daher kostet jede Anfrage das IANA-Geld. Auf die zulässige Verwendung wird in RFC 2606 und RFC 6761 verwiesen. Es steht Ihnen nicht frei, die Domänen für einen beliebigen Zweck zu verwenden, z. B. floddinganstelle eines anderen Servers, wie Sie bereits erwähnt haben. Ihre Behauptung, example.com is defined to be unreachabledie falsch ist, ist erreichbar. Port 81 ist derzeit nicht erreichbar, aber wo soll dies in Zukunft garantiert werden?
Manuel
Der RFC, auf den Sie verweisen, ermöglicht speziell DNS-Tests. Sie empfehlen .test, anstelle einer Top-Level-Domain eine Domain zu verwenden, example.comaber diese Domains wurden eindeutig für diesen Zweck eingerichtet. Ja, es könnte die IANA ein bisschen Geld kosten, aber dies ist ein Service, den sie anbieten. Unsere DNS-Gebühren zahlen dafür.
Speedplane
23

Viele gute Antworten, aber die sauberste Lösung scheint dieser Service zu sein

http://httpstat.us/504?sleep=60000

Sie können die Timeout-Dauer (bis zu 230 Sekunden) und den eventuellen Rückkehrcode konfigurieren.

AndyTheEntity
quelle
16

Mit Python REPL können Sie eine Zeitüberschreitung beim Empfang von Daten simulieren (dh nachdem eine Verbindung erfolgreich hergestellt wurde). Es wird nur eine Standard-Python-Installation benötigt.

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()

Jetzt wartet es auf eine eingehende Verbindung. Verbinden Sie alles, was Sie testen möchten localhost:9000. Wenn Sie dies tun, akzeptiert Python die Verbindung und accept()gibt sie zurück. Sofern Sie keine Daten über das senden clientsocket, sollte der Socket des Anrufers während des nächsten Zeitlimits ablaufen recv().

Henrik Heimbuerger
quelle
Funktioniert nicht bei mir; etwas fehlt. Vielleicht s.listen(5)vorher s.accept()?
Bmaupin
@bmaupin Das klingt vernünftig, das habe ich wohl einfach vergessen. Bearbeitet es jetzt (jedoch mit einer Backlog-Warteschlange von 0), danke!
Henrik Heimbuerger
1
Ich war in der Lage, das Hören und Akzeptieren von Parts in eine while True:Schleife zu setzen, und das scheint ein schönes, dauerhaftes Timeout-Ziel zu sein, das zum Testen getroffen werden kann.
AlanSE
2
Es funktioniert, aber es gibt "Lese-Timeout" -Fehler, der nicht mit "Verbindungs-Timeout" identisch ist
Timur
13
  • 10.0.0.0
  • 10.255.255.255
  • 172.16.0.0
  • 172.31.255.255
  • 192.168.0.0
  • 192.168.255.255

Alle diese sind nicht routingfähig.

rajesh_kw
quelle
2
(Wie ich die akzeptierte Antwort kommentiert habe) Als ich eine XMLHttpRequest in Node.js getestet habe, haben Verbindungen zu 10.0.0.0und 10.255.255.255einen EACCES-Fehler ausgelöst, anstatt eine Zeitüberschreitung zu verursachen. 10.255.255.1, 172.16.0.0, 172.31.255.255, 192.168.0.0, Und 192.168.255.255tat Timeout jedoch.
Jamie Birch
9

Ich möchte die Aufmerksamkeit aller auf Pathod lenken

Mit einer Konfiguration (aus den Beispielen entnommen) erhalten 200:b@100:drSie eine Verbindung, die zufällig unterbrochen wird.

Amenthes
quelle
1
Nicht dasselbe wie eine Auszeit
dentarg
8

Wie wäre es mit einer Softwarelösung:

Installieren Sie den SSH-Server auf dem Anwendungsserver. Verwenden Sie dann den Socket-Tunnel, um eine Verbindung zwischen Ihrem lokalen Port und dem Remote-Port auf dem Anwendungsserver herzustellen. Sie können dazu ssh-Client-Tools verwenden. Lassen Sie Ihre Client-Anwendung stattdessen eine Verbindung zu Ihrem zugeordneten lokalen Port herstellen. Anschließend können Sie den Socket-Tunnel nach Belieben unterbrechen, um das Verbindungszeitlimit zu simulieren.

Stoneboy
quelle
4

Wenn Sie eine aktive Verbindung verwenden möchten, können Sie auch http://httpbin.org/delay/# verwenden , wobei # die Zeit ist, zu der der Server warten soll, bevor eine Antwort gesendet wird. Solange Ihr Timeout kürzer als die Verzögerung ist ... sollte der Effekt simuliert werden. Ich habe es erfolgreich mit dem Python-Anforderungspaket verwendet.

Möglicherweise möchten Sie Ihre Anfrage ändern, wenn Sie vertrauliche Informationen senden - keine Ahnung, was mit den an sie gesendeten Daten geschieht.

RoHS4U
quelle
Maximal 10 Sekunden (Wenn Sie eine höhere Zahl eingeben, reagiert diese nach 10 Sekunden)
Harry Wood
2

Es stehen Dienste zur Verfügung, mit denen Sie künstlich Zeitüberschreitungen beim Ursprung erstellen können, indem Sie eine API aufrufen, in der Sie angeben, wie lange der Server für die Antwort benötigt. Das Server-Timeout unter Macgyver ist ein Beispiel für einen solchen Dienst.

Wenn Sie beispielsweise eine Anfrage testen möchten, deren Beantwortung 15 Sekunden dauert, stellen Sie einfach eine Post-Anfrage an die Macgyver-API.

JSON-Nutzlast:

{
    "timeout_length": 15000
}

API-Antwort (nach 15 Sekunden):

{
    "response": "ok"
}

Server Timeout-Programm auf Macgyver
https://askmacgyver.com/explore/program/server-timeout/3U4s6g6u

Timothy Moody
quelle
1

Möglicherweise installieren Sie den Microsoft Loopback-Treiber, der eine separate Schnittstelle für Sie erstellt. Dann können Sie eine Verbindung zu einem Ihrer Dienste (Ihrem eigenen Host) herstellen. Dann können Sie in Netzwerkverbindungen eine solche Schnittstelle deaktivieren / aktivieren ...

Marcin Gil
quelle
1

Obwohl nicht ganz klar ist, welche das OP testen möchte: Es gibt einen Unterschied zwischen dem Versuch, eine Verbindung zu einem nicht vorhandenen Host / Port herzustellen, und einem Timeout einer bereits hergestellten Verbindung. Ich würde mit Rob gehen und warten, bis die Verbindung funktioniert und dann das Kabel ziehen. Oder lassen Sie der Einfachheit halber eine virtuelle Maschine als Testserver (mit überbrücktem Netzwerk) arbeiten und die virtuelle Netzwerkschnittstelle einfach deaktivieren, sobald die Verbindung hergestellt ist.


quelle
1

Die Technik, die ich häufig verwende, um ein zufälliges Verbindungszeitlimit zu simulieren, ist die Verwendung der lokalen ssh-Portweiterleitung.

ssh -L 12345:realserver.com:80 localhost

Dadurch wird der Datenverkehr auf localhost: 12345 an realserver.com:80 weitergeleitet. Sie können dies auch auf Ihrem eigenen lokalen Computer durchlaufen, wenn Sie möchten:

ssh -L 12345:localhost:8080 localhost

Sie können Ihre Anwendung also auf Ihren lokalen Host und Ihren benutzerdefinierten Port verweisen, und der Datenverkehr wird an den Zielhost weitergeleitet: port. Anschließend können Sie diese Shell verlassen (möglicherweise müssen Sie die Shell nach dem Beenden auch mit Strg + C drücken), wodurch die Weiterleitung abgebrochen wird und Ihre App einen Verbindungsverlust feststellt.

jdi
quelle
0

Stecken Sie Ihr Netzwerkkabel in einen Switch, der keine anderen Verbindungen / Kabel hat. Das sollte imho funktionieren.

GHad
quelle
0

Es gibt einige Taktiken, mit denen ich in der Vergangenheit Netzwerkprobleme simuliert habe.

  1. Ziehen Sie das Netzwerkkabel heraus
  2. Schalten Sie den Switch (idealerweise mit dem Switch, an den der Computer angeschlossen ist, der noch mit Strom versorgt wird, damit der Computer seine "Netzwerkverbindung" beibehält) zwischen Ihrem Computer und dem "Ziel" -Computer aus
  3. Führen Sie auf dem Zielcomputer eine Firewall-Software aus, die empfangene Daten stillschweigend löscht

Eine dieser Ideen gibt Ihnen möglicherweise die Möglichkeit, das von Ihnen benötigte Szenario künstlich zu generieren

rauben
quelle
0

Abhängig davon, welche Firewall-Software Sie installiert / verfügbar haben, sollten Sie in der Lage sein, den ausgehenden Port zu blockieren, und je nachdem, wie Ihre Firewall eingerichtet ist, sollte das Verbindungsanforderungspaket einfach verworfen werden. Es erfolgt keine Verbindungsanforderung, keine Verbindung, Zeitüberschreitung. Dies würde wahrscheinlich besser funktionieren, wenn es auf Routerebene implementiert würde (sie neigen dazu, Pakete zu verwerfen, anstatt Resets zu senden, oder was auch immer das Äquivalent für die Situation ist), aber es muss ein Softwarepaket geben, das auch den Trick macht.

Matthew Scharley
quelle
0

Am einfachsten ist es, die Verbindung mit CurrPorts zu trennen .

Um Ihren Code für die Ausnahmebehandlung zu testen, sollten Sie möglicherweise in Betracht ziehen, Ihren Netzwerkverbindungscode zu abstrahieren und einen Stub, Mock oder Decorator zu schreiben, der bei Bedarf Ausnahmen auslöst. Sie können dann die Anwendungsfehlerbehandlungslogik testen, ohne das Netzwerk tatsächlich verwenden zu müssen.

Matt Howells
quelle
Mit CurrPorts kann ich anscheinend nur die Verbindung schließen (was dazu führt, dass die nächste recv()sofort fehlschlägt), aber keine Möglichkeit finden, eine Zeitüberschreitung zu simulieren (dh es werden keine Daten mehr übertragen, aber die Verbindung bleibt offen).
Henrik Heimbuerger
Ich habe diese Antwort geschätzt, weil ich einen Komponententest vorgeschlagen habe, der Verbindungsausnahmen bei Bedarf verspottet.
Danny Bullis
0

Ich hatte Probleme in der gleichen Richtung wie Sie. Um das Softwareverhalten zu testen, habe ich das Netzwerkkabel zum richtigen Zeitpunkt abgezogen. Ich musste einen Haltepunkt setzen, bevor ich das Kabel abziehen wollte.

Wenn ich es noch einmal machen würde, würde ich einen Schalter (einen normalerweise geschlossenen momentanen Druckknopf) in ein Netzwerkkabel stecken.

Wenn die physische Trennung ein anderes Verhalten verursacht, können Sie Ihren Computer an einen billigen Hub anschließen und den oben genannten Switch zwischen Ihren Hub und das Hauptnetzwerk stellen.

- BEARBEITEN - In vielen Fällen muss die Netzwerkverbindung funktionieren, bis Sie zu einem bestimmten Punkt in Ihrem Programm gelangen. DANN möchten Sie die Verbindung mit einem der vielen angebotenen Vorschläge trennen.

Brad Bruce
quelle
0

Für mich war es am einfachsten, eine statische Route auf dem Office-Router basierend auf dem Zielnetzwerk hinzuzufügen. Leiten Sie den Datenverkehr einfach an einen nicht reagierenden Host (z. B. Ihren Computer) weiter, und Sie erhalten ein Zeitlimit für die Anforderung.

Das Beste für mich war, dass die statische Route über die Weboberfläche verwaltet und einfach aktiviert / deaktiviert werden kann.

Ivan Marjanovic
quelle
-1

Sie können versuchen, eine Verbindung zu einer bekannten Website über einen Port herzustellen, der möglicherweise nicht von außen verfügbar ist, z. B. 200. Die meisten Firewalls arbeiten im DROP-Modus und simulieren eine Zeitüberschreitung für Sie.

Dmitry Khalatov
quelle