Westwood算法控制的是在从快速恢复阶段退出时的拥塞窗口的值。原理上讲,这时的窗口值应该是一个不包括队列缓存在内的BDP,即最大带宽与最小RTT的乘积。
        问题是如何求最大带宽。
        标准的Westwood算法做的非常粗糙,它将一个TCP连接的生命周期分解为一段一段的采样周期,每一个采样周期内采集被ACK的字节数,然后除以采样周期的间隔,结果做低通滤波(其实就是移动指数平均),就是带宽。
        我们来看一下Westwood是如何在采样周期内采集ACK字节数的。
        然而,4.9版本之前的内核对于Linux的TCP实现,在开放给拥塞控制回调的接口中,只能通过当前的snd_una与上次记录的snd_una之间的差值来估算被ACK的字节数,说“估算”这个词的意思是,在拥塞控制回调中,关于SACK的信息会丢失。
        比如说收到一个ACK,如果它是重复的ACK,那么在拥塞控制回调中将无法取到任何其携带的SACK信息。虽然说一个重复的ACK可能携带了一大段SACK,然而对于拥塞控制回调而言,它看到的只是一个没有推进snd_una的ACK。本来,携带SACK的ACK段是想告诉拥塞模块对端其实收到了N个字节的数据,只不过没有按序,按照BDP的观点,这些乱序的数据也应该计入BDP的,然而却由于拥塞模块听不到这个信息而被忽略。我们来看一下这个逻辑:

