Créer artificiellement une erreur de dépassement de délai de connexion

291

J'ai eu un bogue dans notre logiciel qui se produit lorsque je reçois un délai de connexion. Ces erreurs sont très rares (généralement lorsque ma connexion est interrompue par notre réseau interne). Comment générer artificiellement ce type d'effet pour tester notre logiciel?

Si cela est important, l'application est écrite en C ++ / MFC à l'aide des classes CAsyncSocket.

Éditer:

J'ai essayé d'utiliser un hôte inexistant et j'obtiens l'erreur de socket:

WSAEINVAL (10022) Argument non valide

Ma prochaine tentative a été d'utiliser la suggestion d' Alexander de se connecter à un autre port, par exemple 81 (sur mon propre serveur cependant). Cela a très bien fonctionné. Exactement la même chose qu'une connexion interrompue (60 secondes d'attente, puis erreur). Je vous remercie!

Mark Ingram
la source
Salut Mark, j'ai essayé une solution qui fonctionne pour vous mais ce que je reçois est le # 503 (Service non disponible.). Ne devrait pas être l'un d'entre eux, # 504 ( Délai d'expiration de la passerelle), # 599 (Erreur de délai d'expiration de la connexion réseau), # 598 (Erreur d'expiration du délai de lecture du réseau).
CoDe

Réponses:

297

Connectez-vous à un hôte existant mais à un port bloqué par le pare-feu qui supprime simplement les paquets TCP SYN. Par exemple, www.google.com:81.

Alexandre
la source
6
Cette réponse est simple et fonctionne exactement comme la réponse de @ emu ci-dessous. Je comprends que cette réponse n'avait pas l'intention de suggérer d'utiliser google.com:81 mais le point ici est d'utiliser un port différent qui est bloqué. Vous pouvez donc toujours utiliser <your-own-ip>: <blocked-port>.
James Selvakumar
6
À moins que ce ne soit votre propre serveur, il est impoli de frapper d'autres serveurs pour vos tests. Utilisez une solution civilisée comme celle émue mentionnée ci-dessous, en frappant une adresse IP non routable comme 10.255.255.1, ou configurez votre propre serveur virtuel à des fins de test.
zeeshan
2
Je pense que Google a peut-être bloqué ce port. Lorsque je teste cela avec Chrome, je dis simplement "Serveur non disponible". Lorsque j'utilise l'astuce de @ emu ci-dessous, la connexion se bloque comme prévu. Suis-je en train de manquer quelque chose?
entpnerd
L'OP dit qu'il s'est connecté au port 81 sur son propre serveur et a obtenu le délai d'expiration. Cela a aussi fonctionné pour moi. La solution d'emu m'a donné une UnknownHostException sur Android.
Barry Fruitman
2
Cela donnera une connexion refusée et non un délai d'attente.
Mehdi
425

Connectez-vous à une adresse IP non routable, telle que 10.255.255.1.

émeu
la source
12
Idem, et je suppose que c'est une meilleure réponse car google.com:81 pourrait être joignable un jour.
Gui13
138
... et parce que l'envoi de paquets aléatoires aux serveurs d'autres personnes à partir de vos tests unitaires est impoli.
Glenn Maynard
15
Cela ne fonctionnera pas toujours. Par exemple, avec Python urllib, cela renverra une exception «Aucune route vers l'hôte». Pour info
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 tous ces éléments ne sont pas routables.
rajesh_kw
4
L'erreur "Pas de route vers l'hôte" mentionnée par @FHI apparaît généralement dans deux conditions: (a) lorsque vous essayez de vous connecter à un hôte non accessible sur votre réseau local (ce qui signifie qu'il ne répond pas aux requêtes ARP, c'est donc essentiellement un " Délai ARP "). Et (b) lorsqu'un routeur renvoie l'erreur ICMP correspondante. Le premier cas se produit si vous êtes dans le même sous-réseau que l'adresse IP privée que vous testez. Le deuxième cas si un routeur ne sait pas comment acheminer votre paquet vers sa destination, mais dans certains cas, il laisse simplement tomber le paquet sans envoyer l'erreur ICMP.
Ale
47

Si vous êtes sur une machine Unix, vous pouvez démarrer une écoute de port en utilisant netcat:

nc -l 8099

Ensuite, modifiez votre service pour appeler tout ce qu'il fait habituellement sur ce port, par exemple http: // localhost: 8099 / some / sort / of / endpoint

Ensuite, votre service ouvrira la connexion et écrira des données, mais n'obtiendra jamais de réponse, et vous donnera donc un délai de lecture (plutôt que la connexion refusée)

