Path: csiph.com!x330-a1.tempe.blueboxinc.net!usenet.pasdenom.info!aioe.org!eternal-september.org!feeder.eternal-september.org!mx04.eternal-september.org!.POSTED!not-for-mail From: Kaz Kylheku Newsgroups: comp.os.linux.development.apps Subject: Re: EOF, close(), shutdown(), on POSIX sockets Date: Fri, 6 Jan 2012 01:10:47 +0000 (UTC) Organization: A noiseless patient Spider Lines: 54 Message-ID: <20120105155657.311@kylheku.com> References: Injection-Date: Fri, 6 Jan 2012 01:10:47 +0000 (UTC) Injection-Info: mx04.eternal-september.org; posting-host="UCk3K/YilCUd19+i749f3A"; logging-data="3162"; mail-complaints-to="abuse@eternal-september.org"; posting-account="U2FsdGVkX193GR73KhZcFM/dxwBMiuPMSYzwO/BiLes=" User-Agent: slrn/pre1.0.0-18 (Linux) Cancel-Lock: sha1:Ks8KGaSeGLKJVSe8C5hGx6DAQqo= Xref: x330-a1.tempe.blueboxinc.net comp.os.linux.development.apps:355 On 2012-01-05, David Dyer-Bennet wrote: > If I receive EOF when I read from A, I think I should do shutdown(B, > SHUT_WR), and if I receive EOF when I read from B, I should similarly do > shutdown (A, SHUT_WR). Indeed, if you want the proxy in the middle to be transparent to half-closes, which is a wortwhile requirement to implement if you want it to be as transparent as possible. > 17:58:48.764575 shutdown(3, 0 /* receive */) = 0 > > nc promptly shuts down the socket it just received EOF on. Should I be > doing this in addition to the other? This is not necessary, and SHUT_RD can basically be even regarded as useless in TCP communication. Look in net/ipv4/tcp_ipv4.c in the tcp_shutdown function. It bails out if it's not in the write direction: if (!(how & SEND_SHUTDOWN)) return; Shutting down for reading is basically nonsensical; don't waste cycles tripping into the kernel for this. > Another confusing factor: immediately after this, nc reads 1024 bytes > from stdin (leaving it in the middle of the test file, about 56%; and > that's only 1/8 of the amount of data requested), writes it to 3, then > closes and exits -- meaning it aborts reading and transmitting the input > file. I've just looked at four different variants of netcat source code. (From this I can gather that you're running the one from the netcat-openbsd package.) I looked at the repository for GNU netcat, openbsd-netcat some original netcat sources from "hobbit@avian.org", as well as the NMAP project's netcat-like program. All of them bail their loop on EOF from the socket. This is probably because the typical use case for netcat is to do a one-directional transfer, in the absence of any kind of request/response transaction. One side dumps data into the socket, the other dumps it into a file. When EOF is detected from the network, of course all previously received data has been written, and the sender is not expecting anything in return. Half-close logic is required for correctly implementing two-way transactions, whereby the client indicates "I have no more requests for the server", but not all the responses have been received. So these netcat utilities do not seem to provide a complete test case for a proxy's transparent handling of half close. Try proxying some true client/server protocols. (HTTP? RDBMS's? ...)