Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Cannot assign requested address - possible causes?

Tags:

c

tcp

sockets

errno

I have a program that consists of a master server and distributed slave servers. The slave servers send status updates to the server, and if the server hasn't heard from a specific slave in a fixed period, it marks the slave as down. This is happening consistently.

From inspecting logs, I have found that the slave is only able to send one status update to the server, and then is never able to send another update, always failing on the call to connect() "Cannot assign requested address (99).

Oddly enough, the slave is able to send several other updates to the server, and all of the connections are happening on the same port. It seems that the most common cause of this failure is that connections are left open, but I'm having trouble finding anything left open. Are there other possible explanations?

To clarify, here's how I'm connecting:

struct sockaddr *sa; // parameter
size_t           sa_size; //parameter
int              i = 1;
int              stream;

stream = socket(AF_INET,SOCK_STREAM,0);
setsockopt(stream,SOL_SOCKET,SO_REUSEADDR,&i,sizeof(i));
bindresvport(stream,NULL);
connect(stream,sa,sa_size);

This code is in a function to obtain a connection to another server, and a failure on any of those 4 calls causes the function to fail.

like image 451
dbeer Avatar asked Oct 03 '11 21:10

dbeer


People also ask

What does can't assign requested address mean?

This is happening when the socket that the application is trying to use cannot be assigned or the requested local address could not be assigned.

How to fix java net BindException cannot assign requested address?

BindException: Cannot assign requested address: JVM_Bind. You can try by following program to reproduce this issue, remember, you need admin rights to change /etc/host settings in Windows. Just, correct the mapping, or add 127.0. 0.1 against the localhost to resolve this issue.

Can t assign requested address connect?

This error is not specifically for macOS, it tells you that the provided IP is not available for your network or it's already in use. You should provide an assigned IP from your networks, you could execute hostname -I (or equivalent) to check them.


4 Answers

It turns out that the problem really was that the address was busy - the busyness was caused by some other problems in how we are handling network communications. Your inputs have helped me figure this out. Thank you.

EDIT: to be specific, the problems in handling our network communications were that these status updates would be constantly re-sent if the first failed. It was only a matter of time until we had every distributed slave trying to send its status update at the same time, which was over-saturating our network.

like image 82
dbeer Avatar answered Oct 04 '22 00:10

dbeer


Maybe SO_REUSEADDR helps here? http://www.unixguide.net/network/socketfaq/4.5.shtml

like image 26
Michel Avatar answered Oct 02 '22 00:10

Michel


this is just a shot in the dark : when you call connect without a bind first, the system allocates your local port, and if you have multiple threads connecting and disconnecting it could possibly try to allocate a port already in use. the kernel source file inet_connection_sock.c hints at this condition. just as an experiment try doing a bind to a local port first, making sure each bind/connect uses a different local port number.

like image 31
dmh2000 Avatar answered Oct 02 '22 00:10

dmh2000


Okay, my problem wasn't the port, but the binding address. My server has an internal address (10.0.0.4) and an external address (52.175.223.XX). When I tried connecting with:

$sock = @stream_socket_server('tcp://52.175.223.XX:123', $errNo, $errStr, STREAM_SERVER_BIND|STREAM_SERVER_LISTEN);

It failed because the local socket was 10.0.0.4 and not the external 52.175.223.XX. You can checkout the local available interfaces with sudo ifconfig.

like image 33
Dallas Clarke Avatar answered Oct 01 '22 00:10

Dallas Clarke