refine congestion control

pull/215/head
v2ray 2016-07-04 15:34:14 +02:00
parent 8ea3c13236
commit d1d153acb9
No known key found for this signature in database
GPG Key ID: 7251FFA14BB18169
1 changed files with 18 additions and 13 deletions

View File

@ -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 {