Julian Elischer wrote this message on Mon, Jun 25, 2007 at 10:17 -0700: > Bruce Evans wrote: > >On Fri, 22 Jun 2007, Julian Elischer wrote: > > > >>If one has an event-driven process that accepts tcp connections, one > >>needs to set eh non-blocking socket option and use kqueue or similar > >>to schedule work. > >> > >>This is ok for data transfers, however when it comes to the close() > >>call there is a problem. The problem in in the following code in > >>so_close() > >> > >> > >> if (so->so_options & SO_LINGER) { > >> if ((so->so_state & SS_ISDISCONNECTING) && > >> (so->so_state & SS_NBIO)) > >> goto drop; > >>... > >>drop: > >> [ continues on to destroy socket ] > >> > >> > >>because SS_NBIO is set, the socket acts as if SO_LINGER was set, with > >>a timeout of 0. > >>the result of this, is the following behaviour: > > > >[ patckets in flight get lost ] > > > >This seems to be the correct behaviour. The application doesn't care > >about its data and/or wants to close the descriptor without blocking, > >so it doesn't turn off the blocking flag and/or wait for i/o to complete > >(so that it can see if the i/o actually worked) before calling close(). > > It's not the correct behaviour if the only packet coming back is an Ack of > the FIN (and a FIN) because in the real world, making IE7 throw an error > screen is not an acceptable option. This is the sort of thing > that gets FreeBSD thrown out on favour of "anything else". > Believe me, our customers are "NOT HAPPY" about this. > Instead of getting an "authorization required" page along with > the opportunity to log in, they get an error, and no opportunity > to log in, which makes the system unusable. > Yes, Blame Microsoft, but we are breaking the TCP spec, not them. > We need to fix this some how.
As bde mention, the bug is in the application... Even SUSv2 says: When all file descriptors associated with a pipe or FIFO special file are closed, any data remaining in the pipe or FIFO will be discarded. Our own close(2) says: on the last close of a socket(2) associated naming information and queued data are discarded So, failure of the application to ensure that all data is sent is the application's fault... bde alluded to a simple work around of clearing the non-blocking flag which will return close to the "expected" (but apprently broken) behavior of keeping the tcp socket around till all remaining data has been sent... I must note that the code you quoted has been in FreeBSD since 2.0. > >I implemented this behaviour for tty drivers in FreeBSD. Old BSD tty > >drivers didn't check the nonblocking flag and didn't have a timeout, > >so close() on tty devices tended to hang forever (normally at long > >weekends) even for closes that should have been nonblocking. -- John-Mark Gurney Voice: +1 415 225 5579 "All that I will do, has been done, All that I have, has not." _______________________________________________ freebsd-net@freebsd.org mailing list http://lists.freebsd.org/mailman/listinfo/freebsd-net To unsubscribe, send any mail to "[EMAIL PROTECTED]"