|
@@ -9,6 +9,7 @@ import (
|
|
|
"time"
|
|
"time"
|
|
|
|
|
|
|
|
"github.com/apernet/quic-go/congestion"
|
|
"github.com/apernet/quic-go/congestion"
|
|
|
|
|
+ "github.com/apernet/quic-go/monotime"
|
|
|
|
|
|
|
|
"github.com/xtls/xray-core/transport/internet/hysteria/congestion/common"
|
|
"github.com/xtls/xray-core/transport/internet/hysteria/congestion/common"
|
|
|
)
|
|
)
|
|
@@ -130,7 +131,7 @@ type bbrSender struct {
|
|
|
// triggers PROBE_RTT mode) if no new value is sampled during that period.
|
|
// triggers PROBE_RTT mode) if no new value is sampled during that period.
|
|
|
minRtt time.Duration
|
|
minRtt time.Duration
|
|
|
// The time at which the current value of |min_rtt_| was assigned.
|
|
// The time at which the current value of |min_rtt_| was assigned.
|
|
|
- minRttTimestamp congestion.Time
|
|
|
|
|
|
|
+ minRttTimestamp monotime.Time
|
|
|
|
|
|
|
|
// The maximum allowed number of bytes in flight.
|
|
// The maximum allowed number of bytes in flight.
|
|
|
congestionWindow congestion.ByteCount
|
|
congestionWindow congestion.ByteCount
|
|
@@ -171,7 +172,7 @@ type bbrSender struct {
|
|
|
// pacing gain cycle.
|
|
// pacing gain cycle.
|
|
|
cycleCurrentOffset int
|
|
cycleCurrentOffset int
|
|
|
// The time at which the last pacing gain cycle was started.
|
|
// The time at which the last pacing gain cycle was started.
|
|
|
- lastCycleStart congestion.Time
|
|
|
|
|
|
|
+ lastCycleStart monotime.Time
|
|
|
|
|
|
|
|
// Indicates whether the connection has reached the full bandwidth mode.
|
|
// Indicates whether the connection has reached the full bandwidth mode.
|
|
|
isAtFullBandwidth bool
|
|
isAtFullBandwidth bool
|
|
@@ -186,7 +187,7 @@ type bbrSender struct {
|
|
|
// Time at which PROBE_RTT has to be exited. Setting it to zero indicates
|
|
// Time at which PROBE_RTT has to be exited. Setting it to zero indicates
|
|
|
// that the time is yet unknown as the number of packets in flight has not
|
|
// that the time is yet unknown as the number of packets in flight has not
|
|
|
// reached the required value.
|
|
// reached the required value.
|
|
|
- exitProbeRttAt congestion.Time
|
|
|
|
|
|
|
+ exitProbeRttAt monotime.Time
|
|
|
// Indicates whether a round-trip has passed since PROBE_RTT became active.
|
|
// Indicates whether a round-trip has passed since PROBE_RTT became active.
|
|
|
probeRttRoundPassed bool
|
|
probeRttRoundPassed bool
|
|
|
|
|
|
|
@@ -313,18 +314,18 @@ func (b *bbrSender) SetRTTStatsProvider(provider congestion.RTTStatsProvider) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// TimeUntilSend implements the SendAlgorithm interface.
|
|
// TimeUntilSend implements the SendAlgorithm interface.
|
|
|
-func (b *bbrSender) TimeUntilSend(bytesInFlight congestion.ByteCount) congestion.Time {
|
|
|
|
|
|
|
+func (b *bbrSender) TimeUntilSend(bytesInFlight congestion.ByteCount) monotime.Time {
|
|
|
return b.pacer.TimeUntilSend()
|
|
return b.pacer.TimeUntilSend()
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// HasPacingBudget implements the SendAlgorithm interface.
|
|
// HasPacingBudget implements the SendAlgorithm interface.
|
|
|
-func (b *bbrSender) HasPacingBudget(now congestion.Time) bool {
|
|
|
|
|
|
|
+func (b *bbrSender) HasPacingBudget(now monotime.Time) bool {
|
|
|
return b.pacer.Budget(now) >= b.maxDatagramSize
|
|
return b.pacer.Budget(now) >= b.maxDatagramSize
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// OnPacketSent implements the SendAlgorithm interface.
|
|
// OnPacketSent implements the SendAlgorithm interface.
|
|
|
func (b *bbrSender) OnPacketSent(
|
|
func (b *bbrSender) OnPacketSent(
|
|
|
- sentTime congestion.Time,
|
|
|
|
|
|
|
+ sentTime monotime.Time,
|
|
|
bytesInFlight congestion.ByteCount,
|
|
bytesInFlight congestion.ByteCount,
|
|
|
packetNumber congestion.PacketNumber,
|
|
packetNumber congestion.PacketNumber,
|
|
|
bytes congestion.ByteCount,
|
|
bytes congestion.ByteCount,
|
|
@@ -353,7 +354,7 @@ func (b *bbrSender) MaybeExitSlowStart() {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// OnPacketAcked implements the SendAlgorithm interface.
|
|
// OnPacketAcked implements the SendAlgorithm interface.
|
|
|
-func (b *bbrSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes, priorInFlight congestion.ByteCount, eventTime congestion.Time) {
|
|
|
|
|
|
|
+func (b *bbrSender) OnPacketAcked(number congestion.PacketNumber, ackedBytes, priorInFlight congestion.ByteCount, eventTime monotime.Time) {
|
|
|
// Do nothing.
|
|
// Do nothing.
|
|
|
}
|
|
}
|
|
|
|
|
|
|
@@ -407,7 +408,7 @@ func (b *bbrSender) OnCongestionEvent(number congestion.PacketNumber, lostBytes,
|
|
|
// Do nothing.
|
|
// Do nothing.
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (b *bbrSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime congestion.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) {
|
|
|
|
|
|
|
+func (b *bbrSender) OnCongestionEventEx(priorInFlight congestion.ByteCount, eventTime monotime.Time, ackedPackets []congestion.AckedPacketInfo, lostPackets []congestion.LostPacketInfo) {
|
|
|
totalBytesAckedBefore := b.sampler.TotalBytesAcked()
|
|
totalBytesAckedBefore := b.sampler.TotalBytesAcked()
|
|
|
totalBytesLostBefore := b.sampler.TotalBytesLost()
|
|
totalBytesLostBefore := b.sampler.TotalBytesLost()
|
|
|
|
|
|
|
@@ -598,7 +599,7 @@ func (b *bbrSender) probeRttCongestionWindow() congestion.ByteCount {
|
|
|
return b.minCongestionWindow
|
|
return b.minCongestionWindow
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-func (b *bbrSender) maybeUpdateMinRtt(now congestion.Time, sampleMinRtt time.Duration) bool {
|
|
|
|
|
|
|
+func (b *bbrSender) maybeUpdateMinRtt(now monotime.Time, sampleMinRtt time.Duration) bool {
|
|
|
// Do not expire min_rtt if none was ever available.
|
|
// Do not expire min_rtt if none was ever available.
|
|
|
minRttExpired := b.minRtt != 0 && now.After(b.minRttTimestamp.Add(minRttExpiry))
|
|
minRttExpired := b.minRtt != 0 && now.After(b.minRttTimestamp.Add(minRttExpiry))
|
|
|
if minRttExpired || sampleMinRtt < b.minRtt || b.minRtt == 0 {
|
|
if minRttExpired || sampleMinRtt < b.minRtt || b.minRtt == 0 {
|
|
@@ -610,7 +611,7 @@ func (b *bbrSender) maybeUpdateMinRtt(now congestion.Time, sampleMinRtt time.Dur
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Enters the STARTUP mode.
|
|
// Enters the STARTUP mode.
|
|
|
-func (b *bbrSender) enterStartupMode(now congestion.Time) {
|
|
|
|
|
|
|
+func (b *bbrSender) enterStartupMode(now monotime.Time) {
|
|
|
b.mode = bbrModeStartup
|
|
b.mode = bbrModeStartup
|
|
|
// b.maybeTraceStateChange(logging.CongestionStateStartup)
|
|
// b.maybeTraceStateChange(logging.CongestionStateStartup)
|
|
|
b.pacingGain = b.highGain
|
|
b.pacingGain = b.highGain
|
|
@@ -622,7 +623,7 @@ func (b *bbrSender) enterStartupMode(now congestion.Time) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Enters the PROBE_BW mode.
|
|
// Enters the PROBE_BW mode.
|
|
|
-func (b *bbrSender) enterProbeBandwidthMode(now congestion.Time) {
|
|
|
|
|
|
|
+func (b *bbrSender) enterProbeBandwidthMode(now monotime.Time) {
|
|
|
b.mode = bbrModeProbeBw
|
|
b.mode = bbrModeProbeBw
|
|
|
// b.maybeTraceStateChange(logging.CongestionStateProbeBw)
|
|
// b.maybeTraceStateChange(logging.CongestionStateProbeBw)
|
|
|
b.congestionWindowGain = b.congestionWindowGainConstant
|
|
b.congestionWindowGain = b.congestionWindowGainConstant
|
|
@@ -655,7 +656,7 @@ func (b *bbrSender) updateRoundTripCounter(lastAckedPacket congestion.PacketNumb
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Updates the current gain used in PROBE_BW mode.
|
|
// Updates the current gain used in PROBE_BW mode.
|
|
|
-func (b *bbrSender) updateGainCyclePhase(now congestion.Time, priorInFlight congestion.ByteCount, hasLosses bool) {
|
|
|
|
|
|
|
+func (b *bbrSender) updateGainCyclePhase(now monotime.Time, priorInFlight congestion.ByteCount, hasLosses bool) {
|
|
|
// In most cases, the cycle is advanced after an RTT passes.
|
|
// In most cases, the cycle is advanced after an RTT passes.
|
|
|
shouldAdvanceGainCycling := now.After(b.lastCycleStart.Add(b.getMinRtt()))
|
|
shouldAdvanceGainCycling := now.After(b.lastCycleStart.Add(b.getMinRtt()))
|
|
|
// If the pacing gain is above 1.0, the connection is trying to probe the
|
|
// If the pacing gain is above 1.0, the connection is trying to probe the
|
|
@@ -722,7 +723,7 @@ func (b *bbrSender) maybeAppLimited(bytesInFlight congestion.ByteCount) {
|
|
|
|
|
|
|
|
// Transitions from STARTUP to DRAIN and from DRAIN to PROBE_BW if
|
|
// Transitions from STARTUP to DRAIN and from DRAIN to PROBE_BW if
|
|
|
// appropriate.
|
|
// appropriate.
|
|
|
-func (b *bbrSender) maybeExitStartupOrDrain(now congestion.Time) {
|
|
|
|
|
|
|
+func (b *bbrSender) maybeExitStartupOrDrain(now monotime.Time) {
|
|
|
if b.mode == bbrModeStartup && b.isAtFullBandwidth {
|
|
if b.mode == bbrModeStartup && b.isAtFullBandwidth {
|
|
|
b.mode = bbrModeDrain
|
|
b.mode = bbrModeDrain
|
|
|
// b.maybeTraceStateChange(logging.CongestionStateDrain)
|
|
// b.maybeTraceStateChange(logging.CongestionStateDrain)
|
|
@@ -739,7 +740,7 @@ func (b *bbrSender) maybeExitStartupOrDrain(now congestion.Time) {
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
// Decides whether to enter or exit PROBE_RTT.
|
|
// Decides whether to enter or exit PROBE_RTT.
|
|
|
-func (b *bbrSender) maybeEnterOrExitProbeRtt(now congestion.Time, isRoundStart, minRttExpired bool) {
|
|
|
|
|
|
|
+func (b *bbrSender) maybeEnterOrExitProbeRtt(now monotime.Time, isRoundStart, minRttExpired bool) {
|
|
|
if minRttExpired && !b.exitingQuiescence && b.mode != bbrModeProbeRtt {
|
|
if minRttExpired && !b.exitingQuiescence && b.mode != bbrModeProbeRtt {
|
|
|
b.mode = bbrModeProbeRtt
|
|
b.mode = bbrModeProbeRtt
|
|
|
// b.maybeTraceStateChange(logging.CongestionStateProbRtt)
|
|
// b.maybeTraceStateChange(logging.CongestionStateProbRtt)
|