zoukankan      html  css  js  c++  java
  • TCP的初始cwnd和ssthresh

    概述

    linux 3.0以前,内核默认的initcwnd比较小,MSS为1460时,初始的拥塞控制窗口为3。
    linux3.0以后,采取了Google的建议,把初始拥塞控制窗口调到了10。
    Google's advice :《An Argument for Increasing TCP's Initial Congestion Window》
    The recommended value of initcwnd is 10*MSS.

    内核版本:linux-2.6.37

     

    dst_entry

    目的入口dst_entry反映了相邻的外部主机在主机内部的一种映像。
    A dst_entry corresponds to the destination host bound to the socket.
    A dst_entry object stores a lot of data used by the kernel whenever it sends a packet to
    the corresponding remote host.

    __u32 tcp_init_cwnd(struct tcp_sock *tp, struct dst_entry *dst)
    {
        /* 取出路由中的initcwnd */
        __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0);
    
        /* 如果没有路由信息的话 */
        if (! cwnd)
            cwnd = rfc3390_bytes_to_packets(tp->mss_cache);
    
        /* 不能超过snd_cwnd的最大值:snd_cwnd_clamp */
        return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
    }

    根据MSS来决定initcwnd:
    (1)MSS <= 1095,initcwnd = 4
    (2)1095 < MSS <= 2190,initcwnd = 3
    (3)MSS > 2190,initcwnd = 2

    /* Convert RFC3390 larger initial window into an equivalent number of packets.
     * This is based on the numbers specified in RFC 6861, 3.1.
     */
    static inline u32 rfc3390_bytes_to_packets(const u32 smss)
    {
        return smss <= 1095 ? 4 : (smss > 2190 ? 2 : 3);
    }

    一般我们的MSS为1460,所以内核默认的TCP初始拥塞控制窗口为3。

    内核版本:linux 3.2.12

     

    内核初始的慢启动阈值(ssthresh)

    /* 初始的慢启动阈值为无穷大*/
    #define TCP_INFINITE_SSTHRESH 0x7fffffff
    
    /* 根据慢启动阈值来判断是否处于初始的慢启动阶段*/
    static inline bool tcp_in_initial_slowstart(const struct tcp_sock *tp)
    {
        return tp->snd_ssthresh >= TCP_INFINITE_SSTHRESH;
    }

    内核初始的拥塞窗口(initcwnd)

    #define TCP_INIT_CWND 10
    
    __u32 tcp_init_cwnd(const struct tcp_sock *tp, const struct dst_entry *dst)
    {
        /* 取出路由中的initcwnd */
        __u32 cwnd = (dst ? dst_metric(dst, RTAX_INITCWND) : 0);
    
        /* 如果没有相关的路由,则把初始值设为10 */
        if (! cwnd) 
            cwnd = TCP_INIT_CWND;
    
        /* 不能超过snd_cwnd的最大值:snd_cwnd_clamp */
        return min_t(__u32, cwnd, tp->snd_cwnd_clamp);
    }

    设置初始的ssthresh和cwnd

    (1)ip route方法,对通过此路由的TCP连接有效。
    设置:ip route change default via <gateway> dev <eth0> initcwnd <value1> ssthresh <value2>
    查看:ip route show
    注意:In order to make it effective after a reboot, you can place above line in /etc/rc.local.

    (2)sysctl方法,对所有的TCP连接有效。
    在内核中增加一个控制initcwnd的proc参数,/proc/sys/net/ipv4/tcp_initcwnd。 

    ip route是通过netlink来修改dst_entry中RTAX_INITCWND对应的值,而sysctl则可以直接在内核中
    增加一个变量,它们都需要通过tcp_init_cwnd()来改变initcwnd。

  • 相关阅读:
    destoon自定义函数获取地区名称
    dt开发之-自定义函数获取分类名称
    dt二次开发之-地区链接伪静态标签用法
    DT二次开发之-采购页面加入好看的倒计时
    DT二次开发之-资讯列表中调用 TAG 关键词
    DT系统中tag如何使用like与%来进行模糊查询
    如何防护DDOS攻击策略
    织梦阿里云OSS解决方案
    漫画解读“跨视图粒度计算”,了解有数分析利器
    [译] 关于 SPA,你需要掌握的 4 层 (1)
  • 原文地址:https://www.cnblogs.com/aiwz/p/6333380.html
Copyright © 2011-2022 走看看