Files
netstack/tcpip/transport/tcp/reno.go
2022-12-19 18:40:12 +08:00

79 lines
2.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package tcp
import "netstack/logger"
type renoState struct {
s *sender
}
// 新建reno算法对象
func newRenoCC(s *sender) *renoState {
return &renoState{s: s}
}
// updateSlowStart 将根据NewReno使用的慢启动算法更新拥塞窗口。
// 如果在调整拥塞窗口后我们越过了 SSthreshold ,那么它将返回在拥塞避免模式下必须消耗的数据包的数量。
func (r *renoState) updateSlowStart(packetsAcked int) int {
// 在慢启动阶段每次收到acksndCwnd加上已确认的段数
newcwnd := r.s.sndCwnd + packetsAcked
// 判断增大过后的拥塞窗口是否超过慢启动阀值 sndSsthresh
// 如果超过 sndSsthresh ,将窗口调整为 sndSsthresh
if newcwnd >= r.s.sndSsthresh {
newcwnd = r.s.sndSsthresh
r.s.sndCAAckCount = 0
}
// 是否超过 sndSsthresh packetsAcked>0表示超过 没超过就是0
packetsAcked -= newcwnd - r.s.sndCwnd
// 更新拥塞窗口
r.s.sndCwnd = newcwnd
logger.NOTICE("慢启动中。。。 reno Update 新的拥塞窗口大小: ", atoi(r.s.sndCwnd))
return packetsAcked
}
// updateCongestionAvoidance 将在拥塞避免模式下更新拥塞窗口,
// 如RFC5681第3.1节所述
func (r *renoState) updateCongestionAvoidance(packetsAcked int) {
logger.FIXME("超过阈值后调整拥塞窗口 拥塞避免阶段")
}
// 当检测到网络拥塞时,调用 reduceSlowStartThreshold。
// 它将 sndSsthresh 变为 outstanding 的一半。
// sndSsthresh 最小为2因为至少要比丢包后的拥塞窗口cwnd=1来的大才会进入慢启动阶段。
func (r *renoState) reduceSlowStartThreshold() {
r.s.sndSsthresh = r.s.sndSsthresh/2
if r.s.sndSsthresh < 2 {
r.s.sndSsthresh = 2
}
}
// HandleNDupAcks implements congestionControl.HandleNDupAcks.
// 当收到三个重复ack时调用 HandleNDupAcks 来处理。
func (r *renoState) HandleNDupAcks() {
// A retransmit was triggered due to nDupAckThreshold
// being hit. Reduce our slow start threshold.
// 减小慢启动阀值
r.reduceSlowStartThreshold()
}
func (r *renoState) HandleRTOExpired() {
}
// packetsAcked 已经确认过的数据段数
func (r *renoState) Update(packetsAcked int) {
// 当拥塞窗口没有超过慢启动阀值的时候,使用慢启动来增大窗口,
// 否则进入拥塞避免阶段
if r.s.sndCwnd < r.s.sndSsthresh {
packetsAcked = r.updateSlowStart(packetsAcked)
if packetsAcked == 0 {
return
}
}
// 进入拥塞避免阶段
r.updateCongestionAvoidance(packetsAcked)
}
func (r *renoState) PostRecovery() {
// 不需要实现
}