From owner-cvs-src-old@FreeBSD.ORG Fri Apr 29 15:40:23 2011 Return-Path: Delivered-To: cvs-src-old@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 3B6DD1065788 for ; Fri, 29 Apr 2011 15:40:23 +0000 (UTC) (envelope-from jhb@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [IPv6:2001:4f8:fff6::29]) by mx1.freebsd.org (Postfix) with ESMTP id 0C8B58FC14 for ; Fri, 29 Apr 2011 15:40:23 +0000 (UTC) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.14.4/8.14.4) with ESMTP id p3TFeMXC004647 for ; Fri, 29 Apr 2011 15:40:22 GMT (envelope-from jhb@repoman.freebsd.org) Received: (from svn2cvs@localhost) by repoman.freebsd.org (8.14.4/8.14.4/Submit) id p3TFeMIP004646 for cvs-src-old@freebsd.org; Fri, 29 Apr 2011 15:40:22 GMT (envelope-from jhb@repoman.freebsd.org) Message-Id: <201104291540.p3TFeMIP004646@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: svn2cvs set sender to jhb@repoman.freebsd.org using -f From: John Baldwin Date: Fri, 29 Apr 2011 15:40:12 +0000 (UTC) To: cvs-src-old@freebsd.org X-FreeBSD-CVS-Branch: HEAD Subject: cvs commit: src/sys/netinet tcp_input.c tcp_output.c tcp_timer.c tcp_var.h X-BeenThere: cvs-src-old@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: **OBSOLETE** CVS commit messages for the src tree List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 29 Apr 2011 15:40:23 -0000 jhb 2011-04-29 15:40:12 UTC FreeBSD src repository Modified files: sys/netinet tcp_input.c tcp_output.c tcp_timer.c tcp_var.h Log: SVN rev 221209 on 2011-04-29 15:40:12Z by jhb TCP reuses t_rxtshift to determine the backoff timer used for both the persist state and the retransmit timer. However, the code that implements "bad retransmit recovery" only checks t_rxtshift to see if an ACK has been received in during the first retransmit timeout window. As a result, if ticks has wrapped over to a negative value and a socket is in the persist state, it can incorrectly treat an ACK from the remote peer as a "bad retransmit recovery" and restore saved values such as snd_ssthresh and snd_cwnd. However, if the socket has never had a retransmit timeout, then these saved values will be zero, so snd_ssthresh and snd_cwnd will be set to 0. If the socket is in fast recovery (this can be caused by excessive duplicate ACKs such as those fixed by 220794), then each ACK that arrives triggers either NewReno or SACK partial ACK handling which clamps snd_cwnd to be no larger than snd_ssthresh. In effect, the socket's send window is permamently stuck at 0 even though the remote peer is advertising a much larger window and pending data is only sent via TCP window probes (so one byte every few seconds). Fix this by adding a new TCP pcb flag (TF_PREVVALID) that indicates that the various snd_*_prev fields in the pcb are valid and only perform "bad retransmit recovery" if this flag is set in the pcb. The flag is set on the first retransmit timeout that occurs and is cleared on subsequent retransmit timeouts or when entering the persist state. Reviewed by: bz MFC after: 2 weeks Revision Changes Path 1.428 +4 -1 src/sys/netinet/tcp_input.c 1.178 +1 -0 src/sys/netinet/tcp_output.c 1.120 +3 -1 src/sys/netinet/tcp_timer.c 1.200 +1 -0 src/sys/netinet/tcp_var.h