Tom Chamberlain
la source
1
C'est utile car vous pouvez voir toutes les données que votre application pousse. Vous pouvez vérifier si votre candidature demande une réponse.
Paul
Cela est vrai pour la navigation vers une sorte de point de terminaison, comme mentionné, mais si j'essaie de me connecter d'une autre manière, cela donne rapidement une connexion refusée, ce qui n'est pas le comportement que j'essaie de me moquer en ce moment.
AlanSE
@AlanSE - de quelle autre façon parlez-vous? Vous pouvez avoir n'importe quoi après le numéro de port; netcat s'en fiche car il n'a rien pour gérer les URL
Tom Chamberlain
@ TomChamberlain Oh attendez, je sais peut-être ce que je faisais mal. J'essaie de simuler un délai d'expiration de connexion ssh. Je lui donne donc localhost, le port 8099, mais auparavant je ne donnais pas de nom d'utilisateur, donc si je viens de mettre quelque chose ssh alanse@localhost -p 8099, il semble que cela le fasse.
AlanSE
7
Pour tester un délai d'expiration de connexion au niveau du socket, gelez le processus nc avec un kill -STOP <pid>(ou simplement CTRL-Z sans le mettre en arrière-plan). Le système agira comme si le serveur était en cours d'exécution, mais attendez que le serveur accepte la connexion, ce qui entraîne un délai de connexion (errno 110).
philant
27

L'URL suivante donne toujours un délai d'expiration et combine le meilleur des réponses @Alexander et @ Emu ci-dessus:

http://example.com:81

L'utilisation example.com:81est une amélioration de la réponse d'Alexander car example.com est réservé par la norme DNS, il sera donc toujours inaccessible, contrairement à google.com:81ce qui peut changer si Google en a envie. De plus, comme il example.comest défini comme inaccessible, vous n'inonderez pas les serveurs de Google.

Je dirais que c'est une amélioration par rapport à la réponse de @ emu car c'est beaucoup plus facile à retenir.

speedplane
la source
2
actuellement, je vois la example.comrésolution de 93.184.216.34, et sert en fait un court HTML expliquant qu'il s'agit d'un exemple de domaine ... le port 81 ne répond toujours pas.
Beni Cherniavsky-Paskin
La question est vraiment de savoir si example.com est censé être utilisé de cette manière. Ce n'est que s'ils rendent officiellement libre d'être inondé de paquets de test que ce domaine est meilleur que tout autre domaine commercial. L'utilisation de domaines à cette fin sans autorisation est pour le moins contraire à l'éthique, sinon illégale, car cela coûte de l'argent à quelqu'un pour gérer ces paquets. Envisagez d'utiliser httpstat.uscomme @AndyTheEntity a souligné dans sa réponse.
Manuel
@Manuel Vous manquez le point ... example.comn'est pas un domaine commercial, c'est l'un des rares noms de domaine qui est explicitement spécifié comme inutilisable. Personne ne peut posséder example.comet les routeurs DNS savent qu'il ne route jamais vers une adresse réelle. Donc, cela ne coûte du temps à personne, il n'y a rien de mal à l'utiliser
speedplane
@speedplane L'IANA est propriétaire du domaine par règlement et gère un serveur Web fournissant une page Web expliquant le but de example.com. Il y a une infrastructure derrière le domaine, donc chaque demande coûte de l'argent à l'IANA. L'utilisation autorisée est référencée dans les RFC 2606 et RFC 6761, vous n'êtes pas libre d'utiliser les domaines pour le but que vous aimez, comme floddingeux au lieu d'un autre serveur, comme vous le mentionnez. Votre réclamation qui example.com is defined to be unreachableest incorrecte, elle est accessible. Le port 81 est inaccessible maintenant, mais où est-il défini pour être garanti à l'avenir?
Manuel
Le RFC que vous pointez permet spécifiquement des tests DNS. Ils vous recommandent d'utiliser un .testdomaine de premier niveau plutôt que example.com, mais ces domaines ont été clairement configurés à cet effet. Oui, cela pourrait coûter un peu d'argent à l'IANA, mais c'est un service qu'ils fournissent. Nos frais DNS le paient.
speedplane
23

Beaucoup de bonnes réponses mais la solution la plus propre semble être ce service

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

