From owner-freebsd-net@FreeBSD.ORG Thu Mar 18 20:33:15 2010 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 06BF1106564A for ; Thu, 18 Mar 2010 20:33:15 +0000 (UTC) (envelope-from cjharrer@comcast.net) Received: from qmta07.westchester.pa.mail.comcast.net (qmta07.westchester.pa.mail.comcast.net [76.96.62.64]) by mx1.freebsd.org (Postfix) with ESMTP id 94DDA8FC15 for ; Thu, 18 Mar 2010 20:33:14 +0000 (UTC) Received: from omta06.westchester.pa.mail.comcast.net ([76.96.62.51]) by qmta07.westchester.pa.mail.comcast.net with comcast id uk6J1d00316LCl057kL03M; Thu, 18 Mar 2010 20:20:00 +0000 Received: from record ([69.141.194.142]) by omta06.westchester.pa.mail.comcast.net with comcast id ukKy1d00g34oVgM3SkKze3; Thu, 18 Mar 2010 20:20:00 +0000 From: "Chris Harrer" To: Date: Thu, 18 Mar 2010 16:19:53 -0400 Message-ID: <006f01cac6d8$5fc03cb0$1f40b610$@net> MIME-Version: 1.0 X-Mailer: Microsoft Office Outlook 12.0 Thread-Index: AcrG2F5CPSJ4bcf4RQeWOcfUuC5TJA== Content-Language: en-us Content-Type: text/plain; charset="iso-8859-1" Content-Transfer-Encoding: quoted-printable X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: Bug in tcp_output? 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, 18 Mar 2010 20:33:15 -0000 Hi All, =20 In the following block of code, running on a x86_64 platform, I believe = that cwin should be declared as an int: /* * If snd_nxt =3D=3D snd_max and we have transmitted a FIN, the * offset will be > 0 even if so_snd.sb_cc is 0, resulting in * a negative length. This can also occur when TCP opens up * its congestion window while receiving additional duplicate * acks after fast-retransmit because TCP will reset snd_nxt * to snd_max after the fast-retransmit. * * In the normal retransmit-FIN-only case, however, snd_nxt will * be set to snd_una, the offset will be 0, and the length may * wind up 0. * * If sack_rxmit is true we are retransmitting from the = scoreboard * in which case len is already set. */ if (sack_rxmit =3D=3D 0) { if (sack_bytes_rxmt =3D=3D 0) len =3D ((long)ulmin(so->so_snd.sb_cc, sendwin) - = off); else { long cwin; =DF-- Should be an int =20 /* * We are inside of a SACK recovery episode and = are * sending new data, having retransmitted all the * data possible in the scoreboard. */ len =3D ((long)ulmin(so->so_snd.sb_cc, = tp->snd_wnd)=20 - off); /* * Don't remove this (len > 0) check ! * We explicitly check for len > 0 here (although = it=20 * isn't really necessary), to work around a gcc=20 * optimization issue - to force gcc to compute * len above. Without this check, the computation * of len is bungled by the optimizer. */ if (len > 0) { cwin =3D tp->snd_cwnd -=20 (tp->snd_nxt - tp->sack_newdata) - sack_bytes_rxmt; if (cwin < 0) cwin =3D 0; len =3D lmin(len, cwin); } } } =20 Consider the case where: sack_rxmit =3D 0 sack_bytes_rxmt =3D 0x2238 off =3D 0 len =3D0xa19c tp->snd_cwnd =3D 0x2238 tp->snd_nxt =3D 0xdd6d7974 tp->sack_newdata =3D 0xdd6d6858 In this case cwin evaluates to 0x00000000ffffe37c, which is not <0, but instead huge. This causes the remaining data on the socket=92s = so->so_snd buffer to be sent to the network causing more problems at the receiver = which is already dropping frames. Thanks, =20 Chris