|  | @@ -103,7 +103,7 @@ func (this *SendingWindow) Remove(idx uint32) {
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (this *SendingWindow) HandleFastAck(number uint32) {
 | 
	
		
			
				|  |  | +func (this *SendingWindow) HandleFastAck(number uint32, rto uint32) {
 | 
	
		
			
				|  |  |  	if this.len == 0 {
 | 
	
		
			
				|  |  |  		return
 | 
	
		
			
				|  |  |  	}
 | 
	
	
		
			
				|  | @@ -114,7 +114,9 @@ func (this *SendingWindow) HandleFastAck(number uint32) {
 | 
	
		
			
				|  |  |  			break
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		if number != seg.Number {
 | 
	
		
			
				|  |  | -			seg.ackSkipped++
 | 
	
		
			
				|  |  | +			if seg.transmit > 0 && seg.timeout > rto/3 {
 | 
	
		
			
				|  |  | +				seg.timeout -= rto / 3
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  		if i == this.last {
 | 
	
		
			
				|  |  |  			break
 | 
	
	
		
			
				|  | @@ -122,7 +124,7 @@ func (this *SendingWindow) HandleFastAck(number uint32) {
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (this *SendingWindow) Flush(current uint32, resend uint32, rto uint32, maxInFlightSize uint32) {
 | 
	
		
			
				|  |  | +func (this *SendingWindow) Flush(current uint32, rto uint32, maxInFlightSize uint32) {
 | 
	
		
			
				|  |  |  	if this.IsEmpty() {
 | 
	
		
			
				|  |  |  		return
 | 
	
		
			
				|  |  |  	}
 | 
	
	
		
			
				|  | @@ -133,25 +135,20 @@ func (this *SendingWindow) Flush(current uint32, resend uint32, rto uint32, maxI
 | 
	
		
			
				|  |  |  	for i := this.start; ; i = this.next[i] {
 | 
	
		
			
				|  |  |  		segment := this.data[i]
 | 
	
		
			
				|  |  |  		needsend := false
 | 
	
		
			
				|  |  | -		if segment.transmit == 0 {
 | 
	
		
			
				|  |  | -			needsend = true
 | 
	
		
			
				|  |  | -			segment.transmit++
 | 
	
		
			
				|  |  | -			segment.timeout = current + rto
 | 
	
		
			
				|  |  | -			this.totalInFlightSize++
 | 
	
		
			
				|  |  | -		} else if current-segment.timeout < 0x7FFFFFFF {
 | 
	
		
			
				|  |  | -			needsend = true
 | 
	
		
			
				|  |  | -			segment.transmit++
 | 
	
		
			
				|  |  | -			segment.timeout = current + rto
 | 
	
		
			
				|  |  | -			lost++
 | 
	
		
			
				|  |  | -		} else if segment.ackSkipped >= resend {
 | 
	
		
			
				|  |  | +		if current-segment.timeout < 0x7FFFFFFF {
 | 
	
		
			
				|  |  | +			if segment.transmit == 0 {
 | 
	
		
			
				|  |  | +				// First time
 | 
	
		
			
				|  |  | +				this.totalInFlightSize++
 | 
	
		
			
				|  |  | +			} else {
 | 
	
		
			
				|  |  | +				lost++
 | 
	
		
			
				|  |  | +			}
 | 
	
		
			
				|  |  |  			needsend = true
 | 
	
		
			
				|  |  | -			segment.transmit++
 | 
	
		
			
				|  |  | -			segment.ackSkipped = 0
 | 
	
		
			
				|  |  |  			segment.timeout = current + rto
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  		if needsend {
 | 
	
		
			
				|  |  |  			segment.Timestamp = current
 | 
	
		
			
				|  |  | +			segment.transmit++
 | 
	
		
			
				|  |  |  			this.writer.Write(segment)
 | 
	
		
			
				|  |  |  			inFlightSize++
 | 
	
		
			
				|  |  |  			if inFlightSize >= maxInFlightSize {
 | 
	
	
		
			
				|  | @@ -228,7 +225,7 @@ func (this *SendingWorker) ProcessAck(number uint32) {
 | 
	
		
			
				|  |  |  	this.FindFirstUnacknowledged()
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -func (this *SendingWorker) ProcessSegment(current uint32, seg *AckSegment) {
 | 
	
		
			
				|  |  | +func (this *SendingWorker) ProcessSegment(current uint32, seg *AckSegment, rto uint32) {
 | 
	
		
			
				|  |  |  	defer seg.Release()
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	this.Lock()
 | 
	
	
		
			
				|  | @@ -252,7 +249,7 @@ func (this *SendingWorker) ProcessSegment(current uint32, seg *AckSegment) {
 | 
	
		
			
				|  |  |  		}
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  | -	this.window.HandleFastAck(maxack)
 | 
	
		
			
				|  |  | +	this.window.HandleFastAck(maxack, rto)
 | 
	
		
			
				|  |  |  }
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  func (this *SendingWorker) Push(b []byte) int {
 | 
	
	
		
			
				|  | @@ -271,7 +268,6 @@ func (this *SendingWorker) Push(b []byte) int {
 | 
	
		
			
				|  |  |  		seg.Data = AllocateBuffer().Clear().Append(b[:size])
 | 
	
		
			
				|  |  |  		seg.Number = this.nextNumber
 | 
	
		
			
				|  |  |  		seg.timeout = 0
 | 
	
		
			
				|  |  | -		seg.ackSkipped = 0
 | 
	
		
			
				|  |  |  		seg.transmit = 0
 | 
	
		
			
				|  |  |  		this.window.Push(seg)
 | 
	
		
			
				|  |  |  		this.nextNumber++
 | 
	
	
		
			
				|  | @@ -326,7 +322,7 @@ func (this *SendingWorker) Flush(current uint32) {
 | 
	
		
			
				|  |  |  	}
 | 
	
		
			
				|  |  |  
 | 
	
		
			
				|  |  |  	if !this.window.IsEmpty() {
 | 
	
		
			
				|  |  | -		this.window.Flush(current, this.conn.fastresend, this.conn.roundTrip.Timeout(), cwnd)
 | 
	
		
			
				|  |  | +		this.window.Flush(current, this.conn.roundTrip.Timeout(), cwnd)
 | 
	
		
			
				|  |  |  	} else if this.firstUnacknowledgedUpdated {
 | 
	
		
			
				|  |  |  		this.conn.Ping(current, CommandPing)
 | 
	
		
			
				|  |  |  	}
 |