Vous pouvez configurer la durée de temporisation (jusqu'à 230 secondes) et le code retour éventuel.

AndyTheEntity
la source
16

Vous pouvez utiliser Python REPL pour simuler un délai d'attente lors de la réception de données (c'est-à-dire après qu'une connexion a été établie avec succès). Rien d'autre qu'une installation Python standard n'est nécessaire.

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

Maintenant, il attend une connexion entrante. Connectez ce que vous voulez tester localhost:9000. Lorsque vous le faites, Python acceptera la connexion et la accept()renverra. Sauf si vous envoyez des données via le clientsocket, la prise de l'appelant devrait expirer au cours de la prochaine recv().

Henrik Heimbuerger
la source
Ne fonctionne pas pour moi; quelque chose manque. Peut-être s.listen(5)avant s.accept()?
bmaupin
@bmaupin Cela semble raisonnable, je suppose que j'ai juste oublié cela. Modifié maintenant (mais avec une file d'attente de 0), merci!
Henrik Heimbuerger
1
J'ai pu mettre l'écoute et accepter les parties en while True:boucle, et cela semble faire une belle destination de timeout à frapper pour les tests.
AlanSE
2
Cela fonctionne, mais il donne une erreur de "délai d'expiration de lecture", qui n'est pas la même que "délai d'expiration de connexion"
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

Tous ces éléments ne sont pas routables.

