标准的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的,然而却由于拥塞模块听不到这个信息而被忽略。
我们来看一下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的,然而却由于拥塞模块听不到这个信息而被忽略。