385

I've had a bug in our software that occurs when I receive a connection timeout. These errors are very rare (usually when my connection gets dropped by our internal network). How can I generate this kind of effect artificially so I can test our software?

If it matters the app is written in C++/MFC using CAsyncSocket classes.

Edit:

I've tried using a non-existent host, and I get the socket error:

WSAEINVAL (10022) Invalid argument

My next attempt was to use Alexander's suggestion of connecting to a different port, e.g. 81 (on my own server though). That worked great. Exactly the same as a dropped connection (60 second wait, then error). Thank you!

Kevin Burke
  • 61,194
  • 76
  • 188
  • 305
Mark Ingram
  • 71,849
  • 51
  • 176
  • 230
  • Hi Mark, I tried solution that work for you but what I'm receiving is **#503** (Service Unavailable.). Isn't should be one of these, **#504** (Gateway Timeout), **#599** (Network connect timeout error), **#598** (Network read timeout error). – CoDe Apr 05 '19 at 12:08
  • Do you want a connect timeout, or a read timeout? – user207421 May 11 '21 at 00:11

22 Answers22

538

Connect to a non-routable IP address, such as 10.255.255.1.

emu
  • 5,397
  • 1
  • 16
  • 2
  • 13
    Idem, and I guess this is a better answer since google.com:81 might be reachable one day. – Gui13 Jan 27 '12 at 15:00
  • 173
    ... and because sending random packets to other people's servers from your unit tests is rude. – Glenn Maynard Oct 07 '12 at 20:45
  • 15
    This won't always work. For instance, with Python's `urllib`, this will return a 'No route to host' exception. FYI – Mike Shultz Feb 22 '13 at 22:35
  • May be it isn't the most universal but the simplest solution! – Konstantin Smolyanin Aug 31 '13 at 13:16
  • 3
    In Java you get "Connection timed out" – Alex Jun 12 '14 at 08:36
  • 2
    This is an elegant solution. Its rude to hit other people's/company's servers for testing, just like you won't like to be called by wrong numbers by someone testing their phone system. – zeeshan Apr 09 '15 at 15:16
  • 10
    10.0.0.0 , 10.255.255.255, 172.16.0.0, 172.31.255.255, 192.168.0.0 ,192.168.255.255 all these are non-routable. – rajesh_kw Jul 23 '15 at 07:49
  • 2
    In java8 you get java.net.NoRouteToHostException: No route to host – Andrés Oviedo Apr 27 '16 at 11:37
  • 1
    @rajesh_kw When I tested an XMLHttpRequest in Node.js, connections to `10.0.0.0` and `10.255.255.255` fired an EACCES error rather than timing out. `10.255.255.1`, `172.16.0.0`, `172.31.255.255`, `192.168.0.0`, and `192.168.255.255` did timeout, however. – Jamie Birch Jun 20 '17 at 11:43
  • 6
    The "No route to host" error mentioned by @FHI generally appears in two conditions: (a) when you try connecting to a non-reachable host in your local LAN (meaning, it doesn't answer ARP queries so it's basically a "ARP timeout"). And (b) when a router returns the corresponding ICMP error. The first case happens if you are in the same subnet as the private IP you test. The second case if a router doesn't know how to route your packet to its destination, but in some cases they just drop the packet without sending the ICMP error. – Ale Aug 01 '17 at 08:06
386

Connect to an existing host but to a port that is blocked by the firewall that simply drops TCP SYN packets. For example, www.google.com:81.

