Why would connect() give EADDRNOTAVAIL?

Viewed 34274

I have in my application a failure that arose which does not seem to be reproducible. I have a TCP socket connection which failed and the application tried to reconnect it. In the second call to connect() attempting to reconnect, I got an error result with errno == EADDRNOTAVAIL which the man page for connect() says means: "The specified address is not available from the local machine."

Looking at the call to connect(), the second argument appears to be the address to which the error is referring to, but as I understand it, this argument is the TCP socket address of the remote host, so I am confused about the man page referring to the local machine. Is it that this address to the remote TCP socket host is not available from my local machine? If so, why would this be? It had to have succeeded calling connect() the first time before the connection failed and it attempted to reconnect and got this error. The arguments to connect() were the same both times.

Would this error be a transient one which, if I had tried calling connect again might have gone away if I waited long enough? If not, how should I try to recover from this failure?

5 Answers

I got this issue. I got it resolve by enabling tcp timestamp.

Root cause:

  1. After connection close, Connections will go in TIME_WAIT state for some time.

  2. During this state if any new connections comes with same IP and PORT, if SO_REUSEADDR is not provided during socket creation then socket bind() will fail with error EADDRINUSE.

  3. But even though after providing SO_REUSEADDR also sockect connect() may fail with error EADDRNOTAVAIL if tcp timestamp is not enable on both side.

Solution: Please enable tcp timestamp on both side client and server.

echo 1 > /proc/sys/net/ipv4/tcp_timestamps

Reason to enable tcp_timestamp:

When we enable tcp_tw_reuse, sockets in TIME_WAIT state can be used before they expire, and the kernel will try to make sure that there is no collision regarding TCP sequence numbers. If we enable tcp_timestamps, it will make sure that those collisions cannot happen. However, we need TCP timestamps to be enabled on both ends. See the definition of tcp_twsk_unique for the gory details.

reference: https://serverfault.com/questions/342741/what-are-the-ramifications-of-setting-tcp-tw-recycle-reuse-to-1

Related