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