static inline u32 westwood_acked_count(struct sock *sk)
{const struct tcp_sock *tp = tcp_sk(sk);struct westwood *w = inet_csk_ca(sk);w->cumul_ack = tp->snd_una - w->snd_una;/* If cumul_ack is 0 this is a dupack since it's not moving* tp->snd_una.*/if (!w->cumul_ack) {// 如果当前ACK是没有推进snd_una的重复ACK,仅计入一个段,忽略SACK带来的BDP排空。w->accounted += tp->mss_cache;w->cumul_ack = tp->mss_cache;}if (w->cumul_ack > tp->mss_cache) {/* Partial or delayed ack */if (w->accounted >= w->cumul_ack) {w->accounted -= w->cumul_ack;w->cumul_ack = tp->mss_cache;} else {w->cumul_ack -= w->accounted;w->accounted = 0;}}w->snd_una = tp->snd_una;return w->cumul_ack;
}

可见,上述针对ACK数据的计数是极其粗糙的!
        然而这不是Westwood的错,这是Linux TCP实现的错!

可以看到,只有在特定的点,才会进入外挂的拥塞控制模块的回调函数,对于在非Open的拥塞控制状态中,系统会调用私有的tcp_fastretrans_alert函数,该函数中就是例行的PRR降窗过程和重传逻辑了,无法被拥塞控制模块控制。

后来在Linux内核升级时,将重传逻辑从tcp_fastretrans_alert中剥离了出来,但是那只是代码结构的调整,整个非Open状态依然是拥塞控制模块所不能干预的。

也许你会说,可以在tcp_ca_event回调中进行非Open状态的拥塞控制,事实上Westwood等算法也是这么做的,但是即便如此,tcp_ca_event回调的传入参数依然无法满足Westwood的真实所需。但是BBR算法的引入,改变了这一切:

static void tcp_cong_control(struct sock *sk, u32 ack, u32 prior_in_flight, u32 acked_sacked,int flag, const struct rate_sample *rs)
{const struct inet_connection_sock *icsk = inet_csk(sk);// 新增了一个cong_control回调函数。在拥塞状态无关的情况下无条件接管所有的逻辑。if (icsk->icsk_ca_ops->cong_control) {icsk->icsk_ca_ops->cong_control(sk, rs);// 然后直接返回。return;}// 常规的逻辑。类似CUBIC等算法均会调用常规逻辑。if (tcp_in_cwnd_reduction(sk)) {/* Reduce cwnd if state mandates */tcp_cwnd_reduction(sk, acked_sacked, 1);} else if (tcp_may_raise_cwnd(sk, flag)) {/* Advance cwnd if state allows */tcp_cong_avoid(sk, ack, prior_in_flight);}tcp_update_pacing_rate(sk);
}

我认为,抛开BBR算法本身不谈,以上逻辑的引入是BBR为Linux TCP实现带来的最有价值礼物。这个大礼包中最重要的也许要算struct rate_sample参数了。我们看下这个参数包含什么:

/* A rate sample measures the number of (original/retransmitted) data* packets delivered "delivered" over an interval of time "interval_us".* The tcp_rate.c code fills in the rate sample, and congestion* control modules that define a cong_control function to run at the end* of ACK processing can optionally chose to consult this sample when* setting cwnd and pacing rate.* A sample is invalid if "delivered" or "interval_us" is negative.*/
struct rate_sample {struct    skb_mstamp prior_mstamp; /* starting timestamp for interval */u32  prior_delivered;    /* tp->delivered at "prior_mstamp" */s32  delivered;        /* number of packets delivered over interval */long interval_us;   /* time for tp->delivered to incr "delivered" */long rtt_us;        /* RTT of last (S)ACKed packet (or -1) */int  losses;        /* number of packets marked lost upon ACK */u32  acked_sacked;    /* number of packets newly (S)ACKed upon ACK */u32  prior_in_flight;   /* in flight before this ACK */bool is_app_limited;    /* is sample from packet with bubble in pipe? */bool is_retrans;    /* is sample from retransmission? */
};

已经携带了足够的注释,我就不解释了。对于Westwood而言,最重要的或许是acked_sacked参数了。
        好了,现在开始修改Westwood的实现:
1.去掉既有的带宽统计逻辑:

static void tcp_westwood_event(struct sock *sk, enum tcp_ca_event event)
{struct tcp_sock *tp = tcp_sk(sk);struct westwood *w = inet_csk_ca(sk);switch (event) {/** 不再需要*//*case CA_EVENT_FAST_ACK:westwood_fast_bw(sk);break;*/case CA_EVENT_COMPLETE_CWR:tp->snd_cwnd = tp->snd_ssthresh = tcp_westwood_bw_rttmin(sk);break;case CA_EVENT_LOSS:tp->snd_ssthresh = tcp_westwood_bw_rttmin(sk);/* Update RTT_min when next ack arrives */w->reset_rtt_min = 1;break;/** 不再需要*//*case CA_EVENT_SLOW_ACK:westwood_update_window(sk);w->bk += westwood_acked_count(sk);update_rtt_min(w);break;*/default:/* don't care */break;}
}

2.加入新的回调函数和新的带宽统计逻辑
2.1.加入一个新的回调

static struct tcp_congestion_ops tcp_westwood __read_mostly = {.init           = tcp_westwood_init,.ssthresh       = tcp_reno_ssthresh,.cong_collect   = westwood_collect,.cong_avoid     = tcp_reno_cong_avoid,...

添加一个新回调的用意在于不改变原有的BBR以及我修改过的CDG等算法的调用逻辑,因此在tcp_cong_control中需要增加对该回调的调用:

static void tcp_cong_control(struct sock *sk, u32 ack, u32 prior_in_flight, u32 acked_sacked,int flag, const struct rate_sample *rs)
{const struct inet_connection_sock *icsk = inet_csk(sk);// 新增了一个cong_control回调函数。在拥塞状态无关的情况下无条件接管所有的逻辑。if (icsk->icsk_ca_ops->cong_control) {icsk->icsk_ca_ops->cong_control(sk, rs);// 然后直接返回。return;}if (icsk->icsk_ca_ops->cong_collect) {icsk->icsk_ca_ops->cong_collect(sk, rs);// 并不返回。fall through!}// 常规的逻辑。类似CUBIC等算法均会调用常规逻辑。...
}

2.2.实现新增的回调

void westwood_collect(struct sock *sk, struct rate_sample *rs)
{struct tcp_sock *tp = tcp_sk(sk);struct westwood *w = inet_csk_ca(sk);westwood_update_window(sk);// 使用实实在在的acked_sacked计数,而不是估计计数w->bk += rs->acked_sacked * tp->mss_cache;update_rtt_min(w);}

以上就是对Westwood的修改,使它对带宽的统计更加精确。

更加精确的TCP Westwood拥塞控制算法相关推荐

  1. TCP协议拥塞控制算法(Reno、HSTCP、BIC、Vegas、Westwood)

    TCP协议拥塞控制算法(Reno.HSTCP.BIC.Vegas.Westwood) 一.TCP拥塞控制的研究框架 二.现有TCP拥塞控制的算法(Reno.HSTCP.Vegas.Westwood) ...

  2. TCP协议拥塞控制算法(Reno、HSTCP、BIC、Vegas、Westwood

    一.TCP拥塞控制的研究框架 二.现有TCP拥塞控制的算法(Reno.HSTCP.Vegas.Westwood) 三.参考文献 一.TCP拥塞控制的研究框架   注: l 基于丢包反馈:通过ACK所带 ...

  3. 「深度好文」TCP BBR拥塞控制算法深度解析

    linux服务器开发相关视频解析: tcpip,accept,11个状态,细枝末节的秘密,还有哪些你不知道 徒手实现网络协议栈,请准备好环境,一起来写代码 c/c++ linux服务器开发学习地址:c ...

  4. 来自Google的TCP BBR拥塞控制算法解析

    写本文的初衷一部分来自于工作,更多的来自于发现国内几乎还没有中文版的关于TCP bbr算法的文章,我想抢个沙发.本文写于2016/10/15!         本文的写作方式可能稍有不同,之前很多关于 ...

  5. Google的TCP BBR拥塞控制算法深度解析

    原作者:dog250,授权发布 重新整理:极客重生 hi ,大家好,今天推荐一篇我认为在TCP BBR技术里面分析非常透彻的文章,希望大家可以学习到一些真正的知识,理解其背后的设计原理,才能应对各种面 ...

  6. 个人感悟—来自Google的TCP BBR拥塞控制算法解析

    地址:TCR BBR拥塞控制算法另类解析 写本文的初衷一部分来自于工作,更多的来自于发现国内几乎还没有中文版的关于TCP bbr算法的文章,我想抢个沙发.本文写于2016/10/15! 本文的写作方式 ...

  7. tcp拥塞控制_网络TCP的拥塞控制算法简介

    作为网络中使用最广泛的传输协议,TCP的拥塞控制机制是学术界和工业界关注的焦点问题之.然而,目前广泛使用的TCP传输协议的拥塞控制算法仍然使用相对固定的窗口调节策略,无法根据动态变化的场景自适应地调整 ...

  8. 深入浅析TCP——TCP的拥塞控制算法

    TCP拥塞控制 一.TCP拥塞控制 二.TCP拥塞控制的算法 1.慢开始和拥塞避免 2.快重传和快恢复 一.TCP拥塞控制 若对网络中某一资源的需求超过了该资源所能提供的可用部分,网络的性能就要变坏, ...

  9. Google's BBR TCP拥塞控制算法的四个变速引擎

    台风海马来临前的两个几乎通宵的夜晚,我用一篇关于BBR算法的文章的迎接海马!公司在昨晚响应深圳市停工,停课号召,发布了在家办公(请注意,不是放假...)通知...其实吧,我觉得停电才是王道,你觉得呢? ...

  10. TCP拥塞控制算法纵横谈-Illinois和YeAH

    周五晚上,终于下了雨,所以也终于可以乱七八糟多写点松散的东西了... 方法论问题. 这个题目太大以至于内容和题目的关联看起来有失偏颇,不过也无所谓,既然被人以为"没有方法论"而鄙视 ...

最新文章

  1. Kubernetes Service(溪恒)
  2. antd如何获取表单的值_antd 父组件获取子组件中form表单的值
  3. python中list的运算,操作及实例
  4. python flask上传文件_Python-Flask-文件上传
  5. python爬取百度贴吧中的所有邮箱_python写的百度贴吧邮箱采集(带界面)
  6. 基于VMware Workstation创建虚拟机,以Ubuntu16.04为例
  7. Java RandomAccessFile skipBytes()方法与示例
  8. mysql中文乱码 go_Mysql binlog乱码问题研究-Go语言中文社区
  9. 学习产品型是否要满足人们的“懒”需求
  10. de4dot命令 v2.0.3.3405 破解命令
  11. 设置网页title旁边的小图标详解
  12. 服装erp系统的设计方案
  13. 如何制订IT安全审计计划
  14. 康耐视InSight软件电子表格视图功能介绍
  15. 家用洗地机有什么优缺点?入门级家用洗地机
  16. 视频剪辑工具,视频怎样批量加背景音乐和特效
  17. ISCC2021—小明的宠物兔、表情包
  18. cadence SPB17.4 - allegro - allegro_free_viewer
  19. 外来常驻人员使用计算机,在计算机终端上插入外来移动存储介质时,最合理的做法应该是()...
  20. 正式成为 Apache Teaclave 子项目,百度安全 Rust TrustZone SDK 赋能多平台隐私安全计算开源生态

热门文章

  1. “建木”萌芽,聚木成林
  2. com.itextpdf.text.exceptions.IllegalPdfSyntaxException: Unbalanced save/restore state operators
  3. JavaScript闭包,什么是闭包,对闭包的理解
  4. 公众号600篇文章分类和索引
  5. The projiect you are opening contains compilation errors
  6. kali的vmtool工具安装
  7. oracle提高delete的效率,提高Oracle DELETE性能的策略
  8. C++中的悬垂指针(delete指针后依然可以访问的问题)
  9. CrystalDiskInfo 各项参数说明
  10. 求顺序表的交集和并集