Path: csiph.com!x330-a1.tempe.blueboxinc.net!newsfeed.hal-mli.net!feeder3.hal-mli.net!newsfeed.hal-mli.net!feeder1.hal-mli.net!news.glorb.com!news-out.octanews.net!indigo.octanews.net!news-1.mpls.iphouse.net.POSTED!not-for-mail From: David Dyer-Bennet Newsgroups: comp.os.linux.development.apps Subject: EOF, close(), shutdown(), on POSIX sockets Date: Thu, 05 Jan 2012 17:17:47 -0600 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/23.1 (usg-unix-v) Cancel-Lock: sha1:c9rDYqfvaMI66HdNdXTZj3QPKaA= MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Lines: 65 Organization: ipHouse - Welcome Home! NNTP-Posting-Date: 05 Jan 2012 17:17:47 CST NNTP-Posting-Host: 0522486e.newsreader.iphouse.net X-Trace: DXC=9ib]IY2RaTl;`KnLU\7EmnUU[C:R=]MbjeHS>e[L>83`2WM9\jNDQ7oWX@ab@3=d:`mbdiTPUBI>nG^5Pc_WVH4f X-Complaints-To: abuse@iphouse.net Xref: x330-a1.tempe.blueboxinc.net comp.os.linux.development.apps:351 I'm getting myself confused in an application I'm having trouble getting working. I've now got too many different sets of test code that behave differently, and which don't always do what I expect. I'm developing this on a Centos 5 system. The actual code is in Perl, but I don't think that's important (based on strace monitoring of the actual system calls being made, and what happens). Portability isn't a requirement (but is my default way of thinking in general). I'm working on the core of a tcp proxy application. The overall architecture is that the proxy server listens on a socket, accepts connections, reads the first line and decides (based on information transmitted in the local protocol that the request is encoded in) what server to send that request to, forks a child, the child connects to the chosen server, and drops the client and server socket into the core relay bit (while the parent goes back to accept the next connection). The proxy is supposed to be transparent (except, obviously, that the real server can tell where the connection it gets came from if it asks). Much of it seems to work :-). One thing I think I'm having trouble with (tests using netcat don't do quite what I expect) involves what to do in the proxy copy loop when I get EOF (meaning a 0 return from a read, no error). The proxy is copying bi-directionally between two sockets, call them socket A and socket B. 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). (And there is accounting about which sockets I've received EOF reading from, to avoid trying to read them in future, and to keep track of when both sides have shut down so I should close everything and exit.) This appears to be necessary to propogate the EOF through the proxy from client to server or vice-versa. Right? One confusing factor: in the strace from nc (netcat), I get: 17:58:48.764342 poll([{fd=3, events=POLLIN}, {fd=0, events=POLLIN}], 2, -1) = 2 ([{fd=3, revents=POLLIN}, {fd=0, revents=POLLIN}]) 17:58:48.764474 read(3, "", 1024) = 0 nc receives EOF from the proxy (port 3 is the socket connected to the proxy). 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? 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. The nc that the strace was from is invoked as: nc localhost $PORT1 < $TD1 >$TDIR/o2 & where $PORT1 is 8000 and is where the proxy is listening. -- David Dyer-Bennet, dd-b@dd-b.net; http://dd-b.net/ Snapshots: http://dd-b.net/dd-b/SnapshotAlbum/data/ Photos: http://dd-b.net/photography/gallery/ Dragaera: http://dragaera.info