mirror of https://github.com/v2ray/v2ray-core
refine congestion control
parent
8ea3c13236
commit
d1d153acb9
|
@ -16,12 +16,13 @@ type SendingWindow struct {
|
||||||
prev []uint32
|
prev []uint32
|
||||||
next []uint32
|
next []uint32
|
||||||
|
|
||||||
inFlightSize uint32
|
inFlightSize uint32
|
||||||
writer SegmentWriter
|
totalInFlightSize uint32
|
||||||
onPacketLoss func(bool)
|
writer SegmentWriter
|
||||||
|
onPacketLoss func(uint32)
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewSendingWindow(size uint32, inFlightSize uint32, writer SegmentWriter, onPacketLoss func(bool)) *SendingWindow {
|
func NewSendingWindow(size uint32, inFlightSize uint32, writer SegmentWriter, onPacketLoss func(uint32)) *SendingWindow {
|
||||||
window := &SendingWindow{
|
window := &SendingWindow{
|
||||||
start: 0,
|
start: 0,
|
||||||
cap: size,
|
cap: size,
|
||||||
|
@ -72,6 +73,7 @@ func (this *SendingWindow) Remove(idx uint32) {
|
||||||
if seg == nil {
|
if seg == nil {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
this.totalInFlightSize--
|
||||||
seg.Release()
|
seg.Release()
|
||||||
this.data[pos] = nil
|
this.data[pos] = nil
|
||||||
if pos == this.start && pos == this.last {
|
if pos == this.start && pos == this.last {
|
||||||
|
@ -117,7 +119,7 @@ func (this *SendingWindow) Flush(current uint32, resend uint32, rto uint32) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lost := false
|
var lost uint32
|
||||||
var inFlightSize uint32
|
var inFlightSize uint32
|
||||||
|
|
||||||
for i := this.start; ; i = this.next[i] {
|
for i := this.start; ; i = this.next[i] {
|
||||||
|
@ -127,17 +129,17 @@ func (this *SendingWindow) Flush(current uint32, resend uint32, rto uint32) {
|
||||||
needsend = true
|
needsend = true
|
||||||
segment.transmit++
|
segment.transmit++
|
||||||
segment.timeout = current + rto
|
segment.timeout = current + rto
|
||||||
|
this.totalInFlightSize++
|
||||||
} else if _itimediff(current, segment.timeout) >= 0 {
|
} else if _itimediff(current, segment.timeout) >= 0 {
|
||||||
needsend = true
|
needsend = true
|
||||||
segment.transmit++
|
segment.transmit++
|
||||||
segment.timeout = current + rto
|
segment.timeout = current + rto
|
||||||
lost = true
|
lost++
|
||||||
} else if segment.ackSkipped >= resend {
|
} else if segment.ackSkipped >= resend {
|
||||||
needsend = true
|
needsend = true
|
||||||
segment.transmit++
|
segment.transmit++
|
||||||
segment.ackSkipped = 0
|
segment.ackSkipped = 0
|
||||||
segment.timeout = current + rto
|
segment.timeout = current + rto
|
||||||
lost = true
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if needsend {
|
if needsend {
|
||||||
|
@ -152,7 +154,10 @@ func (this *SendingWindow) Flush(current uint32, resend uint32, rto uint32) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.onPacketLoss(lost)
|
if inFlightSize > 0 && this.totalInFlightSize != 0 {
|
||||||
|
rate := lost * 100 / this.totalInFlightSize
|
||||||
|
this.onPacketLoss(rate)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
type SendingQueue struct {
|
type SendingQueue struct {
|
||||||
|
@ -282,7 +287,7 @@ func (this *SendingWorker) ProcessSegment(seg *AckSegment) {
|
||||||
for i := 0; i < int(seg.Count); i++ {
|
for i := 0; i < int(seg.Count); i++ {
|
||||||
timestamp := seg.TimestampList[i]
|
timestamp := seg.TimestampList[i]
|
||||||
number := seg.NumberList[i]
|
number := seg.NumberList[i]
|
||||||
if this.kcp.current-timestamp > 10000 {
|
if this.kcp.current-timestamp < 10000 {
|
||||||
this.kcp.update_ack(int32(this.kcp.current - timestamp))
|
this.kcp.update_ack(int32(this.kcp.current - timestamp))
|
||||||
}
|
}
|
||||||
this.ProcessAck(number)
|
this.ProcessAck(number)
|
||||||
|
@ -335,14 +340,14 @@ func (this *SendingWorker) PingNecessary() bool {
|
||||||
return this.updated
|
return this.updated
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *SendingWorker) OnPacketLoss(lost bool) {
|
func (this *SendingWorker) OnPacketLoss(lossRate uint32) {
|
||||||
if !effectiveConfig.Congestion {
|
if !effectiveConfig.Congestion || this.kcp.rx_srtt == 0 {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if lost {
|
if lossRate >= 15 {
|
||||||
this.controlWindow = 3 * this.controlWindow / 4
|
this.controlWindow = 3 * this.controlWindow / 4
|
||||||
} else {
|
} else if lossRate <= 5 {
|
||||||
this.controlWindow += this.controlWindow / 4
|
this.controlWindow += this.controlWindow / 4
|
||||||
}
|
}
|
||||||
if this.controlWindow < 4 {
|
if this.controlWindow < 4 {
|
||||||
|
|
Loading…
Reference in New Issue