Very slow or dying Internet connection to some hosts

I you have very slow (or quickly dying) connection to selected hosts and they work normally from other machines/systems you may be experiencing broken TCP window scaling on a host that is on the route between you and the target machine.

The slow connection often gets noticed after recent system/kernel upgrade, or after adding more RAM to the system.

Problem is that Linux kernel’s window scaling parameters depends on the amount of system RAM, and other factors, so while old system could keep the TCP window size small, new may grow it more (i.e. for overseas connection), and broken boxes that mishandle window scaling parameter, effectively blocks the connection with large TCP window size. Notice that window scaling parameter changes during the TCP transfer, thus connection can start well, and got broken after some time.

To check if your connection is affected by this problem you can temporarily disable window scaling with:

as root

echo 0 > /proc/sys/net/ipv4/tcp_window_scaling

Another proposed workaround is to limit maximal window size with:

as root

echo 4096 16384 131072 > /proc/sys/net/ipv4/tcp_wmem
echo 4096 87380 174760 > /proc/sys/net/ipv4/tcp_rmem

It is also possible to make these limitations only for a selected broken route (not to limit connection performance for entry system):

There are black box devices out there, routers and firewalls and whatnot, that simply cannot grok the TCP window scaling option correctly.

People should and do bark at the site running the device causing the problems, but in the mean time folks do want a way to deal with the problem. We don’t want them to turn off window scaling completely as that hurts performance of connections that would run just fine with window scaling enabled.

So give a way to do this on a per-route basis by limiting the window scaling by the per-connection window clamp. Stephen’s changelog message explains how to do this using a route metric.

as root

ip route add via window 65535

You can make any of these workarounds permanent, by adding those lines to your /etc/rc.local file.


Post Scriptum: this is an import of information that I wrote a while ago. Things might have changed since then.

This entry was posted in Linux and tagged , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>