Alexander
  • 9,302
  • 2
  • 26
  • 22
  • 6
    This answer is simple and works just like @emu's answer below. I understand this answer didn't intend to suggest using google.com:81 but the point here is to use a different port that is blocked. So you can always use :. – James Selvakumar Aug 14 '14 at 03:58
  • 19
    Unless its your own server, its rude to hit other servers for your testing. Use a civilized solution like the one emu mentioned below, by hitting a non-routable IP address like 10.255.255.1, or setup a virtual server of your own for testing purposes. – zeeshan Apr 09 '15 at 15:19
  • 2
    I think that Google may have blocked this port. When I test this with Chrome, I just "Server not available." When I use @emu's trick below, the connection hangs as expected. Am I missing something? – entpnerd Dec 09 '15 at 21:48
  • The OP says he connected to port 81 *on his own server* and got the timeout. That worked for me too. emu's solution gave me me an UnknownHostException on Android. – Barry Fruitman Feb 26 '16 at 23:39
  • 3
    This will give a connection refused not timeout . – Mehdi Dec 08 '17 at 15:51
  • What in case of localhost + a well known service such as LDAP ? I've learned that the windows firewall would never block localhost connections. – Herve Mutombo May 08 '19 at 18:03
  • For connection timeout use this: http://example.com:81 – A. Denis Jun 24 '21 at 07:06
  • 1
    I agree with @zeeshan, we are living in a civilized world, instead of choking someone others server, we need to choke our own server. – Shobhit Walia Oct 07 '21 at 12:31
  • This is really brilliant and simple, Focusing on `blocked by the firewall that simply drops TCP SYN packets` meaning you can attach random port to any host and in most cases it will timeout since that port doesn't exist – Harsh Gundecha Nov 04 '22 at 05:21
122

Plenty of good answers but the cleanest solution seems to be this service

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

You can configure the timeout duration (up to 230 seconds) and eventual return code.

Der_Meister
  • 4,771
  • 2
  • 46
  • 53
AndyTheEntity
  • 3,396
  • 1
  • 22
  • 19
  • 5
    this is exactly what I was looking for. Great service, will add it to my bookmarks – Bond Jerome Sep 14 '21 at 19:05
  • 1
    Just a little addendum that you probably need to use status code `200` instead, i.e. `https://httpstat.us/200?sleep=60000`, 'cause the delay didn't seem quite to kick-in for me when using `504` :) – Glenn Mohammad Nov 03 '22 at 15:07
  • As I understand this request is generating the read timeout, not the connection timeout? – Max Dec 23 '22 at 02:42
  • 1
    @Max I havent checked, but it'd make the most sense since a connection would have to be established for the request to be made (and therefore for the server to know how long to delay) – TheTechRobo the Nerd Dec 23 '22 at 15:56
65

If you are on a unix machine, you can start a port listening using netcat:

nc -l 8099

Then, modify you service to call whatever it usually does to that port e.g. http://localhost:8099/some/sort/of/endpoint

Then, your service will open the connection and write data, but will never get a response, and so will give you a Read Time Out (rather than Connection Refused)

Tom Chamberlain
  • 2,955
  • 20
  • 24
  • 2
    It's usefull since you can see whatever data your application is pushing. You could check if your application is asking for a response. – Paul Aug 18 '16 at 07:55
  • This is true for navigating to some sort of endpoint, as mentioned, but if I try to connect some other way it quickly gives a connection refused, which is not the behavior I am trying to mock right now. – AlanSE Jun 28 '17 at 20:32
  • @AlanSE - what other way do you mean? You can have anything after the port number; netcat won't care as it has nothing to handle any URLs – Tom Chamberlain Jun 29 '17 at 09:39
  • @TomChamberlain Oh wait, I might know what I was doing wrong. I am trying to simulate a ssh connection timeout. So I am giving it localhost, port 8099, but previously I didn't give a username, so if I just put in something `ssh alanse@localhost -p 8099`, it looks like that does it. – AlanSE Jun 29 '17 at 11:56
  • 12
    To test a connection timeout at the socket level, freeze the nc process with a `kill -STOP ` (or just CTRL-Z it without putting in background). The system will act as if the server was running, but wait for the server to accept the connection, resulting in a connection timeout (errno 110). – philant May 30 '18 at 12:39
  • @TomChamberlain I have tried this and it give me 503. Isn't this ConnectionTimeout rather ReadTimeout ?? – CoDe Apr 05 '19 at 09:41
  • @CoDe no - connection time out means don’t even use netcat to start a listener just connect to any random port and it won’t go through. Maybe you have a firewall in between your netcat and calling service or bound to different Ethernet adapters – Tom Chamberlain Apr 06 '19 at 19:19
  • @TomChamberlain. **1)** but then it is responding 5XX series which mean some Server side error. **2)** Also I check with random URL but that is also providing 503 only. – CoDe Apr 07 '19 at 23:57
  • Sorry @CoDe - not too sure on your setup. A HTTP container like Tomcat would have to be running to craft a HTTP 5XX response - netcat isn't at the HTTP protocol level and wouldn't even know how to respond with a http code, it just sucks in the traffic in its use above. Maybe you're going through a proxy, but it doesn't sound like you're hitting nc. – Tom Chamberlain Apr 08 '19 at 13:12
  • This solution is applicable when you want to test response timeout and not connection timeout, both are different. Choose based on the scenario you are testing for. @TomChamberlain – stebak Aug 23 '19 at 10:24
  • That is quite right @KBJ - think someone has mentioned above how to freeze the PID to get it to do a Connection Timeout if necessary – Tom Chamberlain Aug 29 '19 at 10:07
  • this is better than the other solutions because libraries (at least python requests) throw a Timeout exception instead of a ConnectionError (which I get eg. with google.com:81) – Daniel Pinyol Mar 03 '20 at 16:05
