From owner-freebsd-net@FreeBSD.ORG Thu May 10 18:15:11 2007 Return-Path: X-Original-To: freebsd-net@freebsd.org Delivered-To: freebsd-net@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id B0AC616A403 for ; Thu, 10 May 2007 18:15:11 +0000 (UTC) (envelope-from cjharrer@comcast.net) Received: from sccrmhc13.comcast.net (sccrmhc13.comcast.net [63.240.77.83]) by mx1.freebsd.org (Postfix) with ESMTP id 7478713C448 for ; Thu, 10 May 2007 18:15:11 +0000 (UTC) (envelope-from cjharrer@comcast.net) Received: from record (h-68-164-177-211.phlapafg.covad.net[68.164.177.211]) by comcast.net (sccrmhc13) with SMTP id <20070510180231013009hehre>; Thu, 10 May 2007 18:02:31 +0000 From: "Chris Harrer" To: Date: Thu, 10 May 2007 14:02:33 -0400 Message-ID: <001001c7932d$6311f0c0$ac01020a@record> MIME-Version: 1.0 X-Mailer: Microsoft Office Outlook 11 X-MimeOLE: Produced By Microsoft MimeOLE V6.00.2900.3028 Thread-Index: AceTLWJH8/C6OVoWQ4ShHkXil40HBA== Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit X-Content-Filtered-By: Mailman/MimeDel 2.1.5 Subject: RELENG 6.2 Slow Start Question 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, 10 May 2007 18:15:11 -0000 Hello All, This is my first time posting a message to this list, so please excuse me if this is not an appropriate message for this list (if it is inappropriate, could you please direct me to a more appropriate place?). I've been looking at some slow start code in the FreeBSD 6.2 RELENG, in particular the following block that increments the CWND in Ack processing: 2128 /* 2129 * When new data is acked, open the congestion window. 2130 * If the window gives us less than ssthresh packets 2131 * in flight, open exponentially (maxseg per packet). 2132 * Otherwise open linearly: maxseg per window 2133 * (maxseg^2 / cwnd per packet). 2134 */ 2135 if ((!tcp_do_newreno && !tp ->sack_enable) || 2136 !IN_FASTRECOVERY (tp )) { 2137 register u_int cw = tp ->snd_cwnd; 2138 register u_int incr = tp ->t_maxseg; 2139 if (cw > tp ->snd_ssthresh) 2140 incr = incr * incr / cw; 2141 tp ->snd_cwnd = min (cw+incr, TCP_MAXWIN < ->snd_scale); 2142 } Assume this connection is just opened, CWND has an initial value of 2920 and snd_ssthresh is sufficiently big (for this example, use 17500). A write is given to TCP of length 8760 bytes. Tcp_output determines it can send the first 2920 bytes of that write based on snd_cwnd and does so. A single ACK is received that ACK's all 2920 bytes of data, in looking at the code above, tp->snd_cwnd would get set to 4380 (assuming a t_maxseg of 1460). This is in contrast to the description in Steven's Volume 1 regarding slow start increasing the window exponentially, as well as the description in RFC 2581 whereby I would expect tp->snd_cwnd to be set to 5840. After processing the ACK, tcp_output would send 3 new full segments as opposed to 4 (i.e., all of the remaining data) which I would expect. This seems obviously wrong to me, but it's code that always been there. I'd like to understand where my analysis goes wrong or why it's acceptable for the call to tcp_output (after the acking of the first 2920 bytes of data) to only send 3 packets as opposed to completing the transmission of the write in two calls to tcp_output. Thanks very much. Chris