首先让我为大家介绍一下这个问题的背景知识。
典型TCP数据包有一个最大窗口大小为64KB的窗口域。这在因特网发展初期,大部分系统都没有能力处理比这更大的数据,因此这个大小是足够的,但是对于现在的接入带宽应用来说,这已经太小了。
为了解决这个问题,1992年提出了一种称为窗口缩放的解决方案,它提供了一个额外的TCP窗口扩大选项,该选项包含一个8位的扩大因子。这个选项 的值指定了窗口应该多大,它是由通过滑动几个比特的窗口大小值来实现的。例如,如果扩大因子设定为5,那么窗口大小应该移动5个比特或乘以32。
窗口扩大选项使TCP的窗口定义从16位增加到32位,这并不是通过修改TCP首部来实现的,TCP首部仍然使用16位,而是通过定义一个选项实现对16位的扩大操作来完成的。
在2.6.16和更早内核中默认扩大因子为0,所以没有增加窗口大小。在2.6.17内核中,扩大因子被设定为7。理想的情况下,这不会有什么问题。但实际上,一些“坏掉”的路由器会重写窗口缩放TCP选项——将扩大因子设定为0但是实际处理能力选项却没有改变。
本质上,这意味着有一些网站使用2.6.17和更高内核的系统将会连接不上。从内核开发人员的立场看他们会认为那些路由器是坏掉的需要进行替换。实际上,这些路由器在修理或替换前可能还可以继续使用好多年。
解决这个问题的一个方法是重新设置Linux内核的窗口缩放选项。虽然这不会修复坏掉的路由器,但是如果你正受到窗口缩放问题的影响,该方法可以使你的系统连接到远程站点。
解决办法,可以编辑/etc/sysctl.conf文件,添加下面一句:
1 | net.ipv4.tcp_window_scaling = 0 |
把前面的#干掉
这将完全禁用窗口缩放功能,这将允许你连接到一些以前不能连接的站点。无论正确还是错误,内核开发人员拒绝恢复这个改变,因此使用该选项既可以禁用 你自己的窗口缩放功能以回到2.6.17以前的默认设置,也可以连接到那些不能到达的站点并使他们确信因该查找并替换坏掉的路由器。