49

The following URL always gives a timeout, and combines the best of @Alexander and @Emu's answers above:

http://example.com:81

Using example.com:81 is an improvement on Alexander's answer because example.com is reserved by the DNS standard, so it will always be unreachable, unlike google.com:81, which may change if Google feels like it. Also, because example.com is defined to be unreachable, you won't be flooding Google's servers.

I'd say it's an improvement over @emu's answer because it's a lot easier to remember.

speedplane
  • 15,673
  • 16
  • 86
  • 138
  • 2
    currently I see `example.com` resolving to 93.184.216.34, and actually serves a short HTML explaining it's an example domain... port 81 still doesn't respond. – Beni Cherniavsky-Paskin Apr 24 '17 at 16:33
  • 1
    The question is really whether example.com is supposed to be used in that way. Only if they make it officially free to be flooded with test packets is this domain better than any other commercial domain. Using domains for such purpose without permission is unethical, to say the least, if not illegal, because it's costing someone money to handle these packets. Consider using `httpstat.us` as @AndyTheEntity pointed out in his answer. – Manuel May 04 '20 at 01:09
  • @Manuel You're missing the point... `example.com` is not a commercial domain, it's one of the few domain names that's explicitly specified as being unusable. No one can own `example.com` and DNS routers know that it never routes to a real address. So it's not costing anyone server time, there is nothing wrong with using it – speedplane May 13 '20 at 15:17
  • 2
    @speedplane The IANA owns the domain by regulation and maintains a web server providing a web page explaining the purpose of `example.com`. There is infrastructure behind the domain, hence every request it is costing the IANA money. The permissible use is referenced in RFC 2606 and RFC 6761, you are not free to use the domains for whatever purpose you like, like `flodding` them instead of another server, as you mention. Your claim that `example.com is defined to be unreachable` is incorrect, it is reachable. Port 81 is unreachable now, but where is that defined to be guaranteed in the future? – Manuel May 13 '20 at 15:47
  • The RFC you point to specifically allows for DNS testing. They recommend you use a `.test` top level domain, rather than `example.com`, but these domains were clearly setup for this purpose. Yes, it might cost the IANA a bit of money, but this is a service that they provide. Our DNS fees are paying for it. – speedplane May 13 '20 at 23:16
  • Works perfect with error code of curl 28. Google:81 give curl 7 instead, so example.com is better. – A. Denis Jun 24 '21 at 07:04
21
  • 10.0.0.0
  • 10.255.255.255
  • 172.16.0.0
  • 172.31.255.255
  • 192.168.0.0
  • 192.168.255.255

All these are non-routable.

Wai Ha Lee
  • 8,598
  • 83
  • 57
  • 92
