Re: socket close
From: Eric Dumazet
Date: Wed Jul 04 2007 - 09:35:09 EST
On Wed, 04 Jul 2007 22:39:55 +1000
skaller <skaller@xxxxxxxxxxxxxxxxxxxxx> wrote:
> On Wed, 2007-07-04 at 12:34 +0200, Eric Dumazet wrote:
> > On Wed, 04 Jul 2007 19:56:29 +1000
> > skaller <skaller@xxxxxxxxxxxxxxxxxxxxx> wrote:
> > > I wonder if someone can tell me what Linux does here.
> > >
> > > First: it seems to me Posix specification are such that
> > > the behaviour on closing a socket is unspecified, except
> > > if the socket is blocking and SO_LINGER is used to specify
> > > a timeout. In that case the close blocks until written data
> > > is sent down the wire or the nominated timeout expires.
> > >
> > > IMHO this specification is unacceptable because it makes
> > > reliable non-blocking socket operations impossible.
> > > However I may misunderstand the spec.
> > >
> > > Second: I have observed that in non-blocking mode,
> > > Linux discards written data without sending it down the wire.
> > > As above: this seems unacceptable, although it conforms to
> > > Posix 'in vaccuuo' :)
> > >
> > > Can anyone tell me what Linux *actually* does?
> > >
> > In my understanding, the behavior at close() time depends if
> > you still have data in receive queue.
> > If you dont have data wating in receive queue
> > (but possibly some data in output queue), then stack sends
> > data and FIN, no loss of data.
> > However, If you have some unread data, then a RST is sent
> > (and data in output queue is lost).
> > So maybe your app is actually closing a socket with
> > unread data (this would be an application error)
> There is *definitely* unread data in the
> receive queue in our test case.
> Looks like, after reading what it wants, the application
> (a brain dead web server) should do a shutdown
> on input. (A shutdown on the output IS being used).
> Otherwise the RST is sent, triggering the client
> to close its READER, and send a RST back to the server,
> which then shuts down its writer. Is that right?
> [I can't see why the kernel would flush the output
> queue just because the application hasn't shutdown
> the input side of the link]
You may take a look at RFC 1122 ( http://www.faqs.org/rfcs/rfc1122.html )
section 188.8.131.52 Closing a Connection:
"A host MAY implement a "half-duplex" TCP close sequence, so
that an application that has called CLOSE cannot continue to
read data from the connection. If such a host issues a
CLOSE call while received data is still pending in TCP, or
if new data is received after CLOSE is called, its TCP
SHOULD send a RST to show that data was lost."
If your app is doing a close() on a socket where incoming data is in receive queue or expected to come after the close() (and this is where the problem really is : depending on timing, if your app is really fast, it could close the socket before the 'extra data' really hit you), so the answer (RST or not) could depend on timing.
sending an RST if data is in receive queue is just to respect RFC spirit : notity the other peer that data was lost.
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html