From owner-freebsd-net@FreeBSD.ORG Fri Jun 19 17:58:32 2009 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 AF38E1065698 for ; Fri, 19 Jun 2009 17:58:32 +0000 (UTC) (envelope-from Hartmut.Brandt@dlr.de) Received: from smtp1.dlr.de (smtp1.dlr.de [129.247.252.32]) by mx1.freebsd.org (Postfix) with ESMTP id 480F98FC12 for ; Fri, 19 Jun 2009 17:58:32 +0000 (UTC) (envelope-from Hartmut.Brandt@dlr.de) Received: from beagle.kn.op.dlr.de ([129.247.178.136]) by smtp1.dlr.de over TLS secured channel with Microsoft SMTPSVC(6.0.3790.3959); Fri, 19 Jun 2009 19:46:28 +0200 Date: Fri, 19 Jun 2009 19:46:37 +0200 (CEST) From: Harti Brandt X-X-Sender: brandt_h@beagle.kn.op.dlr.de To: net@freebsd.org Message-ID: <20090619194608.W697@beagle.kn.op.dlr.de> X-OpenPGP-Key: harti@freebsd.org MIME-Version: 1.0 Content-Type: TEXT/PLAIN; charset=US-ASCII; format=flowed X-OriginalArrivalTime: 19 Jun 2009 17:46:28.0322 (UTC) FILETIME=[DF7A1420:01C9F105] Cc: Subject: TCP bug? X-BeenThere: freebsd-net@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list Reply-To: Harti Brandt List-Id: Networking and TCP/IP with FreeBSD List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 19 Jun 2009 17:58:33 -0000 Hi all, one of my TCP test cases breaks in what one could call an edge case: When the TCP is in SYN-SENT state (the user has called connect()) and the peer answers with an almost-lamp test packet which has SYN, FIN, ACK and data larger than the window, TCP ACKs a window full of data, drops the rest, but processes the FIN - it goes into CLOSE_WAIT. This looks wrong to me. When dropping the data that is outside the window, it should also drop the FIN. The problem seems to be very old - I found it alread in rev. 1.1 of tcp_input.c. In -CURRENT it is on line 2590: when the sequence number of the incoming segment is the next expected one, the reassembly queue is empty and we are in an established state, the segment data is added to the socket buffer and all TCP header flags are cleared except for TH_FIN. Unfortunately here the original header flags are taken instead of the cached version in thflags. Earlier in the processing the out-of-window data and the FIN in thflags were chopped off and now TH_FIN reappears. The fix should be easy: instead of using the original flag byte to get the FIN use the cached copy. Index: tcp_input.c =================================================================== --- tcp_input.c (revision 194499) +++ tcp_input.c (working copy) @@ -2587,7 +2587,7 @@ else tp->t_flags |= TF_ACKNOW; tp->rcv_nxt += tlen; - thflags = th->th_flags & TH_FIN; + thflags &= TH_FIN; TCPSTAT_INC(tcps_rcvpack); TCPSTAT_ADD(tcps_rcvbyte, tlen); ND6_HINT(tp); I wonder, though, why the code is as it is, i.e. why it takes the original FIN flag. Any idea? harti