rajesh_kw
  • 1,572
  • 16
  • 14
  • 6
    (As I've commented on the accepted answer) When I tested an XMLHttpRequest in Node.js, connections to `10.0.0.0` and `10.255.255.255` fired an EACCES error rather than timing out. `10.255.255.1`, `172.16.0.0`, `172.31.255.255`, `192.168.0.0`, and `192.168.255.255` did timeout, however. – Jamie Birch Jun 20 '17 at 11:44
  • @JamieBirch Can it be that you were within the network 10.0.0.0/8 when you tested? Or that your router was aware of such a network, either because it was directly connected to it or had a policy that forbids routing to it? In all these cases you would get an explicit error an no timeout. – Mecki Jul 13 '20 at 17:30
  • These may not be viable if your codebase blocks them for security reasons because they are private networks, loopback addresses. https://en.wikipedia.org/wiki/Private_network https://www.webopedia.com/TERM/A/APIPA.html – user1821961 Feb 10 '21 at 16:29
  • 192.168.0.0 gives me ENETUNREACH, not a timeout. – UpTheCreek Nov 18 '21 at 14:08
16

You can use the Python REPL to simulate a timeout while receiving data (i.e. after a connection has been established successfully). Nothing but a standard Python installation is needed.

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

Now it waits for an incoming connection. Connect whatever you want to test to localhost:9000. When you do, Python will accept the connection and accept() will return it. Unless you send any data through the clientsocket, the caller's socket should time out during the next recv().

Henrik Heimbuerger
  • 9,924
  • 6
  • 56
  • 69
11

I would like to point everybody's attention to mitmproxy.

With a config (taken from their examples) of 200:b@100:dr you'll get a connection that randomly drops.

zb226
  • 9,586
  • 6
  • 49
  • 79
amenthes
  • 3,117
  • 1
  • 32
  • 38
  • 2
    Not same as a timeout – dentarg Dec 08 '16 at 12:21
  • 2
    I would like to point out that the edit by @zb226 is not _really_ helpful in this case. while it is true that pathod (what I recommended seven years ago) is now part of mitmproxy, this post makes no sense in its current form. I could not find documentation on how a similar thing is achievable with mitmproxy, so I'm leaving this comment for anyone who wonders how that's supposed to work. – amenthes Jun 09 '21 at 11:06
  • @amenthes well, at least it made you aware of that fact :) – zb226 Jun 09 '21 at 11:16
8

How about a software solution:

Install SSH server on the application server. Then, use socket tunnel to create a link between your local port and the remote port on the application server. You can use ssh client tools to do so. Have your client application connect to your mapped local port instead. Then, you can break the socket tunnel at will to simulate the connection timeout.

stoneboy
  • 109
  • 1
  • 3
6

If you want to use an active connection you can also use http://httpbin.org/delay/#, where # is the time you want their server to wait before sending a response. As long as your timeout is shorter than the delay ... should simulate the effect. I've successfully used it with the python requests package.

You may want to modify your request if you're sending anything sensitive - no idea what happens to the data sent to them.

RoHS4U
  • 178
  • 1
  • 7
3

There are services available which allow you to artificially create origin timeouts by calling an API where you specify how long the server will take to respond. Server Timeout on macgyver is an example of such a service.

For example if you wanted to test a request that takes 15 seconds to respond you would simply make a post request to the macgyver API.

JSON Payload:

{
    "timeout_length": 15000
}

API Response (After 15 seconds):

{
    "response": "ok"
}

Server Timeout program on macgyver
https://askmacgyver.com/explore/program/server-timeout/3U4s6g6u

Timothy Moody
  • 479
  • 1
  • 7
  • 9
1

You might install Microsoft Loopback driver that will create a separate interface for you. Then you can connect on it to some service of yours (your own host). Then in Network Connections you can disable/enable such interface...

Marcin Gil
  • 68,043
  • 8
  • 59
  • 60
1

Despite it isn't completely clear which one the OP wants to test: there's a difference between attempting a connection to a non-existent host/port and a timeout of an already established connection. I would go with Rob and wait until the connection is working and then pull the cable. Or - for convenience - have a virtual machine working as the test server (with bridged networking) and just deactivating the virtual network interface once the connection is established.

1

The technique I use frequently to simulate a random connection timeout is to use ssh local port forwarding.

ssh -L 12345:realserver.com:80 localhost

This will forward traffic on localhost:12345 to realserver.com:80 You can loop this around in your own local machine as well, if you want:

