[comp.protocols.tcp-ip] reuse of addresses when calling bind

booloo@lll-crg.llnl.gov (Mark Boolootian) (11/30/90)

I've got a meeting in a couple minutes so I'm going to try and ask this quickly.
If you setsockopt() with SO_REUSEADDR, as I understand it, you should be able
to issue a bind() for a ip/port address that is already in use.  However, it
appears that it is still possible for bind() to return the error EADDRINUSE (for
example, look at routine getdatasock() in ftpd.c where they have a loop that
retries the bind() several times before giving up, all the while checking for
EADDRINUSE).  

What I'd like to know is why this happens, in lieu of the call to setsockopt().
Thanks in advance.  Email would be nice but I'll wade through stuff if need be.

regards,
mb

booloo@lll-crg.llnl.gov

pww@bnr.ca (Peter Whittaker) (12/01/90)

In article <86984@lll-winken.LLNL.GOV> booloo@lll-crg.llnl.gov (Mark Boolootian) writes:
>I've got a meeting in a couple minutes so I'm going to try and ask this quickly.
>If you setsockopt() with SO_REUSEADDR, as I understand it, you should be able
>to issue a bind() for a ip/port address that is already in use.  However, it
>appears that it is still possible for bind() to return the error EADDRINUSE (for
>example, look at routine getdatasock() in ftpd.c where they have a loop that
>retries the bind() several times before giving up, all the while checking for
>EADDRINUSE).  
>
>What I'd like to know is why this happens, in lieu of the call to setsockopt().
>Thanks in advance.  Email would be nice but I'll wade through stuff if need be.

I'm posting instead of e-mailing you directly in order to check my answer against the combined wisdom of the net...

First, the original socket must have set SO_REUSEADDR - you cannot set it 
retroactively.

Second, two independent processes cannot bind to the same port no matter 
what options are set.  SO_REUSEADDR allows the same process, or children of
that process, to bind to same port (this is how ftp works:  one server binds
its children to the same port, so all data flows from the same port).

Finally, under certain conditions (notably the use of SO_KEEPALIVE in 
an HP-UX 6.5 client), connections never disppear when the server dies/exits;
the kernel tells the server that the socket is closed, but never manages to
close it, because the HPUS 6.5 client interferes with the shutdown.  Result:
regardless of any options, the socket cannot reused until the client shuts
down or the machine is rebooted.

--
Peter Whittaker      [~~~~~~~~~~~~~~~~~~~~~~~~~~]   Open Systems Integration
pww@bnr.ca           [                          ]   Bell Northern Research 
Ph: +1 613 765 2064  [                          ]   P.O. Box 3511, Station C
FAX:+1 613 763 3283  [__________________________]   Ottawa, Ontario, K1Y 4H7

booloo@lll-crg.llnl.gov (Mark Boolootian) (12/01/90)

In article <1990Nov30.202155.8253@bwdls61.bnr.ca> pww@bnr.ca (Peter Whittaker) writes:
>In article <86984@lll-winken.LLNL.GOV> booloo@lll-crg.llnl.gov (Mark Boolootian) writes:
>>If you setsockopt() with SO_REUSEADDR, as I understand it, you should be able
>>to issue a bind() for a ip/port address that is already in use.  However, it
>>appears that it is still possible for bind() to return the error EADDRINUSE 
>
>
>First, the original socket must have set SO_REUSEADDR - you cannot set it 
>retroactively.

This is the case.  Each socket wishing to bind to the same port number must 
issue a setsockopt() for SO_REUSEADDR.

>
>Second, two independent processes cannot bind to the same port no matter 
>what options are set.  SO_REUSEADDR allows the same process, or children of
>that process, to bind to same port (this is how ftp works:  one server binds
>its children to the same port, so all data flows from the same port).
>

This certainly isn't true.  The FTP server always binds to local port 20 for 
data connections.  The uniqueness of the connection must be guaranteed by the 
client's selection of a remote port.  Since it is possible for there to be
multiple instances of the ftp server running at one time, it is necessary to set
the data socket with the SO_REUSEADDR option. 

This issue is talked about in the Unix Programmer's Manual on page 8-31 (PS1).
Unfortunately, I still don't see how this particular error can occur once the
socket has been correctly setsockopt()'ed.

Thanks for the reply but I'm still confused.
mb

enag@ifi.uio.no (Erik Naggum) (12/01/90)

In article <87047@lll-winken.LLNL.GOV>, Mark Boolootian writes:

   Unfortunately, I still don't see how this particular error
   [EADDRINUSE] can occur once the socket has been correctly
   setsockopt()'ed.

A TCP connection is uniquely identified by the 4-tuple <Raddr, Rport,
Laddr, Lport> where R means Remote and L Local, a total of 96 bits!
Given that you always have a peer in an established connection, I have
never understood what you gain from defaulting to consider only the
<Laddr, Lport> pair for uniqueness.  Seems silly.  Even with several
processes listen()ing to the same Lport, it isn't a problem, since the
TCP handler will arbitrarily assign a connection to one of the waiting
processes, and thereafter the connection is uniquely identified.  Can
someone with first-hand experience tell me why BSD sockets don't
default to "reusing" addresses?  (I think "reuse" is a misnomer, too,
since it's not actually reused, unless you narrow your view to the
local <addr, port> pair, sort of like thinking that the horizon is a
place.)

However, there is a chance that things may go astray.  If a broken
application (say, one which always calls out on the SMTP port (25),
instead of getting a fresh Lport) attempts to connect to the same host
on the same port (say, SMTP), the 96-bit connection "identifier" is
already in use.  In most of the implementations of TCP that I have
seen, you would have to work _real_hard_ to accomplish this.  (At
least I would have to work real hard, others may find it obvious that
it should be done that way, and complain about how stupid TCP is. :-)

--
[Erik Naggum]	Snail: Naggum Software / BOX 1570 VIKA / 0118 OSLO / NORWAY
		Mail: <erik@naggum.uu.no>, <enag@ifi.uio.no>
My opinions.	Wail: +47-2-836-863