home *** CD-ROM | disk | FTP | other *** search
- Newsgroups: comp.unix.programmer
- Path: sparky!uunet!gumby!wupost!eclnews!achilles!pete
- From: pete@arl.wustl.edu (Peter Flugstad,,,)
- Subject: Re: SO_REUSEADDR (was: Re: Socket Programm
- Message-ID: <1992Nov9.161326.19246@wuecl.wustl.edu>
- Sender: usenet@wuecl.wustl.edu (Usenet Administrator)
- Nntp-Posting-Host: achilles
- Reply-To: pete@arl.wustl.edu
- Organization: Applied Research Lab, Washington University in St. Louis
- References: <101017@bu.edu>
- Date: Mon, 9 Nov 1992 16:13:26 GMT
- Lines: 153
-
- In article 101017@bu.edu, tasos@cs.bu.edu (Anastasios Kotsikonas) writes:
- >In article <1992Nov7.023043.19007@wuecl.wustl.edu> pete@arl.wustl.edu writes:
- [.. my comment saying SO_REUSEADDR doesn't work as advertised...]
- >
- >I am sorry but this is nonsense. I have used SO_REUSEADDR on BSD 4.1.1, AIX
- >3.1.5 and up, HP UX 8.05 and up, SGI OS 4.0 and up and pure SVR4 systems,
- >quite successfully I might add, for both privileged and non-privileged
- >ports.
- >
- >Tasos
-
- hmmm, I think some more detail is needed... I'm not saying your wrong
- (please, no flames :-), just that I've got conflicting stories...
-
- First, some context... I'm using SunOS 4.1.1, and I believe most of the poeple I
- refer to are using BSD based (SunOS) UNIX as well.
-
- (My appologies if reference someone and I don't give a name, I didn't keep
- most of the messages).
-
- Someone had posted a message to comp.unix.internals saying that they were
- having problems binding to a port twice in quick succession. They had started
- their program, killed it, then restarted it quickly again, attempting to bind to
- the same local port both times. They were getting an error back from the bind
- system call stating "Address in use".
-
- Someone else posted a message suggesting they try using SO_REUSEADDR.
-
- I then posted a message saying that it has been my experience that this flag doesn't
- work quite as advertised. On occassion I have killed (ctrl-c) a running program that
- had a TCP socket open. Because my program catches ctrl-c and generally cleans up
- after itself, explicitly closing open sockets and such, I assummed that re-starting it
- immediatley would be no problem, and USUALLY THIS IS THE CASE. But, I have
- found that if there were outstanding messages in the TCP queue, then the socket would
- be stuck in TIME_WAIT for 60 seconds, and so I'd get EADDRINUSE. This occurred
- despite my setting SO_REUSEADD, and SO_DONTLINGER (yes, I know it's going away).
-
- Then, Chris Torek posted a followup to my message, examining some of the code that
- implements this. Here's his message:
-
- ------ BEGIN included message ------
-
- From torek@horse.ee.lbl.gov (Chris Torek)
- Path:eclnews!wupost!bcm!cs.utexas.edu!sun-barr!ames!agate!dog.ee.lbl.gov!horse.ee.lbl.gov!torek
- Newsgroups: comp.unix.internals
- Subject: Re: A problem in bind() system call.Help!
- Date: 5 Nov 1992 06:04:15 GMT
- Organization: Lawrence Berkeley Laboratory, Berkeley
- Lines: 82
- Message-ID: <27240@dog.ee.lbl.gov>
- References: <mahesh.720064067@depot.cis.ksu.edu.cis.ksu.edu> <1992Nov4.192429.10342@wuecl.wustl.edu>
- Reply-To: torek@horse.ee.lbl.gov (Chris Torek)
- NNTP-Posting-Host: 128.3.112.15
-
- In article <1992Nov4.192429.10342@wuecl.wustl.edu> pete@arl.wustl.edu writes:
- >... I tried to use SO_REUSEADDR as well, but I believe it doesn't work in
- >all cases.
-
- Oddly enough, I just looked into something similar today.
-
- SO_REUSEADDR is rather broken. It does work for special cases.
-
- The current 4BSD kernel---recent SunOS releases are similar---has this
- code in in_pcbbind():
-
- if ((so->so_options & SO_REUSEADDR) == 0 &&
- ((so->so_proto->pr_flags & PR_CONNREQUIRED) == 0 ||
- (so->so_options & SO_ACCEPTCONN) == 0))
- wild = INPLOOKUP_WILDCARD;
- if (in_pcblookup(..., sin->sin_addr, lport, wild))
- return (EADDRINUSE);
-
- The `wild' flag tells in_pcblookup to include all TCP or UDP sockets,
- rather than only those `listening'. This is often desirable since a
- unique <laddr,lport> pair automatically guarantees that the 4-tuple
- <laddr,lport,faddr,fport> will be unique. (TCP and UDP require the
- latter.) At the time of the bind() call, the <faddr,fport> portion are
- unknown.
-
- (This suggests---rather appropriately, actually---that the system
- really should have a combined bind and connect call, in which one of
- the two addresses is optional. Then the kernel would usually have all
- the information it needs to pass judgement on the four-tuple, rather
- than having to second-guess two elements, or apply too-inclusive tests
- to the <laddr,lport> portion, as it does now. But never mind that.)
-
- The tests in in_pcbbind() use a `wildcard' lookup if:
-
- a) you did not set SO_REUSEADDR, and:
- b1) this is a UDP socket (not PR_CONNREQUIRED), or:
- b2) you have not yet done a listen() call.
-
- Point b2) is most peculiar, because the `standard' method of writing a
- tcp server is:
-
- s = socket(...);
- if (s < 0) ERROR
- if (bind(s, ...)) ERROR
- if (listen(s, 5)) ERROR
- for (;;) {
- s2 = accept(s, ...);
- if (s2 < 0) ERROR
- ...
- }
-
- If you put a listen() call before the bind(), it does its own internal
- bind(), and the system assigns you a port number. This is only OK if
- you use a `service number service' a la Sun's portmap. Even then,
- SO_ACCEPTCONN will not be set in in_pcbbind(), because listen() sets it
- *after* the internal bind. Hence, this is effectively the same as:
-
- if (!SO_REUSEADDR && (is_udp || 1))
- wild = INPLOOKUP_WILDCARD;
-
- or just
-
- if (!SO_REUSEADDR)
-
- Thus, all SO_REUSEADDR does is prevent setting INPLOOKUP_WILDCARD, and
- we can concentrate on the logic (or lack thereof?) in in_pcblookup. It
- is long and twisty, but it boils down to one thing in the case of TCP
- servers:
-
- *** If you specify a local address (other than 0) in your bind()
- *** call, SO_REUSEADDR will have no effect.
-
- The code really ought to say
-
- if ((so->so_state & SO_REUSEADDR) == 0 && in_pcblookup(...))
- return (EADDRINUSE);
-
- and programmers who use SO_REUSEADDR should expect to get EADDRINUSE
- errors from connect() whenever they do not get a unique 4-tuple.
- --
- In-Real-Life: Chris Torek, Lawrence Berkeley Lab CSE/EE (+1 510 486 5427)
- Berkeley, CA Domain: torek@ee.lbl.gov
-
- ------ END included message ------
-
- I really just want an answer to how to close a socket hard, in such a way that any data
- still in the system is discarded, and I can start up right away again. I realise that discarding
- data is probably not a good idea, but usually if I'm killing the program, any pending data
- for it can be discarded as well.
-
- Any definative answers, or is this another system and specific OS dependant thing???
-
- ---
- Pete Flugstad | Internet: pete@arl.wustl.edu
- Applied Research Laboratory | Tel: (314) 935-6110
- Department of Computer Science | "To err is Human, to really
- Washington University in St. Louis | foul up requires a computer"
-
-
-