From owner-freebsd-net@FreeBSD.ORG Wed Jun 13 13:30:39 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 17611106566B for ; Wed, 13 Jun 2012 13:30:39 +0000 (UTC) (envelope-from andre@freebsd.org) Received: from c00l3r.networx.ch (c00l3r.networx.ch [62.48.2.2]) by mx1.freebsd.org (Postfix) with ESMTP id 552468FC12 for ; Wed, 13 Jun 2012 13:30:38 +0000 (UTC) Received: (qmail 72541 invoked from network); 13 Jun 2012 15:27:51 -0000 Received: from c00l3r.networx.ch (HELO [127.0.0.1]) ([62.48.2.2]) (envelope-sender ) by c00l3r.networx.ch (qmail-ldap-1.03) with SMTP for ; 13 Jun 2012 15:27:51 -0000 Message-ID: <4FD895F9.9040109@freebsd.org> Date: Wed, 13 Jun 2012 15:30:33 +0200 From: Andre Oppermann User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:12.0) Gecko/20120428 Thunderbird/12.0.1 MIME-Version: 1.0 To: Navdeep Parhar References: In-Reply-To: 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: Wed, 13 Jun 2012 13:30:39 -0000 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. What is the code path leading to tcp_dropwithreset()? Normally this should only be reached if no tcpcb is found. -- Andre