forked from quic-go/quic-go
@@ -19,6 +19,7 @@ type Packet struct {
|
||||
Retransmitted bool // has this Packet ever been retransmitted
|
||||
|
||||
sendTime time.Time
|
||||
rtoTime time.Time
|
||||
}
|
||||
|
||||
// GetStreamFramesForRetransmission gets all the streamframes for retransmission
|
||||
|
||||
@@ -118,7 +118,9 @@ func (h *sentPacketHandler) SentPacket(packet *Packet) error {
|
||||
if h.lastSentPacketNumber+1 != packet.PacketNumber {
|
||||
return errWrongPacketNumberIncrement
|
||||
}
|
||||
packet.sendTime = time.Now()
|
||||
now := time.Now()
|
||||
packet.sendTime = now
|
||||
packet.rtoTime = now.Add(h.getRTO())
|
||||
if packet.Length == 0 {
|
||||
return errors.New("SentPacketHandler: packet cannot be empty")
|
||||
}
|
||||
@@ -278,3 +280,11 @@ func (h *sentPacketHandler) GetLargestObserved() protocol.PacketNumber {
|
||||
func (h *sentPacketHandler) AllowsSending() bool {
|
||||
return h.BytesInFlight() <= h.congestion.GetCongestionWindow()
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) getRTO() time.Duration {
|
||||
rto := h.congestion.RetransmissionDelay()
|
||||
if rto == 0 {
|
||||
rto = protocol.DefaultRetransmissionTime
|
||||
}
|
||||
return utils.MaxDuration(rto, protocol.MinRetransmissionTime)
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"github.com/lucas-clemente/quic-go/congestion"
|
||||
"github.com/lucas-clemente/quic-go/frames"
|
||||
"github.com/lucas-clemente/quic-go/protocol"
|
||||
"github.com/lucas-clemente/quic-go/utils"
|
||||
. "github.com/onsi/ginkgo"
|
||||
. "github.com/onsi/gomega"
|
||||
)
|
||||
@@ -39,9 +40,12 @@ func (m *mockCongestion) OnCongestionEvent(rttUpdated bool, bytesInFlight protoc
|
||||
func (m *mockCongestion) SetNumEmulatedConnections(n int) { panic("not implemented") }
|
||||
func (m *mockCongestion) OnRetransmissionTimeout(packetsRetransmitted bool) { panic("not implemented") }
|
||||
func (m *mockCongestion) OnConnectionMigration() { panic("not implemented") }
|
||||
func (m *mockCongestion) RetransmissionDelay() time.Duration { panic("not implemented") }
|
||||
func (m *mockCongestion) SetSlowStartLargeReduction(enabled bool) { panic("not implemented") }
|
||||
|
||||
func (m *mockCongestion) RetransmissionDelay() time.Duration {
|
||||
return protocol.DefaultRetransmissionTime
|
||||
}
|
||||
|
||||
var _ = Describe("SentPacketHandler", func() {
|
||||
var (
|
||||
handler *sentPacketHandler
|
||||
@@ -553,4 +557,30 @@ var _ = Describe("SentPacketHandler", func() {
|
||||
Expect(handler.AllowsSending()).To(BeFalse())
|
||||
})
|
||||
})
|
||||
|
||||
Context("calculating RTO", func() {
|
||||
It("uses default RTO", func() {
|
||||
Expect(handler.getRTO()).To(Equal(protocol.DefaultRetransmissionTime))
|
||||
})
|
||||
|
||||
It("uses RTO from rttStats", func() {
|
||||
rtt := time.Second
|
||||
expected := rtt + rtt/2*4
|
||||
handler.rttStats.UpdateRTT(rtt, 0, time.Now())
|
||||
Expect(handler.getRTO()).To(Equal(expected))
|
||||
})
|
||||
|
||||
It("limits RTO min", func() {
|
||||
rtt := time.Millisecond
|
||||
handler.rttStats.UpdateRTT(rtt, 0, time.Now())
|
||||
Expect(handler.getRTO()).To(Equal(protocol.MinRetransmissionTime))
|
||||
})
|
||||
|
||||
It("stores RTO in sent packets", func() {
|
||||
handler.SentPacket(&Packet{PacketNumber: 1, Frames: []frames.Frame{}, Length: 1})
|
||||
val := handler.packetHistory[1].rtoTime
|
||||
expected := time.Now().Add(protocol.DefaultRetransmissionTime)
|
||||
Expect(utils.AbsDuration(expected.Sub(val))).To(BeNumerically("<", time.Millisecond))
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -100,7 +100,7 @@ func (r *RTTStats) UpdateRTT(sendDelta, ackDelay time.Duration, now time.Time) {
|
||||
// Correct for ackDelay if information received from the peer results in a
|
||||
// positive RTT sample. Otherwise, we use the sendDelta as a reasonable
|
||||
// measure for smoothedRTT.
|
||||
sample := (sendDelta)
|
||||
sample := sendDelta
|
||||
if sample > ackDelay {
|
||||
sample -= ackDelay
|
||||
}
|
||||
|
||||
@@ -48,3 +48,9 @@ const InitialConnectionFlowControlWindow ByteCount = (1 << 14) // 16 kB
|
||||
|
||||
// InitialIdleConnectionStateLifetime is the initial idle connection state lifetime
|
||||
const InitialIdleConnectionStateLifetime = 30 * time.Second
|
||||
|
||||
// DefaultRetransmissionTime is the RTO time on new connections
|
||||
const DefaultRetransmissionTime = 500 * time.Millisecond
|
||||
|
||||
// MinRetransmissionTime is the minimum RTO time
|
||||
const MinRetransmissionTime = 200 * time.Millisecond
|
||||
|
||||
@@ -374,6 +374,7 @@ func (s *Session) closeStreamsWithError(err error) {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: try sending more than one packet
|
||||
func (s *Session) maybeSendPacket() error {
|
||||
if !s.sentPacketHandler.AllowsSending() {
|
||||
return nil
|
||||
|
||||
Reference in New Issue
Block a user