From owner-freebsd-net@FreeBSD.ORG Thu Jun 14 00:56:51 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (unknown [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id A91A8106566C; Thu, 14 Jun 2012 00:56:51 +0000 (UTC) (envelope-from nparhar@gmail.com) Received: from mail-pb0-f54.google.com (mail-pb0-f54.google.com [209.85.160.54]) by mx1.freebsd.org (Postfix) with ESMTP id 71F258FC19; Thu, 14 Jun 2012 00:56:51 +0000 (UTC) Received: by pbbro2 with SMTP id ro2so3219419pbb.13 for ; Wed, 13 Jun 2012 17:56:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=sender:message-id:date:from:user-agent:mime-version:to:cc:subject :references:in-reply-to:content-type:content-transfer-encoding; bh=lFKxvLzQbbFpdXBYNKxP3fLIeyNuaUlq0FJLhnUuo3M=; b=V10GoMrHEm9i5XcksPUxLze1KWP9PnrX6gd7aJryd5yIjKItJ2KLOew7eo8r1OVsxh KnzQ1XTomHy7pEqpdtgddoFh4IlCTwkk87MV1BHr4jx3iUsh+7TiKAxOlCXzsBYrGdUR Kp+ORQyJjOrYvHMnry+HONyvTomQ2RteWahGQ727+eWlewdy5QJSTpfxuI1gmiSNkALO cN0iHkLKt8+9aT8dkC6hOZnTm+uEY91LDbubi8JJKyYKV/v8ylmN1DvpjJ8t5p+txlEO xmZYdWclpK1tGrbVom5gCvdpEB/ILti/Hzp26brcWocmCfuaS+XZW4SB5GL7EOhNY0Vs AbSQ== Received: by 10.68.219.226 with SMTP id pr2mr1863512pbc.1.1339635411264; Wed, 13 Jun 2012 17:56:51 -0700 (PDT) Received: from [10.192.166.0] (stargate.chelsio.com. [67.207.112.58]) by mx.google.com with ESMTPS id ip5sm7544090pbc.3.2012.06.13.17.56.49 (version=SSLv3 cipher=OTHER); Wed, 13 Jun 2012 17:56:50 -0700 (PDT) Sender: Navdeep Parhar Message-ID: <4FD936D0.1050005@FreeBSD.org> Date: Wed, 13 Jun 2012 17:56:48 -0700 From: Navdeep Parhar User-Agent: Mozilla/5.0 (X11; FreeBSD amd64; rv:13.0) Gecko/20120609 Thunderbird/13.0 MIME-Version: 1.0 To: Andre Oppermann References: <4FD895F9.9040109@freebsd.org> In-Reply-To: <4FD895F9.9040109@freebsd.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: freebsd-net@freebsd.org Subject: Re: seq# of RST in tcp_dropwithreset 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: Thu, 14 Jun 2012 00:56:51 -0000 On 06/13/12 06:30, Andre Oppermann wrote: > On 07.06.2012 22:28, George Neville-Neil wrote: >> >> On Mar 27, 2012, at 18:13 , Navdeep Parhar wrote: >> >>> When the kernel decides to respond with a RST to an incoming TCP >>> segment, it uses its ack# (if valid) as the seq# of the RST. See this >>> in tcp_dropwithreset: >>> >>> if (th->th_flags& TH_ACK) { >>> tcp_respond(tp, mtod(m, void *), th, m, (tcp_seq)0, >>> th->th_ack, TH_RST); >>> } else { >>> if (th->th_flags& TH_SYN) >>> tlen++; >>> tcp_respond(tp, mtod(m, void *), th, m, th->th_seq+tlen, >>> (tcp_seq)0, TH_RST|TH_ACK); >>> } >>> >>> This can have some unexpected results. I observed this on a link with >>> a very high delay (B is FreeBSD, A could be anything). >>> >>> 1. There is a segment in flight from A to B. The ack# is X (all tx >>> from B to A is up to date and acknowledged). >>> 2. socket is closed on B. B sends a FIN with seq# X. >>> 3. The segment from A arrives and elicits a RST from B. The seq# of >>> this RST will again be X. A receives the FIN and then the RST with >>> identical sequence numbers. The situation resolves itself eventually, >>> when A retransmits and the retransmitted segment ACKs the FIN too and >>> so the next time around B sends a RST with the "correct" seq# (one >>> after the FIN). >>> >>> If there is a local tcpcb for the connection with state>= >>> ESTABLISHED, wouldn't it be more accurate to use its snd_max as the >>> seq# of the RST? >>> >> >> Hi Navdeep, >> >> Sorry I missed this so many months ago, but jhb@ was kind enough to >> point this >> query out to me. My understanding of correct operation in this case, >> is that we >> do not want to move the sequence number until we have received the ACK >> of our >> FIN, as any other value would indicate to the TCP on A that we have >> received their >> ACK of our FIN, which, in this case, we have not. The fact that there >> isn't a better >> way to indicate the error is a tad annoying, but, and others can >> correct me if they think >> I'm wrong, this is the correct way for the stacks to come to eventual >> agreement >> on the closing of the connection. > > In this case Navdeep is correct. As long as a tcpcb is around no RST > should be generated in step 3 if we are in FIN_WAIT_1, FIN_WAIT_2, CLOSING > or TIME_WAIT. Why not? Generating a RST is the right thing to do when faced with excess data that cannot be delivered because the local socket has closed. My question/concern was about the seq# that the kernel's TCP chose for this RST, not the RST itself. > What is the code path leading to tcp_dropwithreset()? Normally this should > only be reached if no tcpcb is found. I don't remember it off the top of my head, but a quick look at tcp_input.c suggests it must have been this piece of code in tcp_do_segment(): /* * If new data are received on a connection after the * user processes are gone, then RST the other end. */ if ((so->so_state & SS_NOFDREF) && tp->t_state > TCPS_CLOSE_WAIT && tlen) { Regards, Navdeep