Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 22 Feb 2000 14:46:07 -0800 (PST)
From:      jayanth@yahoo.com
To:        freebsd-gnats-submit@FreeBSD.org
Subject:   kern/16914: tcp advertises wrong window if tcpsendspace and tcprecvspace are set to 64K
Message-ID:  <200002222246.OAA19268@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help

>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




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200002222246.OAA19268>