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 <dyoung>.
This commit is contained in:
rmind 2007-11-04 11:04:26 +00:00
parent 89eb056b33
commit d63e75f696
2 changed files with 23 additions and 14 deletions

View File

@ -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. * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -152,7 +152,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__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_inet.h"
#include "opt_ipsec.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_requested_s_scale = tb.requested_s_scale;
sc->sc_request_r_scale = 0; sc->sc_request_r_scale = 0;
/* /*
* Compute proper scaling value from buffer space. * Pick the smallest possible scaling factor that
* Leave enough room for the socket buffer to grow * will still allow us to scale up to sb_max.
* with auto sizing. This allows us to scale the *
* receive buffer over a wide range while not losing * We do this because there are broken firewalls that
* any efficiency or fine granularity. * 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 <SYN> * RFC1323: The Window field in a SYN (i.e., a <SYN>
* or <SYN,ACK>) segment itself is never scaled. * or <SYN,ACK>) segment itself is never scaled.
*/ */
while (sc->sc_request_r_scale < TCP_MAX_WINSHIFT && 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++; sc->sc_request_r_scale++;
} else { } else {
sc->sc_requested_s_scale = 15; sc->sc_requested_s_scale = 15;

View File

@ -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. * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@ -102,7 +102,7 @@
*/ */
#include <sys/cdefs.h> #include <sys/cdefs.h>
__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_inet.h"
#include "opt_ipsec.h" #include "opt_ipsec.h"
@ -431,12 +431,11 @@ tcp_usrreq(struct socket *so, int req,
break; break;
} }
/* /*
* Compute window scaling to request: * Compute window scaling to request.
* XXX: This should be moved to tcp_output(), * XXX: This should be moved to tcp_output().
* and should be based on the actual MSS.
*/ */
while (tp->request_r_scale < TCP_MAX_WINSHIFT && 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++; tp->request_r_scale++;
soisconnecting(so); soisconnecting(so);
tcpstat.tcps_connattempt++; tcpstat.tcps_connattempt++;