Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 27 Jul 2016 16:16:43 +1000 (EST)
From:      Bruce Evans <brde@optusnet.com.au>
To:        Don Lewis <truckman@freebsd.org>
Cc:        freebsd-net@freebsd.org
Subject:   Re: IPv6 -> IPv4 fallback broken in serf, kernel bug?
Message-ID:  <20160727154549.P871@besplex.bde.org>
In-Reply-To: <201607262340.u6QNes2t082436@gw.catspoiler.org>
References:  <201607262340.u6QNes2t082436@gw.catspoiler.org>

next in thread | previous in thread | raw e-mail | index | archive | help
On Tue, 26 Jul 2016, Don Lewis wrote:

> On 27 Jul, Bruce Evans wrote:
>> On Tue, 26 Jul 2016, Don Lewis wrote:
>>> ...
>>> kevent(3,{ 4,EVFILT_READ,EV_ADD,0x0,0x0,0x805491300 },1,0x0,0,0x0) = 0 (0x0)
>>> kevent(3,{ 4,EVFILT_WRITE,EV_ADD,0x0,0x0,0x805491300 },1,0x0,0,0x0) = 0 (0x0)
>>> kevent(3,0x0,0,{ 4,EVFILT_READ,EV_EOF,NOTE_LOWAT|0x3c,0x0,0x805491300 4,EVFILT_WRITE,EV_EOF,NOTE_LOWAT|0x3c,0x8000,0x805491300 },32,{ 0.500000000 }) = 2 (0x2)
>>
>> I don't see any POLL* there or completely understand the notation or kqueue,
>> but this looks like the poll() bug with POLLIN together with POLLHUP, not
>> POLLIN together with POLLERR.
>
> I didn't try to decipher out the kqueue stuff.  I was thinking that our
> poll() was using kqueue under the hood, but it turns out that the poll
> emulation is actually being done by apr.  Sigh ...
>
> A comment in the emulation code says:
>
>    /* APR_POLLPRI, APR_POLLERR, and APR_POLLNVAL are not handled by this
>     * implementation.
>
> ... double sigh.
>
>> Everything here seems to be correct.  Not very good, but good enough here.
>>
>> EV_EOF is set by filt_soread() when SBS_CANTRECVMORE is set.
>> SBS_CANTRECVMORE means hangup, not EOF, and I think there can be
>> readable data from a socket in general but not after a connection
>> error.  So this translation is incorrect in general but correct after
>> a connection error.  kqueue just can't represent hangup and conflates
>> it with EOF.
>
> But should there be a hangup or EOF if we never got connected in the
> first place?

I think hangup is correct.  Named pipes have this problem and more.  The
connection may be re-opened, so hangup should not be sticky.  Except,
for some uses it should be sticky.  The initial state when there is
no writer and no data is like a non-sticky hangup, and I think POLLHUP
should be returned for both.  I think this is what the old fifofs
implementation did (it set SBS_CANT* initially and sopoll() should turn
this into POLLHUP).  However, this is not quite right since it leaves
no good way to wait for a writer.  select() and poll() are useless since
they are specified to return immediately in the hangup state.  There is
no way to get back to a blocking open() with an open fd.  You have to
use a new blocking open().  But a new open might have side effects, and
it often have to be in a separate thread, and with threads you could
do almost everything using blocking threads to do the i/o and waiting
in these threads instead of select() or poll().

Emulation gives another problem.  It was difficult to emulate named
pipes on top of sockets in old fifofs even with full access to kernel
state and kernel events.  The socket layer might be missing some state
or events for it changing.  It was missing reporting of POLLHUP as late
as FreeBSD-4.  This is difficult to fix in an emulator, and fifofs in
FreeBSD-4 didn't try.  POLLHUP was just unsupported for most file types
in FreeBSD-4.

Bruce



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