|  | @@ -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
 | 
											
												
													
														|  |  	}
 |  |  	}
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  | -	for i := this.start; ; i = this.next[i] {
 |  | 
 | 
											
												
													
														|  | -		seg := &this.data[i]
 |  | 
 | 
											
												
													
														|  | -		if number-seg.Number > 0x7FFFFFFF {
 |  | 
 | 
											
												
													
														|  | -			break
 |  | 
 | 
											
												
													
														|  | 
 |  | +	this.Visit(func(seg *DataSegment) bool {
 | 
											
												
													
														|  | 
 |  | +		if number == seg.Number || number-seg.Number > 0x7FFFFFFF {
 | 
											
												
													
														|  | 
 |  | +			return false
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  | -		if number != seg.Number {
 |  | 
 | 
											
												
													
														|  | -			if seg.transmit > 0 && seg.timeout > rto/3 {
 |  | 
 | 
											
												
													
														|  | -				seg.timeout -= rto / 3
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +		if seg.transmit > 0 && seg.timeout > rto/3 {
 | 
											
												
													
														|  | 
 |  | +			seg.timeout -= rto / 3
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  | -		if i == this.last {
 |  | 
 | 
											
												
													
														|  | 
 |  | +		return true
 | 
											
												
													
														|  | 
 |  | +	})
 | 
											
												
													
														|  | 
 |  | +}
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +func (this *SendingWindow) Visit(visitor func(seg *DataSegment) bool) {
 | 
											
												
													
														|  | 
 |  | +	for i := this.start; ; i = this.next[i] {
 | 
											
												
													
														|  | 
 |  | +		if !visitor(&this.data[i]) || 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] {
 |  | 
 | 
											
												
													
														|  | -		segment := &this.data[i]
 |  | 
 | 
											
												
													
														|  | -		needsend := false
 |  | 
 | 
											
												
													
														|  | -		if current-segment.timeout < 0x7FFFFFFF {
 |  | 
 | 
											
												
													
														|  | -			if segment.transmit == 0 {
 |  | 
 | 
											
												
													
														|  | -				// First time
 |  | 
 | 
											
												
													
														|  | -				this.totalInFlightSize++
 |  | 
 | 
											
												
													
														|  | -			} else {
 |  | 
 | 
											
												
													
														|  | -				lost++
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | -			needsend = true
 |  | 
 | 
											
												
													
														|  | -			segment.timeout = current + rto
 |  | 
 | 
											
												
													
														|  | 
 |  | +	this.Visit(func(segment *DataSegment) bool {
 | 
											
												
													
														|  | 
 |  | +		if current-segment.timeout >= 0x7FFFFFFF {
 | 
											
												
													
														|  | 
 |  | +			return true
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  | -
 |  | 
 | 
											
												
													
														|  | -		if needsend {
 |  | 
 | 
											
												
													
														|  | -			segment.Timestamp = current
 |  | 
 | 
											
												
													
														|  | -			segment.transmit++
 |  | 
 | 
											
												
													
														|  | -			this.writer.Write(segment)
 |  | 
 | 
											
												
													
														|  | -			inFlightSize++
 |  | 
 | 
											
												
													
														|  | -			if inFlightSize >= maxInFlightSize {
 |  | 
 | 
											
												
													
														|  | -				break
 |  | 
 | 
											
												
													
														|  | -			}
 |  | 
 | 
											
												
													
														|  | 
 |  | +		if segment.transmit == 0 {
 | 
											
												
													
														|  | 
 |  | +			// First time
 | 
											
												
													
														|  | 
 |  | +			this.totalInFlightSize++
 | 
											
												
													
														|  | 
 |  | +		} else {
 | 
											
												
													
														|  | 
 |  | +			lost++
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  | -		if i == this.last {
 |  | 
 | 
											
												
													
														|  | -			break
 |  | 
 | 
											
												
													
														|  | 
 |  | +		segment.timeout = current + rto
 | 
											
												
													
														|  | 
 |  | +
 | 
											
												
													
														|  | 
 |  | +		segment.Timestamp = current
 | 
											
												
													
														|  | 
 |  | +		segment.transmit++
 | 
											
												
													
														|  | 
 |  | +		this.writer.Write(segment)
 | 
											
												
													
														|  | 
 |  | +		inFlightSize++
 | 
											
												
													
														|  | 
 |  | +		if inFlightSize >= maxInFlightSize {
 | 
											
												
													
														|  | 
 |  | +			return false
 | 
											
												
													
														|  |  		}
 |  |  		}
 | 
											
												
													
														|  | -	}
 |  | 
 | 
											
												
													
														|  | 
 |  | +		return true
 | 
											
												
													
														|  | 
 |  | +	})
 | 
											
												
													
														|  |  
 |  |  
 | 
											
												
													
														|  |  	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
 |