22

For network catastrophe simulations of our server environment, we are looking for a way to intentionally timeout a TCP socket. Are there any simple ways for existing sockets? Also, little C test-case program would be a plus.

We have already tried putting down network interfaces during TCP buffer reading, and reading from disconnected mounted resources (samba).

Out test server is Ubuntu 12.04.4.

er453r
  • 867
  • 2
  • 8
  • 22

2 Answers2

22

To cause an exiting connection to timeout you can use iptables. Just enable a DROP rule on the port you want to disable. So to simulate a timeout for your Samaba server, while an active connection is up, execute the following on the server:

sudo iptables -A INPUT -p tcp --dport 445 -j DROP

The DROP target will not reply with a RST packet or ICMP error to the packet's sender. The client will stop receiving packets from the server and eventually timeout.

Depending on if/how you have iptables configured, you may want to insert the rule higher into the INPUT ruleset.

Creek
  • 5,002
  • 1
  • 22
  • 33
  • Tried this using netcat ( to listen/send data ) and waited forever... no timeout :/ And I can confirm the data was dropped. I even changed `/proc/sys/net/ipv4/tcp_keepalive_time` to a really small number – er453r Jun 12 '14 at 13:51
  • @er453r try enabling verbose output with `ncat -v` to see what exactly `ncat` is doing. It took me 2m7.291s on a vanilla Ubuntu 12.04 install to timeout – Creek Jun 12 '14 at 15:23
  • right - I wasn't sending anything through the socket during that first test. I've finally mastered the timeouts and described them in detail below :) – er453r Jun 13 '14 at 10:29
20

The first answer is correct, but I've discovered how these timeouts work, so you could observe and test them (don't forget to block the port!).

There are 4 most interesting kernel parameters that deal with TCP timeouts:

/proc/sys/net/ipv4/tcp_keepalive_time
/proc/sys/net/ipv4/tcp_keepalive_intvl
/proc/sys/net/ipv4/tcp_keepalive_probes
/proc/sys/net/ipv4/tcp_retries2

Now there are 2 scenarios:

  1. The socket is opened and trying to transmit - then (if there is no response from the other side), system retries tcp_retries2 times. With the default value of retires it takes somewhere over 2 minutes and the socket times out.

  2. The socket is opened and idle - then keepalive limits are interesting. With an idle socket system will wait tcp_keepalive_time seconds, and after that try tcp_keepalive_probes times to send a TCP KEEPALIVE in intervals of tcp_keepalive_intvl seconds. And only after that all failes the socket times out.

er453r
  • 867
  • 2
  • 8
  • 22