A forum for questions and answers about network programming on Linux and all other Unix-like systems

You are not logged in.

#1 2002-07-25 06:48 PM

From: Colombia
Registered: 2002-06-12
Posts: 353

Re: 3.6 - bind() explicitly or let connect() do it?

From Andrew Gierth (andrew@erlenstar.demon.co.uk):

** Let the system choose your client's port number **

The exception to this, is if the server has been written to be picky about what client ports it will allow connections from. Rlogind and rshd are the classic examples. This is usually part of a Unix-specific (and rather weak) authentication scheme; the intent is that the server allows connections only from processes with root privilege. (The weakness in the scheme is that many O/Ss (e.g. MS-DOS) allow anyone to bind any port.)

The rresvport() routine exists to help out clients that are using this scheme. It basically does the equivalent of socket() + bind(), choosing a port number in the range 512..1023.

If the server is not fussy about the client's port number, then don't try and assign it yourself in the client, just let connect() pick it for you.

If, in a client, you use the naive scheme of starting at a fixed port number and calling bind() on consecutive values until it works, then you buy yourself a whole lot of trouble:

The problem is if the server end of your connection does an active close. (E.G. client sends 'QUIT' command to server, server responds by closing the connection). That leaves the client end of the connection in CLOSED state, and the server end in TIME_WAIT state. So after the client exits, there is no trace of the connection on the client end.

Now run the client again. It will pick the same port number, since as far as it can see, it's free. But as soon as it calls connect(), the server finds that you are trying to duplicate an existing connection (although one in TIME_WAIT). It is perfectly entitled to refuse to do this, so you get, I suspect, ECONNREFUSED from connect(). (Some systems may sometimes allow the connection anyway, but you can't rely on it.)

This problem is especially dangerous because it doesn't show up unless the client and server are on different machines. (If they are the same machine, then the client won't pick the same port number as before). So you can get bitten well into the development cycle (if you do what I suspect most people do, and test client & server on the same box initially).

Even if your protocol has the client closing first, there are still ways to produce this problem (e.g. kill the server).

From: Deepak Nagrath
Added on: 2002-06-14 08:41:03

It depends on the type of socket whether the system would
bind a port to a socket on calling of connect system call.
For exampler,IP sockets binds the
port on calling connect system call but in domain of
Unix sockets this is not so.
So the better thing is to explicity bind the socket, with
0 port number. In this case Operating system would allocate
the port number and would bind the address to socket.

- Deepak

From: Rob Seace
Added on: 2002-06-14 09:29:54

Um, what are you talking about? There are no such things
as port numbers in Unix domain sockets! There are only
paths (or abstract identifiers, for unnamed sockets)...

And, there's nothing wrong with letting the bind() happen
implicitly at connect() time, as long as you don't need
to specifically bind to a single IP or port#... There's
no advantage at all in doing your own bind() to INADDR_ANY
and port 0, in that case... (But, I suppose there's no
harm either, if you truly want to do it... It should be
functionally equivalent...)


Board footer

Powered by FluxBB