]> CyberLeo.Net >> Repos - FreeBSD/stable/8.git/commit
MFC 221346,223049:
authorjhb <jhb@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Mon, 20 Jun 2011 18:08:34 +0000 (18:08 +0000)
committerjhb <jhb@ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f>
Mon, 20 Jun 2011 18:08:34 +0000 (18:08 +0000)
commit926c0faf645c2febbccefac379fcb8046292b5c8
treea6dd10f6985dedc8c50fdcc59d13339b652b9649
parent9d57cd9e19009178d60fb14008ec1bcc64475563
MFC 221346,223049:
Handle a rare edge case with nearly full TCP receive buffers.  If a TCP
buffer fills up causing the remote sender to enter into persist mode, but
there is still room available in the receive buffer when a window probe
arrives (either due to window scaling, or due to the local application
very slowing draining data from the receive buffer), then the single byte
of data in the window probe is accepted.  However, this can cause rcv_nxt
to be greater than rcv_adv.  This condition will only last until the next
ACK packet is pushed out via tcp_output(), and since the previous ACK
advertised a zero window, the ACK should be pushed out while the TCP
pcb is write-locked.  To guarantee this, advance the advertised window
(rcv_adv) even if we advertise a zero window.

During the window while rcv_nxt is greather than rcv_adv, a few places
would compute the remaining receive window via rcv_adv - rcv_nxt.
However, this value was then (uint32_t)-1.  On a 64 bit machine this
could expand to a positive 2^32 - 1 when cast to a long.  In particular,
when calculating the receive window in tcp_output(), the result would be
that the receive window was computed as 2^32 - 1 resulting in advertising
a far larger window to the remote peer than actually existed.

Fix various places that compute the remaining receive window to either
assert that it is not negative (i.e. rcv_nxt <= rcv_adv), or treat the
window as full if rcv_nxt is greather than rcv_adv.

git-svn-id: svn://svn.freebsd.org/base/stable/8@223343 ccf9f872-aa2e-dd11-9fc8-001c23d0bc1f
sys/netinet/tcp_input.c
sys/netinet/tcp_output.c
sys/netinet/tcp_timewait.c