[ 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