From owner-freebsd-net@FreeBSD.ORG Wed Jan 23 20:20:36 2008 Return-Path: Delivered-To: net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id C08E716A468 for ; Wed, 23 Jan 2008 20:20:36 +0000 (UTC) (envelope-from sean@chittenden.org) Received: from davie.textdrive.com (davie.textdrive.com [207.7.108.101]) by mx1.freebsd.org (Postfix) with ESMTP id BA0D913C46A for ; Wed, 23 Jan 2008 20:20:36 +0000 (UTC) (envelope-from sean@chittenden.org) Received: from [192.168.0.79] (2.ten-net.org [71.6.14.2]) by davie.textdrive.com (Postfix) with ESMTP id CA3FAC2511 for ; Wed, 23 Jan 2008 19:56:35 +0000 (GMT) Message-Id: From: Sean Chittenden To: net@freebsd.org Content-Type: text/plain; charset=US-ASCII; format=flowed; delsp=yes Content-Transfer-Encoding: 7bit Mime-Version: 1.0 (Apple Message framework v915) Date: Wed, 23 Jan 2008 11:56:33 -0800 X-Mailer: Apple Mail (2.915) Cc: Subject: SO_LINGER brokenness... X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 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, 23 Jan 2008 20:20:36 -0000 Howdy. Looks like SO_LINGER is broken on loopback. Here's the test case: 0. Install memcached (databases/memcached) 1. Download test_linger.c: fetch http://sean.chittenden.org/pubfiles/freebsd/test_linger.c 2. Compile: gcc test_linger.c -o test_linger 3. Fire up memcached in a new window: memcached -vvv -p 11211 4. Test: ./test_linger localhost 11211 5. Watch for either: <16 new client connection <16 set valid_key 0 0 8 >16 STORED <16 set valid_key 0 0 8 >16 STORED <16 connection closed. Fail. or <16 new client connection <16 set valid_key 0 0 8 >16 STORED <16 set valid_key 0 0 8 >16 STORED <16 get ENOENT_key >16 END <16 connection closed. Win. Can someone verify that my test case is correct? If it is, I'll port it to src/tools/regression/sockets/. Broken or not, I don't think the behavior suggested in src/netinet/ tcp_usrreq.c:1498 is correct. A The test above write(2)'s and read(2)'s some data successfully before testing the validity of the half-close(2)'ed state, so I'm not worried about whether or not a SYN has been received. I haven't looked too closely yet, but it looks like tcp_close() needs to call to sbflush() if SO_LINGER is set (in fact, it doesn't look like there's any special handling of linger in tcp_subr.c, so I'm not sure if I'm glancing in the right area). /* * User issued close, and wish to trail through shutdown states: * if never received SYN, just forget it. If got a SYN from peer, * but haven't sent FIN, then go to FIN_WAIT_1 state to send peer a FIN. * If already got a FIN from peer, then almost done; go to LAST_ACK * state. In all other cases, have already sent FIN to peer (e.g. * after PRU_SHUTDOWN), and just have to play tedious game waiting * for peer to send FIN or not respond to keep-alives, etc. * We can let the user exit from the close as soon as the FIN is acked. */ Thoughts/guidance? -sc -- Sean Chittenden sean@chittenden.org http://sean.chittenden.org/