mirror of
https://github.com/refraction-networking/uquic.git
synced 2025-04-03 20:27:35 +03:00
limit the ACK delay by max_ack_delay
This commit is contained in:
parent
0e33f3c0da
commit
537737935c
5 changed files with 37 additions and 5 deletions
|
@ -13,6 +13,7 @@ type SentPacketHandler interface {
|
|||
SentPacket(packet *Packet)
|
||||
SentPacketsAsRetransmission(packets []*Packet, retransmissionOf protocol.PacketNumber)
|
||||
ReceivedAck(ackFrame *wire.AckFrame, withPacketNumber protocol.PacketNumber, encLevel protocol.EncryptionLevel, recvTime time.Time) error
|
||||
SetMaxAckDelay(time.Duration)
|
||||
SetHandshakeComplete()
|
||||
ResetForRetry() error
|
||||
|
||||
|
|
|
@ -58,6 +58,7 @@ type sentPacketHandler struct {
|
|||
rttStats *congestion.RTTStats
|
||||
|
||||
handshakeComplete bool
|
||||
maxAckDelay time.Duration
|
||||
|
||||
// The number of times the crypto packets have been retransmitted without receiving an ack.
|
||||
cryptoCount uint32
|
||||
|
@ -122,6 +123,10 @@ func (h *sentPacketHandler) SetHandshakeComplete() {
|
|||
h.handshakeComplete = true
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) SetMaxAckDelay(mad time.Duration) {
|
||||
h.maxAckDelay = mad
|
||||
}
|
||||
|
||||
func (h *sentPacketHandler) SentPacket(packet *Packet) {
|
||||
if isAckEliciting := h.sentPacketImpl(packet); isAckEliciting {
|
||||
h.getPacketNumberSpace(packet.EncryptionLevel).history.SentPacket(packet)
|
||||
|
@ -208,7 +213,7 @@ func (h *sentPacketHandler) ReceivedAck(ackFrame *wire.AckFrame, withPacketNumbe
|
|||
// don't use the ack delay for Initial and Handshake packets
|
||||
var ackDelay time.Duration
|
||||
if encLevel == protocol.Encryption1RTT {
|
||||
ackDelay = ackFrame.DelayTime
|
||||
ackDelay = utils.MinDuration(ackFrame.DelayTime, h.maxAckDelay)
|
||||
}
|
||||
h.rttStats.UpdateRTT(rcvTime.Sub(p.SendTime), ackDelay, rcvTime)
|
||||
if h.logger.Debug() {
|
||||
|
|
|
@ -294,10 +294,10 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
|
||||
It("ignores the DelayTime for Initial and Handshake packets", func() {
|
||||
handler.SentPacket(cryptoPacket(&Packet{PacketNumber: 1}))
|
||||
now := time.Now()
|
||||
handler.SetMaxAckDelay(time.Hour)
|
||||
// make sure the rttStats have a min RTT, so that the delay is used
|
||||
handler.rttStats.UpdateRTT(5*time.Minute, 0, time.Now())
|
||||
getPacket(1, protocol.EncryptionInitial).SendTime = now.Add(-10 * time.Minute)
|
||||
getPacket(1, protocol.EncryptionInitial).SendTime = time.Now().Add(-10 * time.Minute)
|
||||
ack := &wire.AckFrame{
|
||||
AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}},
|
||||
DelayTime: 5 * time.Minute,
|
||||
|
@ -307,10 +307,10 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
})
|
||||
|
||||
It("uses the DelayTime in the ACK frame", func() {
|
||||
now := time.Now()
|
||||
handler.SetMaxAckDelay(time.Hour)
|
||||
// make sure the rttStats have a min RTT, so that the delay is used
|
||||
handler.rttStats.UpdateRTT(5*time.Minute, 0, time.Now())
|
||||
getPacket(1, protocol.Encryption1RTT).SendTime = now.Add(-10 * time.Minute)
|
||||
getPacket(1, protocol.Encryption1RTT).SendTime = time.Now().Add(-10 * time.Minute)
|
||||
ack := &wire.AckFrame{
|
||||
AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}},
|
||||
DelayTime: 5 * time.Minute,
|
||||
|
@ -318,6 +318,19 @@ var _ = Describe("SentPacketHandler", func() {
|
|||
Expect(handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, time.Now())).To(Succeed())
|
||||
Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 5*time.Minute, 1*time.Second))
|
||||
})
|
||||
|
||||
It("limits the DelayTime in the ACK frame to max_ack_delay", func() {
|
||||
handler.SetMaxAckDelay(time.Minute)
|
||||
// make sure the rttStats have a min RTT, so that the delay is used
|
||||
handler.rttStats.UpdateRTT(5*time.Minute, 0, time.Now())
|
||||
getPacket(1, protocol.Encryption1RTT).SendTime = time.Now().Add(-10 * time.Minute)
|
||||
ack := &wire.AckFrame{
|
||||
AckRanges: []wire.AckRange{{Smallest: 1, Largest: 1}},
|
||||
DelayTime: 5 * time.Minute,
|
||||
}
|
||||
Expect(handler.ReceivedAck(ack, 1, protocol.Encryption1RTT, time.Now())).To(Succeed())
|
||||
Expect(handler.rttStats.LatestRTT()).To(BeNumerically("~", 9*time.Minute, 1*time.Second))
|
||||
})
|
||||
})
|
||||
|
||||
Context("determining which ACKs we have received an ACK for", func() {
|
||||
|
|
|
@ -215,6 +215,18 @@ func (mr *MockSentPacketHandlerMockRecorder) SetHandshakeComplete() *gomock.Call
|
|||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetHandshakeComplete", reflect.TypeOf((*MockSentPacketHandler)(nil).SetHandshakeComplete))
|
||||
}
|
||||
|
||||
// SetMaxAckDelay mocks base method
|
||||
func (m *MockSentPacketHandler) SetMaxAckDelay(arg0 time.Duration) {
|
||||
m.ctrl.T.Helper()
|
||||
m.ctrl.Call(m, "SetMaxAckDelay", arg0)
|
||||
}
|
||||
|
||||
// SetMaxAckDelay indicates an expected call of SetMaxAckDelay
|
||||
func (mr *MockSentPacketHandlerMockRecorder) SetMaxAckDelay(arg0 interface{}) *gomock.Call {
|
||||
mr.mock.ctrl.T.Helper()
|
||||
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetMaxAckDelay", reflect.TypeOf((*MockSentPacketHandler)(nil).SetMaxAckDelay), arg0)
|
||||
}
|
||||
|
||||
// ShouldSendNumPackets mocks base method
|
||||
func (m *MockSentPacketHandler) ShouldSendNumPackets() int {
|
||||
m.ctrl.T.Helper()
|
||||
|
|
|
@ -939,6 +939,7 @@ func (s *session) processTransportParameters(data []byte) {
|
|||
s.packer.HandleTransportParameters(params)
|
||||
s.frameParser.SetAckDelayExponent(params.AckDelayExponent)
|
||||
s.connFlowController.UpdateSendWindow(params.InitialMaxData)
|
||||
s.sentPacketHandler.SetMaxAckDelay(params.MaxAckDelay)
|
||||
if params.StatelessResetToken != nil {
|
||||
s.sessionRunner.AddResetToken(*params.StatelessResetToken, s)
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue