Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sockets - Using INADDR_ANY on client side

I recently ran into this blog post which describes a TCP server client using libev. The sever uses INADDR_ANY to bind to an interface which is something I'm familiar with. However, I was surprised to see INADDR_ANY in the client code as well. The relevant code on the client code is as follows:

// Create client socket
if( (sd = socket(PF_INET, SOCK_STREAM, 0)) < 0 )
{
  perror("socket error");
  return -1;
}

bzero(&addr, sizeof(addr));

addr.sin_family = AF_INET;
addr.sin_port = htons(PORT_NO);
addr.sin_addr.s_addr = htonl(INADDR_ANY);

// Connect to server socket
if(connect(sd, (struct sockaddr *)&addr, sizeof addr) < 0)
{
  perror("Connect error");
  return -1;
}

Specifically I'm interesed in the line:

addr.sin_addr.s_addr = htonl(INADDR_ANY);

On the server side I understand that INADDR_ANY will bind the port to all available interfaces, but I'm not sure how this makes sense on the client side. In the end, the client will need to connect on a particular interface. Previously I have always specified the IP address or used INADDR_LOOPBACK.

The Linux IP man page doesn't talk about using INADDR_ANY on the client side. I did find another Stack Overflow post here which says that the OP should use INADDR_ANY on the client side, but gives no justification or explanation.

So what is this actually doing? Is it trying all interfaces until it finds one where the port is available for connection? What order does this happen in?

Thanks for your answers!

like image 438
Benjamin Leinweber Avatar asked Mar 13 '14 16:03

Benjamin Leinweber


3 Answers

This is the answer as provided by nos in a comment. If nos comes back and posts it as an answer, I will mark nos' post as the answer and delete this one.

INADDR_ANY is normally defined as 0. That is the IP address 0.0.0.0. RFC 1122 says that means "This host on this network". The linux IP stack seems to just route this to the loopback interface. (e.g. try ping 0.0.0.0 or even just ping 0). I'd say the author made a typo, and should have used INADDR_LOOPBACK.

like image 80
Benjamin Leinweber Avatar answered Oct 15 '22 17:10

Benjamin Leinweber


It seems like your question is not really about "client-side", but about bind vs connect.

INADDR_ANY can be sensibly used with bind on both client and server. Using it with connect() is pointless and should cause a connection failure.

like image 33
Ben Voigt Avatar answered Oct 15 '22 16:10

Ben Voigt


There is an old BSD convention that connecting to INADDR_ANY means you want to connect to the loopback network. The linux network code explicitly supports this (search for INADDR_ANY in this file). I have no idea what other OSes do or don't support it.

like image 1
Jon Avatar answered Oct 15 '22 15:10

Jon