TCP的初始cwnd和ssthresh

来源:互联网 发布:mac没有iphoto 编辑:程序博客网 时间:2024/06/18 17:22

概述

 

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。

 

 

原创粉丝点击