limit the ACK delay by max_ack_delay

This commit is contained in:
Marten Seemann 2019-05-08 14:34:56 +09:00
parent 0e33f3c0da
commit 537737935c
5 changed files with 37 additions and 5 deletions

View file

@ -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

View file

@ -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() {

View file

@ -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() {

View file

@ -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()

View file

@ -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)
}