From owner-freebsd-net@freebsd.org Wed Jul 27 06:16:46 2016 Return-Path: Delivered-To: freebsd-net@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 68A04BA68DB for ; Wed, 27 Jul 2016 06:16:46 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from mail105.syd.optusnet.com.au (mail105.syd.optusnet.com.au [211.29.132.249]) by mx1.freebsd.org (Postfix) with ESMTP id 343F418AA; Wed, 27 Jul 2016 06:16:46 +0000 (UTC) (envelope-from brde@optusnet.com.au) Received: from c122-106-149-109.carlnfd1.nsw.optusnet.com.au (c122-106-149-109.carlnfd1.nsw.optusnet.com.au [122.106.149.109]) by mail105.syd.optusnet.com.au (Postfix) with ESMTPS id 2376410499BD; Wed, 27 Jul 2016 16:16:44 +1000 (AEST) Date: Wed, 27 Jul 2016 16:16:43 +1000 (EST) From: Bruce Evans X-X-Sender: bde@besplex.bde.org To: Don Lewis cc: freebsd-net@freebsd.org Subject: Re: IPv6 -> IPv4 fallback broken in serf, kernel bug? In-Reply-To: <201607262340.u6QNes2t082436@gw.catspoiler.org> Message-ID: <20160727154549.P871@besplex.bde.org> References: <201607262340.u6QNes2t082436@gw.catspoiler.org> MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-Optus-CM-Score: 0 X-Optus-CM-Analysis: v=2.1 cv=VIkg5I7X c=1 sm=1 tr=0 a=R/f3m204ZbWUO/0rwPSMPw==:117 a=L9H7d07YOLsA:10 a=9cW_t1CCXrUA:10 a=s5jvgZ67dGcA:10 a=kj9zAlcOel0A:10 a=SwiqhOd84akJeGznk5QA:9 a=CjuIK1q_8ugA:10 X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.22 Precedence: list List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 27 Jul 2016 06:16:46 -0000 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