Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 7 Mar 2001 16:20:35 -0500 (EST)
From:      wietse@porcupine.org (Wietse Venema)
To:        Jonathan Lemon <jlemon@flugsvamp.com>
Cc:        Arjan.deVet@adv.iae.nl, net@freebsd.org, wietse@porcupine.org, postfix-users@postfix.org
Subject:   Re: [itojun@iijlab.net: accept(2) behavior with tcp RST right after handshake]
Message-ID:  <20010307212035.8170EBC070@spike.porcupine.org>
In-Reply-To: <200103072013.f27KDoS39501@prism.flugsvamp.com> "from Jonathan Lemon at Mar 7, 2001 02:13:50 pm"

next in thread | previous in thread | raw e-mail | index | archive | help
Several parts of Postfix do: connect() write() close(), where the
close() may happen before the server has accept()ed the connection.

Due to an incompatible change in FreeBSD 4.2-STABLE, this causes
accept() after close() to fail. The already written data is lost.

This is a bad incompatible change.

1 - It introduces a race condition where the result from connect()
    write() close() depends on how quickly the server can accept()
    the connection.

2 - The client gets no error notification. As far as the client
    knows, the write() and the close() completed without error.

The above is experienced with UNIX-DOMAIN sockets. It is not known
whether TCP sockets suffer from the same incompatible change.

> Actually, this is incorrect.  The server in both cases will correctly
> receive the data from the client; it does not matter if the client has
> (correctly) closed the socket before the server gets around to accepting it.

This is incorrect. 

The accept() fails with ECONNABORTED, so that the server never
receives the data. This is experienced by several people who
compiled Postfix on FreeBSD 4.2-STABLE.

This is wrong, because the client gets no error notification. As
far as the client knows, the write() and the close() completed
without error.

> This case only applies to when connection is reset after the initial
> handshake, but before the connection is accepted.  All we are doing is
> returning an error immediately via accept(), instead of waiting for a
> subsequent operation on the socket to fail.  There is no change to the
> read/write semantics here; the local TCP endpoint (and any buffers) have
> already been destroyed.

Several parts of Postfix do connect() write() close(). This bug in
FreeBSD happens when the server calls accept() after the client
has close()d the connection.

This bug in FreeBSD introduces a race condition where the result
of connect() write() close() depends on how quickly the server can
call accept().

This bug in FreeBSD causes loss of data, because the client has
received success returns from write() and close().

I request that this bug in FreeBSD be fixed.

	Wietse

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-net" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010307212035.8170EBC070>