rajesh_kw
la source
2
(Comme je l'ai commenté sur la réponse acceptée) Lorsque j'ai testé un XMLHttpRequest dans Node.js, les connexions à 10.0.0.0et ont 10.255.255.255déclenché une erreur EACCES plutôt que de se terminer. 10.255.255.1, 172.16.0.0, 172.31.255.255, 192.168.0.0Et a 192.168.255.255fait délai d' attente, cependant.
Jamie Birch
9

Je voudrais attirer l'attention de tout le monde sur pathod

Avec une configuration (tirée de leurs exemples) de 200:b@100:drvous obtiendrez une connexion qui tombe aléatoirement.

amenthes
la source
1
Pas la même chose qu'un temps mort
dentarg
8

Que diriez-vous d'une solution logicielle:

Installez le serveur SSH sur le serveur d'applications. Ensuite, utilisez le tunnel de socket pour créer un lien entre votre port local et le port distant sur le serveur d'applications. Pour ce faire, vous pouvez utiliser les outils client ssh. Demandez à votre application client de se connecter à votre port local mappé à la place. Ensuite, vous pouvez interrompre le tunnel de socket à volonté pour simuler le délai de connexion.

Stoneboy
la source
4

Si vous souhaitez utiliser une connexion active, vous pouvez également utiliser http://httpbin.org/delay/# , où # est la durée pendant laquelle votre serveur doit attendre avant d'envoyer une réponse. Tant que votre délai d'attente est plus court que le délai ... devrait simuler l'effet. Je l'ai utilisé avec succès avec le paquet de requêtes python.

Vous voudrez peut-être modifier votre demande si vous envoyez quelque chose de sensible - aucune idée de ce qui arrive aux données qui leur sont envoyées.

RoHS4U
la source
Max 10 secondes cependant (si vous entrez un nombre plus élevé, il répondra après 10 secondes)
Harry Wood
2

Il existe des services disponibles qui vous permettent de créer artificiellement des délais d'expiration d'origine en appelant une API dans laquelle vous spécifiez le délai de réponse du serveur. Le délai d'expiration du serveur sur macgyver est un exemple d'un tel service.

Par exemple, si vous souhaitez tester une demande qui prend 15 secondes pour répondre, vous devrez simplement envoyer une demande à l'API macgyver.

Charge utile JSON:

{
    "timeout_length": 15000
}

Réponse de l'API (après 15 secondes):

{
    "response": "ok"
}

Programme d'expiration du serveur sur macgyver
https://askmacgyver.com/explore/program/server-timeout/3U4s6g6u

Timothy Moody
la source
1

Vous pouvez installer le pilote Microsoft Loopback qui créera une interface distincte pour vous. Ensuite, vous pouvez vous y connecter à un de vos services (votre propre hôte). Ensuite, dans Connexions réseau, vous pouvez désactiver / activer une telle interface ...

Marcin Gil
la source
1

Bien qu'il ne soit pas complètement clair lequel l'OP veut tester: il y a une différence entre tenter une connexion à un hôte / port inexistant et un timeout d'une connexion déjà établie. J'irais avec Rob et j'attendrais que la connexion fonctionne, puis je tirerais le câble. Ou - pour plus de commodité - disposer d'une machine virtuelle fonctionnant comme serveur de test (avec mise en réseau pontée) et désactivant simplement l'interface réseau virtuelle une fois la connexion établie.


la source
1

La technique que j'utilise fréquemment pour simuler un délai de connexion aléatoire consiste à utiliser la redirection de port local ssh.

ssh -L 12345:realserver.com:80 localhost

Cela transmettra le trafic sur localhost: 12345 à realserver.com:80 Vous pouvez également le boucler sur votre propre machine locale, si vous le souhaitez:

ssh -L 12345:localhost:8080 localhost

Ainsi, vous pouvez pointer votre application vers votre port local et votre port personnalisé, et le trafic sera acheminé vers l'hôte cible: port. Ensuite, vous pouvez quitter ce shell (vous devrez peut-être également ctrl + c le shell après avoir quitté) et cela tuera le transfert qui provoquera une perte de connexion pour votre application.

jdi
la source
0

Branchez votre câble réseau dans un commutateur qui n'a pas d'autre connexion / câbles. Cela devrait fonctionner à mon humble avis.

GHad
la source
0

Il y a quelques tactiques que j'ai utilisées dans le passé pour simuler des problèmes de mise en réseau;

  1. Retirez le câble réseau
  2. Éteignez l'interrupteur (idéalement avec l'interrupteur auquel l'ordinateur est branché toujours sous tension pour que la machine conserve sa "connexion réseau") entre votre machine et la machine "cible"
  3. Exécutez un logiciel de pare-feu sur la machine cible qui supprime silencieusement les données reçues

L'une de ces idées pourrait vous donner des moyens de générer artificiellement le scénario dont vous avez besoin

Rob
la source
0

Selon le logiciel de pare-feu que vous avez installé / disponible, vous devriez pouvoir bloquer le port sortant et selon la configuration de votre pare-feu, il devrait simplement supprimer le paquet de demande de connexion. Aucune demande de connexion, aucune connexion, un délai d'attente s'ensuit. Cela fonctionnerait probablement mieux s'il était implémenté au niveau du routeur (ils ont tendance à laisser tomber les paquets au lieu d'envoyer des réinitialisations, ou quel que soit l'équivalent pour la situation), mais il y a forcément un package logiciel qui ferait l'affaire aussi.

Matthew Scharley
la source
0

La chose la plus simple serait de supprimer votre connexion à l'aide de CurrPorts .

Cependant, afin de tester à l'unité votre code de gestion des exceptions, vous devriez peut-être envisager d'abstraire votre code de connexion réseau et écrire un talon, une maquette ou un décorateur qui lève des exceptions à la demande. Vous pourrez ensuite tester la logique de gestion des erreurs de l'application sans avoir à utiliser réellement le réseau.

Matt Howells
la source
Avec CurrPorts, il me semble que je ne peux que fermer la connexion (ce qui provoque l' recv()échec immédiat du prochain ), mais je n'ai pas pu trouver un moyen de simuler un délai d'expiration (c'est-à-dire qu'aucune autre donnée n'est transférée, mais la connexion reste ouverte).
Henrik Heimbuerger
J'ai apprécié cette réponse pour avoir suggéré un test unitaire qui se moque des exceptions de connexion à la demande.
Danny Bullis
0

J'ai eu des problèmes comme vous. Afin de tester le comportement du logiciel, je viens de débrancher le câble réseau au moment approprié. J'ai dû fixer un point d'arrêt juste avant de vouloir débrancher le câble.

Si je recommençais, je mettrais un interrupteur (un bouton-poussoir momentané normalement fermé) dans un câble réseau.

Si la déconnexion physique provoque un comportement différent, vous pouvez connecter votre ordinateur à un concentrateur bon marché et placer le commutateur que j'ai mentionné ci-dessus entre votre concentrateur et le réseau principal.

- MODIFIER - Dans de nombreux cas, vous aurez besoin que la connexion réseau fonctionne jusqu'à ce que vous arriviez à un certain point de votre programme, PUIS vous voudrez vous déconnecter en utilisant l'une des nombreuses suggestions proposées.

Brad Bruce
la source
0

Pour moi, le moyen le plus simple était d'ajouter un itinéraire statique sur le routeur de bureau en fonction du réseau de destination. Acheminez simplement le trafic vers un hôte qui ne répond pas (par exemple, votre ordinateur) et vous obtiendrez le délai d'expiration de la demande.

La meilleure chose pour moi était que la route statique peut être gérée via l'interface Web et activée / désactivée facilement.

Ivan Marjanovic
la source
-1

Vous pouvez essayer de vous connecter à l'un des sites Web bien connus sur un port qui peut ne pas être disponible de l'extérieur - 200 par exemple. La plupart des pare-feu fonctionnent en mode DROP et ils simuleront un timeout pour vous.

Dmitry Khalatov
la source