2018-11-20 17:51:25 -05:00
|
|
|
package congestion
|
|
|
|
|
|
|
|
import (
|
2019-01-17 09:33:18 -05:00
|
|
|
"v2ray.com/core/external/github.com/lucas-clemente/quic-go/internal/protocol"
|
2018-11-20 17:51:25 -05:00
|
|
|
)
|
|
|
|
|
|
|
|
// PrrSender implements the Proportional Rate Reduction (PRR) per RFC 6937
|
|
|
|
type PrrSender struct {
|
|
|
|
bytesSentSinceLoss protocol.ByteCount
|
|
|
|
bytesDeliveredSinceLoss protocol.ByteCount
|
|
|
|
ackCountSinceLoss protocol.ByteCount
|
|
|
|
bytesInFlightBeforeLoss protocol.ByteCount
|
|
|
|
}
|
|
|
|
|
|
|
|
// OnPacketSent should be called after a packet was sent
|
|
|
|
func (p *PrrSender) OnPacketSent(sentBytes protocol.ByteCount) {
|
|
|
|
p.bytesSentSinceLoss += sentBytes
|
|
|
|
}
|
|
|
|
|
|
|
|
// OnPacketLost should be called on the first loss that triggers a recovery
|
|
|
|
// period and all other methods in this class should only be called when in
|
|
|
|
// recovery.
|
|
|
|
func (p *PrrSender) OnPacketLost(priorInFlight protocol.ByteCount) {
|
|
|
|
p.bytesSentSinceLoss = 0
|
|
|
|
p.bytesInFlightBeforeLoss = priorInFlight
|
|
|
|
p.bytesDeliveredSinceLoss = 0
|
|
|
|
p.ackCountSinceLoss = 0
|
|
|
|
}
|
|
|
|
|
|
|
|
// OnPacketAcked should be called after a packet was acked
|
|
|
|
func (p *PrrSender) OnPacketAcked(ackedBytes protocol.ByteCount) {
|
|
|
|
p.bytesDeliveredSinceLoss += ackedBytes
|
|
|
|
p.ackCountSinceLoss++
|
|
|
|
}
|
|
|
|
|
|
|
|
// CanSend returns if packets can be sent
|
|
|
|
func (p *PrrSender) CanSend(congestionWindow, bytesInFlight, slowstartThreshold protocol.ByteCount) bool {
|
|
|
|
// Return QuicTime::Zero In order to ensure limited transmit always works.
|
|
|
|
if p.bytesSentSinceLoss == 0 || bytesInFlight < protocol.DefaultTCPMSS {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
if congestionWindow > bytesInFlight {
|
|
|
|
// During PRR-SSRB, limit outgoing packets to 1 extra MSS per ack, instead
|
|
|
|
// of sending the entire available window. This prevents burst retransmits
|
|
|
|
// when more packets are lost than the CWND reduction.
|
|
|
|
// limit = MAX(prr_delivered - prr_out, DeliveredData) + MSS
|
|
|
|
return p.bytesDeliveredSinceLoss+p.ackCountSinceLoss*protocol.DefaultTCPMSS > p.bytesSentSinceLoss
|
|
|
|
}
|
|
|
|
// Implement Proportional Rate Reduction (RFC6937).
|
|
|
|
// Checks a simplified version of the PRR formula that doesn't use division:
|
|
|
|
// AvailableSendWindow =
|
|
|
|
// CEIL(prr_delivered * ssthresh / BytesInFlightAtLoss) - prr_sent
|
|
|
|
return p.bytesDeliveredSinceLoss*slowstartThreshold > p.bytesSentSinceLoss*p.bytesInFlightBeforeLoss
|
|
|
|
}
|