ssh -L 12345:localhost:8080 localhost

So you can point your application at your localhost and custom port, and the traffic will get routed to the target host:port. Then you can exit out of this shell (you may also need to ctrl+c the shell after you exit) and it will kill the forwarding which causes your app to see a connection loss.

jdi
  • 90,542
  • 19
  • 167
  • 203
  • 1
    A connection loss is not a timeout. – user207421 May 11 '21 at 00:15
  • @user207421 that depends on the application and what it perceives. If the application has already established a connection and then you stop the tunnel, if the client doesn't receive a proper close then it may keep waiting on a request until a timeout is reached. – jdi May 12 '21 at 01:09
0

There are a couple of tactics I've used in the past to simulate networking issues;

  1. Pull out the network cable
  2. Switch off the switch (ideally with the switch that the computer is plugged into still being powered so the machine maintains it's "network connection") between your machine and the "target" machine
  3. Run firewall software on the target machine that silently drops received data

One of these ideas might give you some means of artifically generating the scenario you need

Rob
  • 45,296
  • 24
  • 122
  • 150
0

Depending on what firewall software you have installed/available, you should be able to block the outgoing port and depending on how your firewall is setup it should just drop the connection request packet. No connection request, no connection, timeout ensues. This would probably work better if it was implemented at a router level (they tend to drop packets instead of sending resets, or whatever the equivalent is for the situation) but there's bound to be a software package that'd do the trick too.

Matthew Scharley
  • 127,823
  • 52
  • 194
  • 222
0

I had issues along the same lines you do. In order to test the software behavior, I just unplugged the network cable at the appropriate time. I had to set a break-point right before I wanted to unplug the cable.

If I were doing it again, I'd put a switch (a normally closed momentary push button one) in a network cable.

If the physical disconnect causes a different behavior, you could connect your computer to a cheap hub and put the switch I mentioned above between your hub and the main network.

-- EDIT -- In many cases you'll need the network connection working until you get to a certain point in your program, THEN you'll want to disconnect using one of the many suggestions offered.

Brad Bruce
  • 7,638
  • 3
  • 39
  • 60
0

The easiest thing would be to drop your connection using CurrPorts.

However, in order to unit test your exception handling code, perhaps you should consider abstracting your network connection code, and write a stub, mock or decorator which throws exceptions on demand. You will then be able to test the application error-handling logic without having to actually use the network.

Matt Howells
  • 40,310
  • 20
  • 83
  • 102
  • With CurrPorts, I seem to only be able to close the connection (which causes the next `recv()` to fail immediately), but could not find a way to simulate a timeout (i.e. no more data is transferred, but the connection stays open). – Henrik Heimbuerger Apr 16 '13 at 21:56
  • I appreciated this answer for suggesting a unit test that mocks connection exceptions on demand. – Danny Bullis Jul 19 '18 at 19:17
0

For me easiest way was adding static route on office router based on destination network. Just route traffic to some unresponsive host (e.g. your computer) and you will get request timeout.

Best thing for me was that static route can be managed over web interface and enabled/disabled easily.

Ivan Marjanovic
  • 979
  • 1
  • 9
  • 15
0

Another option is standing up a local endpoint that returns a delayed response. You could do this with a few lines of Python:

from flask import Flask
from time import sleep

app = Flask(__name__)

@app.route('/delayed', methods = ['POST'])
def delayed_request():
    sleep(120) # delay response by 120 seconds
    return {"msg": "completed"}

app.run(port = 5000)

To test it:

curl --request POST http://localhost:5000/delayed

Note that this requires installing Flask as a dependency (pip install flask).

Andrew Puglionesi
  • 945
  • 1
  • 11
  • 16
-1

You can try to connect to one of well-known Web sites on a port that may not be available from outside - 200 for example. Most of firewalls work in DROP mode and it will simulate a timeout for you.

Dmitry Khalatov
  • 4,313
  • 3
  • 33
  • 39
-2

Plug in your network cable into a switch which has no other connection/cables. That should work imho.

GHad
  • 9,611
  • 6
  • 34
  • 40