Re: Fwd: Re: Fwd: Problem with recv syscall on socket when other side closed connection - Mailing list pgsql-hackers

From Tom Lane
Subject Re: Fwd: Re: Fwd: Problem with recv syscall on socket when other side closed connection
Date
Msg-id 24133.962663677@sss.pgh.pa.us
Whole thread Raw
In response to Re: Fwd: Re: Fwd: Problem with recv syscall on socket when other side closed connection  (kuznet@ms2.inr.ac.ru)
Responses Re: Fwd: Re: Fwd: Problem with recv syscall on socket when other side closed connection  (Alan Cox <alan@lxorguk.ukuu.org.uk>)
List pgsql-hackers
[ Sorry for delay in response, I had other things to do over the
weekend. ]

kuznet@ms2.inr.ac.ru writes:
> BTW look at this. It is RFC1122, 4.2.2.13. 

>                                     If a TCP
>             connection is closed by the remote site, the local
>             application MUST be informed whether it closed normally or
>             was aborted.

So?  This is not relevant, because the connection was not aborted.
The sentence immediately preceding that one defines an abort as an event
in which RST segment(s) are sent, but closure of a connection is defined
to send FIN, not RST.  (More about that below.)

The more relevant quote is the next paragraph,
           The normal TCP close sequence delivers buffered data           reliably in both directions.  Since the two
directionsof a           TCP connection are closed independently, it is possible for           a connection to be "half
closed,"i.e., closed in only one           direction, and a host is permitted to continue sending data           in the
opendirection on a half-closed connection.
 

I do not see how you can read the first sentence of that paragraph in
any way but to say that data once sent must be delivered if at all
possible.  Another example is from RFC-793 (STD-7), section 3.8,
definition of CLOSE:
       Closing connections is intended to be a graceful operation in       the sense that outstanding SENDs will be
transmitted(and       retransmitted), as flow control permits, until all have been       serviced.  Thus, it should be
acceptableto make several SEND       calls, followed by a CLOSE, and expect all the data to be sent       to the
destination.

In our situation, the server sends (queues) some data and then closes
its side of the connection.  The server-side TCP stack should send the
data along with FIN and then go to FIN-WAIT-1 state.  In this state
the server side may receive more data from the client side (since the
client isn't yet aware the server has quit).  RFC-793 is perfectly
clear that the server side must send a dummy ACK but *no* RST in this
case --- see section 3.4, almost the end of the section:
   3.  If the connection is in a synchronized state (ESTABLISHED,   FIN-WAIT-1, FIN-WAIT-2, CLOSE-WAIT, CLOSING,
LAST-ACK,TIME-WAIT),   any unacceptable segment (out of window sequence number or   unacceptible acknowledgment number)
mustelicit only an empty   acknowledgment segment containing the current send-sequence number   and an acknowledgment
indicatingthe next sequence number expected   to be received, and the connection remains in the same state.
 

Therefore, sending data to a no-longer-present receiver does not cause
a connection reset (at least not in a spec-conforming TCP stack), and
there is no justification for discarding data that is coming the other
way.

The Linux kernel's present behavior is contrary to the standard, unable
to support an essential user capability (ie, delivery of last-gasp error
messages), and contrary to the behavior of all other TCP implementations
that I have worked with.  There is a reason why you are in the minority
here...
        regards, tom lane


pgsql-hackers by date:

Previous
From: teg@redhat.com (Trond Eivind Glomsrød)
Date:
Subject: Re: proposed improvements to PostgreSQL license
Next
From: Tom Lane
Date:
Subject: Re: Fwd: Re: Fwd: Problem with recv syscall on socket when other side closed connection