Tcp retransmit via curl and netcat

curlnetcattcp

I'm trying to setup iptables to cause realistic network failures between docker containers. On the server, I run both netcat -lk 1234 and an Erlang cowboy server. On the client I run clients:

  • echo blah | netcat myserver 1234
  • curl myserver/xyz

Initially, these work ok, there's evidence of client-server communications. Next, I introduce iptables DROP rule on client's OUTPUT.

  • iptables -A OUTPUT -j DROP
  • echo blah | netcat myserver 1234
  • curl myserver/xyz

Both netcat and curl communications don't get through, until I remove the DROP rule, at which point they recover seamlessly!

Finally I repeat the above, but before the remove the DROP rule, I ctrl-c the client executables. Upon removing the DROP rule, I observe no evience of server receiving client's requests.

My conclusion is that the netat/curl client must be attempting to re-transmit indefinitely? Shouldn't I eventually expect a failure? Btw, same thing happens when with other clients, eg. Erlang http/websocket_client.

Best Answer

Yes, TCP attempts to establish a reliable connection over an unreliable network, so it is tolerant to some degree of packet loss. The sender would keep retrying sending its data, until it gets an ACK from the receiver, or until it times out and decides that the connection is lost.

According to this post, on Linux the default timeout when sending data is just over 2 minutes.

(If neither endpoint is sending data, they might not discover that the connection is broken at all, unless they are configured to send TCP keepalive messages. However, TCP keepalive messages are sent after 2 hours of inactivity by default.)

Related Topic