Re: Fwd: Re: Fwd: Problem with recv syscall on socket when other side closed connection

From: Tom Lane <tgl(at)sss(dot)pgh(dot)pa(dot)us>
To: kuznet(at)ms2(dot)inr(dot)ac(dot)ru
Cc: dyp(at)perchine(dot)com, pgsql-hackers(at)postgresql(dot)org, davem(at)redhat(dot)com (Dave Miller), alan(at)lxorguk(dot)ukuu(dot)org(dot)uk (Alan Cox)
Subject: Re: Fwd: Re: Fwd: Problem with recv syscall on socket when other side closed connection
Date: 2000-07-03 22:34:37
Message-ID: 24133.962663677@sss.pgh.pa.us
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

[ Sorry for delay in response, I had other things to do over the
weekend. ]

kuznet(at)ms2(dot)inr(dot)ac(dot)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 directions of 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 open direction 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 acceptable to 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) must elicit only an empty
acknowledgment segment containing the current send-sequence number
and an acknowledgment indicating the 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

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Alan Cox 2000-07-03 22:41:30 Re: Fwd: Re: Fwd: Problem with recv syscall on socket when other side closed connection
Previous Message Trond Eivind=?iso-8859-1?q?_Glomsr=F8d?= 2000-07-03 21:51:46 Re: [HACKERS] proposed improvements to PostgreSQL license