Date: Thu, 18 Mar 2010 16:19:53 -0400 From: "Chris Harrer" <cjharrer@comcast.net> To: <freebsd-net@freebsd.org> Subject: Bug in tcp_output? Message-ID: <006f01cac6d8$5fc03cb0$1f40b610$@net>
next in thread | raw e-mail | index | archive | help
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
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?006f01cac6d8$5fc03cb0$1f40b610$>