From owner-freebsd-bugs Tue Feb 22 14:50:13 2000 Delivered-To: freebsd-bugs@freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id CC53037B760 for ; Tue, 22 Feb 2000 14:50:00 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id OAA19542; Tue, 22 Feb 2000 14:50:00 -0800 (PST) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.FreeBSD.ORG [204.216.27.21]) by hub.freebsd.org (Postfix) with ESMTP id 371F837B574 for ; Tue, 22 Feb 2000 14:46:07 -0800 (PST) (envelope-from nobody@FreeBSD.org) Received: (from nobody@localhost) by freefall.freebsd.org (8.9.3/8.9.2) id OAA19268; Tue, 22 Feb 2000 14:46:07 -0800 (PST) (envelope-from nobody@FreeBSD.org) Message-Id: <200002222246.OAA19268@freefall.freebsd.org> Date: Tue, 22 Feb 2000 14:46:07 -0800 (PST) From: jayanth@yahoo.com To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-1.0 Subject: kern/16914: tcp advertises wrong window if tcpsendspace and tcprecvspace are set to 64K Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk X-Loop: FreeBSD.org >Number: 16914 >Category: kern >Synopsis: tcp advertises wrong window if tcpsendspace and tcprecvspace are set to 64K >Confidential: no >Severity: serious >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: sw-bug >Submitter-Id: current-users >Arrival-Date: Tue Feb 22 14:50:00 PST 2000 >Closed-Date: >Last-Modified: >Originator: Jayanth Vijayaraghavan >Release: 4.0-CURRENT >Organization: Yahoo! >Environment: FreeBSD 4.0-CURRENT cvsupped on Feb 2 >Description: There seems to be a certain condition where tcp advertises the wrong window size when the tcpsendspace and tcprecvspace value are set to a value = 65536(>65000 ) Assume rfc1323 is off. Went through the code and found that in tcp_input.c in tcp_mss() the following code bumps the value from 65536 to 65700 tcp_mss() --------- #ifdef RTV_RPIPE if ((bufsize = rt->rt_rmx.rmx_recvpipe) == 0) #endif bufsize = so->so_rcv.sb_hiwat; if (bufsize > mss) { bufsize = roundup(bufsize, mss); ^^^^^^^^^^^^^^^^^^^^^^^^^^^ if (bufsize > sb_max) bufsize = sb_max; (void)sbreserve(&so->so_rcv, bufsize); If the keepalive timer expires the tcp_respond() uses the sbspace(so->so_rcv) to determine the window size. tcp_respond() ------------ ti->ti_win = htons((u_short) (win >> tp->rcv_scale)); else ti->ti_win = htons((u_short)win); ti->ti_win is cast to a unsigned short resulting in the wrap around 65700 - 65336 = 164 which is the advertised window size.. The problem occurs if the roundup result is greater than 65536. >How-To-Repeat: set tcpsendspace and tcprecvspace to 65536. turn rfc1323 off. Turn keepalive on and open a connection. Send some data and let the connection be idle. let the keepalive timer expire at the server end. tcp now advertises a window size of 164 instead of the original window size. >Fix: The fix is to limit the maximum permissible TCP window size to 65535 octets if window scaling is disabled. --- tcp_subr.c Tue Feb 22 14:33:26 2000 +++ tcp_subr.c.new Tue Feb 22 14:09:10 2000 @@ -314,8 +314,11 @@ ipov = ipgen; if (tp) { - if (!(flags & TH_RST)) + if (!(flags & TH_RST)){ win = sbspace(&tp->t_inpcb->inp_socket->so_rcv); + if (win > (long)TCP_MAXWIN << tp->rcv_scale) + win = (long)TCP_MAXWIN << tp->rcv_scale; + } #ifdef INET6 if (isipv6) ro6 = &tp->t_inpcb->in6p_route; >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message