From owner-freebsd-net@FreeBSD.ORG Tue Apr 3 13:45:23 2012 Return-Path: Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 086BC106564A for ; Tue, 3 Apr 2012 13:45:23 +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 2AADE8FC1B for ; Tue, 3 Apr 2012 13:45:21 +0000 (UTC) Received: (qmail 25802 invoked from network); 3 Apr 2012 13:43:38 -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 ; 3 Apr 2012 13:43:38 -0000 Message-ID: <4F7AFEEF.60708@freebsd.org> Date: Tue, 03 Apr 2012 15:45:19 +0200 From: Andre Oppermann User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:10.0.2) Gecko/20120216 Thunderbird/10.0.2 MIME-Version: 1.0 To: Darren Reed References: <4F75C1A3.4030401@freebsd.org> <4F75D9ED.7080707@freebsd.org> <4F780373.6030107@freebsd.org> In-Reply-To: <4F780373.6030107@freebsd.org> Content-Type: text/plain; charset=ISO-8859-1; format=flowed Content-Transfer-Encoding: 7bit Cc: darrenr@freebsd.org, freebsd-net@freebsd.org Subject: Re: FreeBSD TCP ignores zero window size 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: Tue, 03 Apr 2012 13:45:23 -0000 On 01.04.2012 09:27, Darren Reed wrote: > Andre, > > Your changes bring it closer to working correctly with a > small change: rather than "tiwin > tp->snd_wnd", it should > be "tiwin != tp->snd_wnd". In this trace, the remote end > has set a window scale factor of 5 during connection > establishment. > > The same change should be made in the if() a few lines down. Window updates are a tricky thing by that we must not accept old and outdated segments to update our window. Hence we have to test for freshness while at the same time be open enough to handle weird cases like bidirectional data transfers on lossy links with data waiting in reassembly queues on both sides. There are two clear cut cases we can accept a window update: a) the incoming segment ACK'ed new data (moved snd_una). b) the incoming segment carries new data (moved rcv_nxt). The latter gets tricky already with the addition of the reassembly queue. Here only segments that have a higher SEQ than highest already present in the reassembly queue are OK. And then we have a window probe where we'll get an answer that neither moves our ACK (zero byte probes) nor carries any data. Here the window update is vital for the future progress of the session. > The problem here is that it only tracks the window size as > it grows, not as it shrinks. Thus the remote end setting its > window size to 0 is ignored. My patch is wrong as the acked count is already integrated by the time we reach this spot. I'm working on a better implementation. > But having made that change, there appears to be still one > problem that still lingers. As can be seen below, freebsd 8.2 > fails to properly ack the data that the remote end is trying > to send, ultimately causing the connection to be dropped. It's the other way around. remote.ssh is sending old data which freebsd82.62922 has already ack'ed. The sessions seems to be de-synchronized, perhaps some middle box mucking with the segments trying to modulate something? > Darren > > 16:06:50.207927 IP remote.ssh > freebsd82.62922: . 6268613:6270053(1440) ack 367219 win 128 > > 16:06:50.208736 IP freebsd82.62922 > remote.ssh: . ack 6270053 win 8100 > 16:06:50.210902 IP remote.ssh > freebsd82.62922: . 6270053:6271493(1440) ack 367219 win 128 > > 16:06:50.211752 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 ACK 6,271,493 for data segment preceeding it. > 16:06:50.229987 IP remote.ssh > freebsd82.62922: . ack 370099 win 38 > 16:06:50.419926 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:06:50.422858 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:06:51.207172 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:06:51.419263 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:06:53.203547 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0 > Incoming old data 6,267,173+1440 already ACK'ed 4320 bytes ago. > 16:06:53.204320 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 ACK for highest SEQ seen again to re-synchronize. > 16:06:53.415648 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:06:59.207766 IP remote.ssh > freebsd82.62922: . 6267173:6268613(1440) ack 371315 win 0 > remote.ssh doesn't get and retransmits... > 16:06:59.208469 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:06:59.419342 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:07:11.212606 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0 > keeps on going with reduced MSS. > 16:07:11.213158 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:07:11.424414 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:07:35.227356 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0 > > 16:07:35.227954 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:07:35.440105 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:08:23.257747 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0 > > 16:08:23.258471 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:08:23.469790 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:09:27.299037 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0 > > 16:09:27.299734 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:09:27.510740 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:10:31.340328 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0 > > 16:10:31.340996 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:10:31.552639 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:11:35.380906 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0 > > 16:11:35.381519 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:11:35.592948 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:12:39.421327 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0 > > 16:12:39.421957 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:12:39.633531 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:13:43.462137 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0 > > 16:13:43.462625 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:13:43.674110 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:14:47.502951 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0 > > 16:14:47.503637 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:14:47.715729 IP remote.ssh > freebsd82.62922: . ack 371315 win 0 > 16:15:51.542134 IP remote.ssh > freebsd82.62922: . 6267173:6267697(524) ack 371315 win 0 > > 16:15:51.542794 IP freebsd82.62922 > remote.ssh: . ack 6271493 win 8280 > 16:16:55.581199 IP remote.ssh > freebsd82.62922: R 6271493:6271493(0) ack 371315 win 0 Retransmission timeout exhausted and sending a reset with the correct SEQ that freebsd82.62922 is trying to ack all the time! The time difference between that last sync-ack and the RST doesn't make it look like a direct response as in a closed socket. -- Andre