mirror of https://github.com/v2ray/v2ray-core
simplify kcp logic
parent
2a2b0242cb
commit
4ee758c4d2
|
@ -80,14 +80,15 @@ func (this *AckList) Add(number uint32, timestamp uint32) {
|
||||||
func (this *AckList) Clear(una uint32) {
|
func (this *AckList) Clear(una uint32) {
|
||||||
count := 0
|
count := 0
|
||||||
for i := 0; i < len(this.numbers); i++ {
|
for i := 0; i < len(this.numbers); i++ {
|
||||||
if this.numbers[i] >= una {
|
if this.numbers[i] < una {
|
||||||
if i != count {
|
continue
|
||||||
this.numbers[count] = this.numbers[i]
|
|
||||||
this.timestamps[count] = this.timestamps[i]
|
|
||||||
this.nextFlush[count] = this.nextFlush[i]
|
|
||||||
}
|
|
||||||
count++
|
|
||||||
}
|
}
|
||||||
|
if i != count {
|
||||||
|
this.numbers[count] = this.numbers[i]
|
||||||
|
this.timestamps[count] = this.timestamps[i]
|
||||||
|
this.nextFlush[count] = this.nextFlush[i]
|
||||||
|
}
|
||||||
|
count++
|
||||||
}
|
}
|
||||||
if count < len(this.numbers) {
|
if count < len(this.numbers) {
|
||||||
this.numbers = this.numbers[:count]
|
this.numbers = this.numbers[:count]
|
||||||
|
@ -99,15 +100,16 @@ func (this *AckList) Clear(una uint32) {
|
||||||
func (this *AckList) Flush(current uint32, rto uint32) {
|
func (this *AckList) Flush(current uint32, rto uint32) {
|
||||||
seg := NewAckSegment()
|
seg := NewAckSegment()
|
||||||
for i := 0; i < len(this.numbers) && !seg.IsFull(); i++ {
|
for i := 0; i < len(this.numbers) && !seg.IsFull(); i++ {
|
||||||
if this.nextFlush[i] <= current {
|
if this.nextFlush[i] > current {
|
||||||
seg.PutNumber(this.numbers[i])
|
continue
|
||||||
seg.PutTimestamp(this.timestamps[i])
|
|
||||||
timeout := rto / 4
|
|
||||||
if timeout < 20 {
|
|
||||||
timeout = 20
|
|
||||||
}
|
|
||||||
this.nextFlush[i] = current + timeout
|
|
||||||
}
|
}
|
||||||
|
seg.PutNumber(this.numbers[i])
|
||||||
|
seg.PutTimestamp(this.timestamps[i])
|
||||||
|
timeout := rto / 4
|
||||||
|
if timeout < 20 {
|
||||||
|
timeout = 20
|
||||||
|
}
|
||||||
|
this.nextFlush[i] = current + timeout
|
||||||
}
|
}
|
||||||
if seg.Count > 0 {
|
if seg.Count > 0 {
|
||||||
this.writer.Write(seg)
|
this.writer.Write(seg)
|
||||||
|
|
|
@ -109,21 +109,25 @@ func (this *SendingWindow) Remove(idx uint32) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (this *SendingWindow) HandleFastAck(number uint32, rto uint32) {
|
func (this *SendingWindow) HandleFastAck(number uint32, rto uint32) {
|
||||||
if this.len == 0 {
|
if this.IsEmpty() {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.Visit(func(seg *DataSegment) bool {
|
||||||
|
if number == seg.Number || number-seg.Number > 0x7FFFFFFF {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
if seg.transmit > 0 && seg.timeout > rto/3 {
|
||||||
|
seg.timeout -= rto / 3
|
||||||
|
}
|
||||||
|
return true
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (this *SendingWindow) Visit(visitor func(seg *DataSegment) bool) {
|
||||||
for i := this.start; ; i = this.next[i] {
|
for i := this.start; ; i = this.next[i] {
|
||||||
seg := &this.data[i]
|
if !visitor(&this.data[i]) || i == this.last {
|
||||||
if number-seg.Number > 0x7FFFFFFF {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
if number != seg.Number {
|
|
||||||
if seg.transmit > 0 && seg.timeout > rto/3 {
|
|
||||||
seg.timeout -= rto / 3
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if i == this.last {
|
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -137,33 +141,27 @@ func (this *SendingWindow) Flush(current uint32, rto uint32, maxInFlightSize uin
|
||||||
var lost uint32
|
var lost uint32
|
||||||
var inFlightSize uint32
|
var inFlightSize uint32
|
||||||
|
|
||||||
for i := this.start; ; i = this.next[i] {
|
this.Visit(func(segment *DataSegment) bool {
|
||||||
segment := &this.data[i]
|
if current-segment.timeout >= 0x7FFFFFFF {
|
||||||
needsend := false
|
return true
|
||||||
if current-segment.timeout < 0x7FFFFFFF {
|
|
||||||
if segment.transmit == 0 {
|
|
||||||
// First time
|
|
||||||
this.totalInFlightSize++
|
|
||||||
} else {
|
|
||||||
lost++
|
|
||||||
}
|
|
||||||
needsend = true
|
|
||||||
segment.timeout = current + rto
|
|
||||||
}
|
}
|
||||||
|
if segment.transmit == 0 {
|
||||||
|
// First time
|
||||||
|
this.totalInFlightSize++
|
||||||
|
} else {
|
||||||
|
lost++
|
||||||
|
}
|
||||||
|
segment.timeout = current + rto
|
||||||
|
|
||||||
if needsend {
|
segment.Timestamp = current
|
||||||
segment.Timestamp = current
|
segment.transmit++
|
||||||
segment.transmit++
|
this.writer.Write(segment)
|
||||||
this.writer.Write(segment)
|
inFlightSize++
|
||||||
inFlightSize++
|
if inFlightSize >= maxInFlightSize {
|
||||||
if inFlightSize >= maxInFlightSize {
|
return false
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if i == this.last {
|
return true
|
||||||
break
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if this.onPacketLoss != nil && inFlightSize > 0 && this.totalInFlightSize != 0 {
|
if this.onPacketLoss != nil && inFlightSize > 0 && this.totalInFlightSize != 0 {
|
||||||
rate := lost * 100 / this.totalInFlightSize
|
rate := lost * 100 / this.totalInFlightSize
|
||||||
|
|
Loading…
Reference in New Issue