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。

 

 

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
根据题意,可以得到以下信息: 初始 ssthresh = 8 在第 1 次传输时,使用慢启动,cwnd = 1,ssthresh 不变 在第 2 次传输时,使用慢启动,cwnd = 2,ssthresh 不变 在第 3 次传输时,使用慢启动,cwnd = 4,ssthresh 不变 在第 4 次传输时,使用慢启动,cwnd = 8,ssthresh 不变 在第 5 次传输时,使用拥塞避免,cwnd = 9,ssthresh = 8 在第 6 次传输时,使用拥塞避免,cwnd = 10,ssthresh = 8 在第 7 次传输时,使用拥塞避免,cwnd = 11,ssthresh = 8 在第 8 次传输时,使用拥塞避免,cwnd = 12,ssthresh = 8 在第 9 次传输时,发生超时,ssthresh = cwnd / 2 = 6,cwnd = 1,重新进入慢启动 在第 10 次传输时,使用慢启动,cwnd = 2,ssthresh = 6 在第 11 次传输时,使用慢启动,cwnd = 4,ssthresh = 6 在第 12 次传输时,使用慢启动,cwnd = 6,ssthresh = 6 在第 13 次传输时,使用拥塞避免,cwnd = 7,ssthresh = 6 在第 14 次传输时,使用拥塞避免,cwnd = 8,ssthresh = 6 在第 15 次传输时,使用拥塞避免,cwnd = 9,ssthresh = 6 每当发生超时,ssthresh 被设置为当前拥塞窗口的一半(cwnd/2),同时将拥塞窗口的大小设置为1,然后重新进入慢启动;每当拥塞窗口大小达到ssthresh时,拥塞控制算法就从慢启动模式转换为拥塞避免模式,此时每经过一个往返时间RTT,cwnd增加1,直到再次发生超时或者接收到3个冗余ACK,此时ssthresh被设置为当前拥塞窗口的一半,并将cwnd设置为ssthresh,然后重新进入慢启动。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值