[PATCH] fix tcp_default_win_scale.

From: Stephen Hemminger
Date: Tue Jul 06 2004 - 13:48:54 EST


Recent TCP changes exposed the problem that there ar lots of really broken firewalls
that strip or alter TCP options.
When the options are modified TCP gets busted now. The problem is that when
we propose window scaling, we expect that the other side receives the same initial
SYN request that we sent. If there is corrupting firewalls that strip it then
the window we send is not correctly scaled; so the other side thinks there is not
enough space to send.

I propose that the following that will avoid sending window scaling that
is big enough to break in these cases unless the tcp_rmem has been increased.
It will keep default configuration from blowing in a corrupt world.

Signed-off-by: Stephen Hemminger <shemminger@xxxxxxxx>

diff -Nru a/include/linux/sysctl.h b/include/linux/sysctl.h
--- a/include/linux/sysctl.h 2004-07-06 11:45:18 -07:00
+++ b/include/linux/sysctl.h 2004-07-06 11:45:18 -07:00
@@ -337,7 +337,7 @@
NET_TCP_BIC=102,
NET_TCP_BIC_FAST_CONVERGENCE=103,
NET_TCP_BIC_LOW_WINDOW=104,
- NET_TCP_DEFAULT_WIN_SCALE=105,
+/* NET_TCP_DEFAULT_WIN_SCALE */
NET_TCP_MODERATE_RCVBUF=106,
};

diff -Nru a/include/net/tcp.h b/include/net/tcp.h
--- a/include/net/tcp.h 2004-07-06 11:45:18 -07:00
+++ b/include/net/tcp.h 2004-07-06 11:45:18 -07:00
@@ -611,7 +611,6 @@
extern int sysctl_tcp_bic;
extern int sysctl_tcp_bic_fast_convergence;
extern int sysctl_tcp_bic_low_window;
-extern int sysctl_tcp_default_win_scale;
extern int sysctl_tcp_moderate_rcvbuf;

extern atomic_t tcp_memory_allocated;
@@ -1690,6 +1689,13 @@
*ptr++ = htonl((TCPOPT_NOP << 24) | (TCPOPT_WINDOW << 16) | (TCPOLEN_WINDOW << 8) | (wscale));
}

+/* Default window scaling based on the size of the maximum window */
+static inline __u8 tcp_default_win_scale(void)
+{
+ int b = ffs(sysctl_tcp_rmem[2]);
+ return (b < 17) ? 0 : b-16;
+}
+
/* Determine a window scaling and initial window to offer.
* Based on the assumption that the given amount of space
* will be offered. Store the results in the tp structure.
@@ -1732,8 +1738,7 @@
space - max((space>>sysctl_tcp_app_win), mss>>*rcv_wscale) < 65536/2)
(*rcv_wscale)--;

- *rcv_wscale = max((__u8)sysctl_tcp_default_win_scale,
- *rcv_wscale);
+ *rcv_wscale = max(tcp_default_win_scale(), *rcv_wscale);
}

/* Set initial window to value enough for senders,
diff -Nru a/net/ipv4/sysctl_net_ipv4.c b/net/ipv4/sysctl_net_ipv4.c
--- a/net/ipv4/sysctl_net_ipv4.c 2004-07-06 11:45:18 -07:00
+++ b/net/ipv4/sysctl_net_ipv4.c 2004-07-06 11:45:18 -07:00
@@ -667,14 +667,6 @@
.proc_handler = &proc_dointvec,
},
{
- .ctl_name = NET_TCP_DEFAULT_WIN_SCALE,
- .procname = "tcp_default_win_scale",
- .data = &sysctl_tcp_default_win_scale,
- .maxlen = sizeof(int),
- .mode = 0644,
- .proc_handler = &proc_dointvec,
- },
- {
.ctl_name = NET_TCP_MODERATE_RCVBUF,
.procname = "tcp_moderate_rcvbuf",
.data = &sysctl_tcp_moderate_rcvbuf,
diff -Nru a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c 2004-07-06 11:45:18 -07:00
+++ b/net/ipv4/tcp.c 2004-07-06 11:45:18 -07:00
@@ -276,8 +276,6 @@

atomic_t tcp_orphan_count = ATOMIC_INIT(0);

-int sysctl_tcp_default_win_scale = 7;
-
int sysctl_tcp_mem[3];
int sysctl_tcp_wmem[3] = { 4 * 1024, 16 * 1024, 128 * 1024 };
int sysctl_tcp_rmem[3] = { 4 * 1024, 87380, 87380 * 2 };
-
To unsubscribe from this list: send the line "unsubscribe linux-net" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at http://vger.kernel.org/majordomo-info.html