From d63e75f696168fa2b66e53e1f958ca33c16a71ff Mon Sep 17 00:00:00 2001 From: rmind Date: Sun, 4 Nov 2007 11:04:26 +0000 Subject: [PATCH] Pick the smallest possible TCP window scaling factor that will still allow us to scale up to sb_max. This might fix the problems with some firewalls. Taken from FreeBSD (silby). OK by . --- sys/netinet/tcp_input.c | 26 ++++++++++++++++++-------- sys/netinet/tcp_usrreq.c | 11 +++++------ 2 files changed, 23 insertions(+), 14 deletions(-) diff --git a/sys/netinet/tcp_input.c b/sys/netinet/tcp_input.c index 798b5fe5e400..25f15c648941 100644 --- a/sys/netinet/tcp_input.c +++ b/sys/netinet/tcp_input.c @@ -1,4 +1,4 @@ -/* $NetBSD: tcp_input.c,v 1.270 2007/08/02 13:06:30 yamt Exp $ */ +/* $NetBSD: tcp_input.c,v 1.271 2007/11/04 11:04:26 rmind Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -152,7 +152,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.270 2007/08/02 13:06:30 yamt Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tcp_input.c,v 1.271 2007/11/04 11:04:26 rmind Exp $"); #include "opt_inet.h" #include "opt_ipsec.h" @@ -4086,17 +4086,27 @@ syn_cache_add(struct sockaddr *src, struct sockaddr *dst, struct tcphdr *th, sc->sc_requested_s_scale = tb.requested_s_scale; sc->sc_request_r_scale = 0; /* - * Compute proper scaling value from buffer space. - * Leave enough room for the socket buffer to grow - * with auto sizing. This allows us to scale the - * receive buffer over a wide range while not losing - * any efficiency or fine granularity. + * Pick the smallest possible scaling factor that + * will still allow us to scale up to sb_max. + * + * We do this because there are broken firewalls that + * will corrupt the window scale option, leading to + * the other endpoint believing that our advertised + * window is unscaled. At scale factors larger than + * 5 the unscaled window will drop below 1500 bytes, + * leading to serious problems when traversing these + * broken firewalls. + * + * With the default sbmax of 256K, a scale factor + * of 3 will be chosen by this algorithm. Those who + * choose a larger sbmax should watch out + * for the compatiblity problems mentioned above. * * RFC1323: The Window field in a SYN (i.e., a * or ) segment itself is never scaled. */ while (sc->sc_request_r_scale < TCP_MAX_WINSHIFT && - (0x1 << sc->sc_request_r_scale) < tcp_minmss) + (TCP_MAXWIN << sc->sc_request_r_scale) < sb_max) sc->sc_request_r_scale++; } else { sc->sc_requested_s_scale = 15; diff --git a/sys/netinet/tcp_usrreq.c b/sys/netinet/tcp_usrreq.c index 22c48e262b05..72337e8dd84c 100644 --- a/sys/netinet/tcp_usrreq.c +++ b/sys/netinet/tcp_usrreq.c @@ -1,4 +1,4 @@ -/* $NetBSD: tcp_usrreq.c,v 1.137 2007/09/19 04:33:44 dyoung Exp $ */ +/* $NetBSD: tcp_usrreq.c,v 1.138 2007/11/04 11:04:27 rmind Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -102,7 +102,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.137 2007/09/19 04:33:44 dyoung Exp $"); +__KERNEL_RCSID(0, "$NetBSD: tcp_usrreq.c,v 1.138 2007/11/04 11:04:27 rmind Exp $"); #include "opt_inet.h" #include "opt_ipsec.h" @@ -431,12 +431,11 @@ tcp_usrreq(struct socket *so, int req, break; } /* - * Compute window scaling to request: - * XXX: This should be moved to tcp_output(), - * and should be based on the actual MSS. + * Compute window scaling to request. + * XXX: This should be moved to tcp_output(). */ while (tp->request_r_scale < TCP_MAX_WINSHIFT && - (0x1 << tp->request_r_scale) < tcp_minmss) + (TCP_MAXWIN << tp->request_r_scale) < sb_max) tp->request_r_scale++; soisconnecting(so); tcpstat.tcps_connattempt++;