Explorar el Código

refine congestion control

v2ray hace 9 años
padre
commit
d1d153acb9
Se han modificado 1 ficheros con 18 adiciones y 13 borrados
  1. 18 13
      transport/internet/kcp/sending.go

+ 18 - 13
transport/internet/kcp/sending.go

@@ -16,12 +16,13 @@ type SendingWindow struct {
 	prev []uint32
 	next []uint32
 
-	inFlightSize uint32
-	writer       SegmentWriter
-	onPacketLoss func(bool)
+	inFlightSize      uint32
+	totalInFlightSize uint32
+	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{
 		start:        0,
 		cap:          size,
@@ -72,6 +73,7 @@ func (this *SendingWindow) Remove(idx uint32) {
 	if seg == nil {
 		return
 	}
+	this.totalInFlightSize--
 	seg.Release()
 	this.data[pos] = nil
 	if pos == this.start && pos == this.last {
@@ -117,7 +119,7 @@ func (this *SendingWindow) Flush(current uint32, resend uint32, rto uint32) {
 		return
 	}
 
-	lost := false
+	var lost uint32
 	var inFlightSize uint32
 
 	for i := this.start; ; i = this.next[i] {
@@ -127,17 +129,17 @@ func (this *SendingWindow) Flush(current uint32, resend uint32, rto uint32) {
 			needsend = true
 			segment.transmit++
 			segment.timeout = current + rto
+			this.totalInFlightSize++
 		} else if _itimediff(current, segment.timeout) >= 0 {
 			needsend = true
 			segment.transmit++
 			segment.timeout = current + rto
-			lost = true
+			lost++
 		} else if segment.ackSkipped >= resend {
 			needsend = true
 			segment.transmit++
 			segment.ackSkipped = 0
 			segment.timeout = current + rto
-			lost = true
 		}
 
 		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 {
@@ -282,7 +287,7 @@ func (this *SendingWorker) ProcessSegment(seg *AckSegment) {
 	for i := 0; i < int(seg.Count); i++ {
 		timestamp := seg.TimestampList[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.ProcessAck(number)
@@ -335,14 +340,14 @@ func (this *SendingWorker) PingNecessary() bool {
 	return this.updated
 }
 
-func (this *SendingWorker) OnPacketLoss(lost bool) {
-	if !effectiveConfig.Congestion {
+func (this *SendingWorker) OnPacketLoss(lossRate uint32) {
+	if !effectiveConfig.Congestion || this.kcp.rx_srtt == 0 {
 		return
 	}
 
-	if lost {
+	if lossRate >= 15 {
 		this.controlWindow = 3 * this.controlWindow / 4
-	} else {
+	} else if lossRate <= 5 {
 		this.controlWindow += this.controlWindow / 4
 	}
 	if this.controlWindow < 4 {