From 9b3ff059fc9d2dca5086504b79f6a89c0946a976 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Sun, 4 May 2025 18:51:39 +0800 Subject: [PATCH] delete closed connections after 3 PTOs (#5117) In most cases, this should be earlier than the current timeout value of 5s. --- conn_id_generator.go | 10 +++++----- conn_id_generator_test.go | 18 +++++++++--------- connection.go | 6 +++--- connection_test.go | 10 +++++----- integrationtests/self/close_test.go | 6 +++--- internal/protocol/params.go | 4 ---- mock_conn_runner_test.go | 13 +++++++------ mock_packet_handler_manager_test.go | 13 +++++++------ packet_handler_map.go | 15 ++++++--------- packet_handler_map_test.go | 10 ++++------ 10 files changed, 49 insertions(+), 56 deletions(-) diff --git a/conn_id_generator.go b/conn_id_generator.go index 0b0b90fd8..394d5b8a8 100644 --- a/conn_id_generator.go +++ b/conn_id_generator.go @@ -13,7 +13,7 @@ import ( type connRunnerCallbacks struct { AddConnectionID func(protocol.ConnectionID) RemoveConnectionID func(protocol.ConnectionID) - ReplaceWithClosed func([]protocol.ConnectionID, []byte) + ReplaceWithClosed func([]protocol.ConnectionID, []byte, time.Duration) } // The memory address of the Transport is used as the key. @@ -31,9 +31,9 @@ func (cr connRunners) RemoveConnectionID(id protocol.ConnectionID) { } } -func (cr connRunners) ReplaceWithClosed(ids []protocol.ConnectionID, b []byte) { +func (cr connRunners) ReplaceWithClosed(ids []protocol.ConnectionID, b []byte, expiry time.Duration) { for _, c := range cr { - c.ReplaceWithClosed(ids, b) + c.ReplaceWithClosed(ids, b, expiry) } } @@ -188,7 +188,7 @@ func (m *connIDGenerator) RemoveAll() { } } -func (m *connIDGenerator) ReplaceWithClosed(connClose []byte) { +func (m *connIDGenerator) ReplaceWithClosed(connClose []byte, expiry time.Duration) { connIDs := make([]protocol.ConnectionID, 0, len(m.activeSrcConnIDs)+len(m.connIDsToRetire)+1) if m.initialClientDestConnID != nil { connIDs = append(connIDs, *m.initialClientDestConnID) @@ -199,7 +199,7 @@ func (m *connIDGenerator) ReplaceWithClosed(connClose []byte) { for _, c := range m.connIDsToRetire { connIDs = append(connIDs, c.connID) } - m.connRunners.ReplaceWithClosed(connIDs, connClose) + m.connRunners.ReplaceWithClosed(connIDs, connClose, expiry) } func (m *connIDGenerator) AddConnRunner(id *Transport, r connRunnerCallbacks) { diff --git a/conn_id_generator_test.go b/conn_id_generator_test.go index bdd31bdb3..2c482cdbc 100644 --- a/conn_id_generator_test.go +++ b/conn_id_generator_test.go @@ -41,7 +41,7 @@ func testConnIDGeneratorIssueAndRetire(t *testing.T, hasInitialClientDestConnID connRunnerCallbacks{ AddConnectionID: func(c protocol.ConnectionID) { added = append(added, c) }, RemoveConnectionID: func(c protocol.ConnectionID) { removed = append(removed, c) }, - ReplaceWithClosed: func([]protocol.ConnectionID, []byte) {}, + ReplaceWithClosed: func([]protocol.ConnectionID, []byte, time.Duration) {}, }, func(f wire.Frame) { queuedFrames = append(queuedFrames, f) }, &protocol.DefaultConnectionIDGenerator{ConnLen: 5}, @@ -114,7 +114,7 @@ func TestConnIDGeneratorRetiring(t *testing.T) { connRunnerCallbacks{ AddConnectionID: func(c protocol.ConnectionID) { added = append(added, c) }, RemoveConnectionID: func(c protocol.ConnectionID) { removed = append(removed, c) }, - ReplaceWithClosed: func([]protocol.ConnectionID, []byte) {}, + ReplaceWithClosed: func([]protocol.ConnectionID, []byte, time.Duration) {}, }, func(f wire.Frame) {}, &protocol.DefaultConnectionIDGenerator{ConnLen: 5}, @@ -185,7 +185,7 @@ func testConnIDGeneratorRemoveAll(t *testing.T, hasInitialClientDestConnID bool) connRunnerCallbacks{ AddConnectionID: func(c protocol.ConnectionID) { added = append(added, c) }, RemoveConnectionID: func(c protocol.ConnectionID) { removed = append(removed, c) }, - ReplaceWithClosed: func([]protocol.ConnectionID, []byte) {}, + ReplaceWithClosed: func([]protocol.ConnectionID, []byte, time.Duration) {}, }, func(f wire.Frame) {}, &protocol.DefaultConnectionIDGenerator{ConnLen: 5}, @@ -235,7 +235,7 @@ func testConnIDGeneratorReplaceWithClosed(t *testing.T, hasInitialClientDestConn connRunnerCallbacks{ AddConnectionID: func(c protocol.ConnectionID) { added = append(added, c) }, RemoveConnectionID: func(c protocol.ConnectionID) { t.Fatal("didn't expect conn ID removals") }, - ReplaceWithClosed: func(connIDs []protocol.ConnectionID, b []byte) { + ReplaceWithClosed: func(connIDs []protocol.ConnectionID, b []byte, _ time.Duration) { replaced = connIDs replacedWith = b }, @@ -252,7 +252,7 @@ func testConnIDGeneratorReplaceWithClosed(t *testing.T, hasInitialClientDestConn require.NoError(t, g.Retire(4, protocol.ParseConnectionID([]byte{1, 1, 1, 1}), time.Now())) require.Len(t, added, protocol.MaxIssuedConnectionIDs+1) - g.ReplaceWithClosed([]byte("foobar")) + g.ReplaceWithClosed([]byte("foobar"), time.Second) if hasInitialClientDestConnID { require.Len(t, replaced, protocol.MaxIssuedConnectionIDs+3) require.Contains(t, replaced, *initialClientDestConnID) @@ -278,21 +278,21 @@ func TestConnIDGeneratorAddConnRunner(t *testing.T) { runner1 := connRunnerCallbacks{ AddConnectionID: func(c protocol.ConnectionID) { tracker1.added = append(tracker1.added, c) }, RemoveConnectionID: func(c protocol.ConnectionID) { tracker1.removed = append(tracker1.removed, c) }, - ReplaceWithClosed: func(connIDs []protocol.ConnectionID, _ []byte) { + ReplaceWithClosed: func(connIDs []protocol.ConnectionID, _ []byte, _ time.Duration) { tracker1.replaced = append(tracker1.replaced, connIDs...) }, } runner2 := connRunnerCallbacks{ AddConnectionID: func(c protocol.ConnectionID) { tracker2.added = append(tracker2.added, c) }, RemoveConnectionID: func(c protocol.ConnectionID) { tracker2.removed = append(tracker2.removed, c) }, - ReplaceWithClosed: func(connIDs []protocol.ConnectionID, _ []byte) { + ReplaceWithClosed: func(connIDs []protocol.ConnectionID, _ []byte, _ time.Duration) { tracker2.replaced = append(tracker2.replaced, connIDs...) }, } runner3 := connRunnerCallbacks{ AddConnectionID: func(c protocol.ConnectionID) { tracker3.added = append(tracker3.added, c) }, RemoveConnectionID: func(c protocol.ConnectionID) { tracker3.removed = append(tracker3.removed, c) }, - ReplaceWithClosed: func(connIDs []protocol.ConnectionID, _ []byte) { + ReplaceWithClosed: func(connIDs []protocol.ConnectionID, _ []byte, _ time.Duration) { tracker3.replaced = append(tracker3.replaced, connIDs...) }, } @@ -345,7 +345,7 @@ func TestConnIDGeneratorAddConnRunner(t *testing.T) { require.Equal(t, []protocol.ConnectionID{clientDestConnID}, tracker1.removed) require.Equal(t, []protocol.ConnectionID{clientDestConnID}, tracker2.removed) - g.ReplaceWithClosed([]byte("connection closed")) + g.ReplaceWithClosed([]byte("connection closed"), time.Second) require.True(t, len(tracker1.replaced) > 0) require.Equal(t, tracker1.replaced, tracker2.replaced) diff --git a/connection.go b/connection.go index 1165078e7..e03e8c945 100644 --- a/connection.go +++ b/connection.go @@ -87,7 +87,7 @@ func (p *receivedPacket) Clone() *receivedPacket { type connRunner interface { Add(protocol.ConnectionID, packetHandler) bool Remove(protocol.ConnectionID) - ReplaceWithClosed([]protocol.ConnectionID, []byte) + ReplaceWithClosed([]protocol.ConnectionID, []byte, time.Duration) AddResetToken(protocol.StatelessResetToken, packetHandler) RemoveResetToken(protocol.StatelessResetToken) } @@ -1908,7 +1908,7 @@ func (s *connection) handleCloseError(closeErr *closeError) { // If this is a remote close we're done here if isRemoteClose { - s.connIDGenerator.ReplaceWithClosed(nil) + s.connIDGenerator.ReplaceWithClosed(nil, 3*s.rttStats.PTO(false)) return } if closeErr.immediate { @@ -1925,7 +1925,7 @@ func (s *connection) handleCloseError(closeErr *closeError) { if err != nil { s.logger.Debugf("Error sending CONNECTION_CLOSE: %s", err) } - s.connIDGenerator.ReplaceWithClosed(connClosePacket) + s.connIDGenerator.ReplaceWithClosed(connClosePacket, 3*s.rttStats.PTO(false)) } func (s *connection) dropEncryptionLevel(encLevel protocol.EncryptionLevel, now time.Time) error { diff --git a/connection_test.go b/connection_test.go index 75e331663..691494f4f 100644 --- a/connection_test.go +++ b/connection_test.go @@ -442,7 +442,7 @@ func TestConnectionTransportError(t *testing.T) { b.Data = append(b.Data, []byte("connection close")...) tc.packer.EXPECT().PackConnectionClose(expectedErr, gomock.Any(), protocol.Version1).Return(&coalescedPacket{buffer: b}, nil) tc.sendConn.EXPECT().Write([]byte("connection close"), gomock.Any(), gomock.Any()) - tc.connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any()).AnyTimes() + tc.connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() gomock.InOrder( tracer.EXPECT().ClosedConnection(expectedErr), tracer.EXPECT().Close(), @@ -476,7 +476,7 @@ func TestConnectionApplicationClose(t *testing.T) { b.Data = append(b.Data, []byte("connection close")...) tc.packer.EXPECT().PackApplicationClose(expectedErr, gomock.Any(), protocol.Version1).Return(&coalescedPacket{buffer: b}, nil) tc.sendConn.EXPECT().Write([]byte("connection close"), gomock.Any(), gomock.Any()) - tc.connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any()).AnyTimes() + tc.connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any(), gomock.Any()).AnyTimes() gomock.InOrder( tracer.EXPECT().ClosedConnection(expectedErr), tracer.EXPECT().Close(), @@ -835,7 +835,7 @@ func testConnectionUnpackFailureFatal(t *testing.T, unpackErr error) error { connectionOptUnpacker(unpacker), ) - tc.connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any()) + tc.connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any(), gomock.Any()) unpacker.EXPECT().UnpackShortHeader(gomock.Any(), gomock.Any()).Return(protocol.PacketNumber(0), protocol.PacketNumberLen(0), protocol.KeyPhaseBit(0), nil, unpackErr) tc.packer.EXPECT().PackConnectionClose(gomock.Any(), gomock.Any(), protocol.Version1).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil) errChan := make(chan error, 1) @@ -952,7 +952,7 @@ func TestConnectionRemoteClose(t *testing.T) { tracer.EXPECT().ReceivedShortHeaderPacket(gomock.Any(), gomock.Any(), gomock.Any(), gomock.Any()) expectedErr := &qerr.TransportError{ErrorCode: qerr.StreamLimitError, Remote: true} - tc.connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any()) + tc.connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any(), gomock.Any()) streamErrChan := make(chan error, 1) mockStreamManager.EXPECT().CloseWithError(gomock.Any()).Do(func(e error) { streamErrChan <- e }) tracerErrChan := make(chan error, 1) @@ -1407,7 +1407,7 @@ func TestConnection0RTTTransportParameters(t *testing.T) { ) tc.packer.EXPECT().PackCoalescedPacket(false, gomock.Any(), gomock.Any(), protocol.Version1).Return(nil, nil).AnyTimes() tc.packer.EXPECT().PackConnectionClose(gomock.Any(), gomock.Any(), protocol.Version1).Return(&coalescedPacket{buffer: getPacketBuffer()}, nil) - tc.connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any()) + tc.connRunner.EXPECT().ReplaceWithClosed(gomock.Any(), gomock.Any(), gomock.Any()) errChan := make(chan error, 1) go func() { errChan <- tc.conn.run() }() diff --git a/integrationtests/self/close_test.go b/integrationtests/self/close_test.go index 94ab8e8d4..de4f7da56 100644 --- a/integrationtests/self/close_test.go +++ b/integrationtests/self/close_test.go @@ -31,7 +31,7 @@ func TestConnectionCloseRetransmission(t *testing.T) { Conn: newUDPConnLocalhost(t), ServerAddr: server.Addr().(*net.UDPAddr), DelayPacket: func(quicproxy.Direction, net.Addr, net.Addr, []byte) time.Duration { - return 5 * time.Millisecond // 10ms RTT + return scaleDuration(5 * time.Millisecond) // 10ms RTT }, DropPacket: func(dir quicproxy.Direction, _, _ net.Addr, b []byte) bool { if drop := drop.Load(); drop && dir == quicproxy.DirectionOutgoing { @@ -57,7 +57,7 @@ func TestConnectionCloseRetransmission(t *testing.T) { sconn.CloseWithError(1337, "closing") // send 100 packets - for i := 0; i < 100; i++ { + for range 100 { str, err := conn.OpenStream() require.NoError(t, err) _, err = str.Write([]byte("foobar")) @@ -68,7 +68,7 @@ func TestConnectionCloseRetransmission(t *testing.T) { // Expect retransmissions of the CONNECTION_CLOSE for the // 1st, 2nd, 4th, 8th, 16th, 32th, 64th packet: 7 in total (+1 for the original packet) var packets [][]byte - for i := 0; i < 8; i++ { + for range 8 { select { case p := <-dropped: packets = append(packets, p) diff --git a/internal/protocol/params.go b/internal/protocol/params.go index f0aa3ad97..fe86317fb 100644 --- a/internal/protocol/params.go +++ b/internal/protocol/params.go @@ -102,10 +102,6 @@ const DefaultIdleTimeout = 30 * time.Second // DefaultHandshakeIdleTimeout is the default idle timeout used before handshake completion. const DefaultHandshakeIdleTimeout = 5 * time.Second -// RetiredConnectionIDDeleteTimeout is the time we keep closed connections around in order to retransmit the CONNECTION_CLOSE. -// after this time all information about the old connection will be deleted -const RetiredConnectionIDDeleteTimeout = 5 * time.Second - // MinStreamFrameSize is the minimum size that has to be left in a packet, so that we add another STREAM frame. // This avoids splitting up STREAM frames into small pieces, which has 2 advantages: // 1. it reduces the framing overhead diff --git a/mock_conn_runner_test.go b/mock_conn_runner_test.go index b6868fc31..f2d68168a 100644 --- a/mock_conn_runner_test.go +++ b/mock_conn_runner_test.go @@ -11,6 +11,7 @@ package quic import ( reflect "reflect" + time "time" protocol "github.com/quic-go/quic-go/internal/protocol" gomock "go.uber.org/mock/gomock" @@ -187,15 +188,15 @@ func (c *MockConnRunnerRemoveResetTokenCall) DoAndReturn(f func(protocol.Statele } // ReplaceWithClosed mocks base method. -func (m *MockConnRunner) ReplaceWithClosed(arg0 []protocol.ConnectionID, arg1 []byte) { +func (m *MockConnRunner) ReplaceWithClosed(arg0 []protocol.ConnectionID, arg1 []byte, arg2 time.Duration) { m.ctrl.T.Helper() - m.ctrl.Call(m, "ReplaceWithClosed", arg0, arg1) + m.ctrl.Call(m, "ReplaceWithClosed", arg0, arg1, arg2) } // ReplaceWithClosed indicates an expected call of ReplaceWithClosed. -func (mr *MockConnRunnerMockRecorder) ReplaceWithClosed(arg0, arg1 any) *MockConnRunnerReplaceWithClosedCall { +func (mr *MockConnRunnerMockRecorder) ReplaceWithClosed(arg0, arg1, arg2 any) *MockConnRunnerReplaceWithClosedCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceWithClosed", reflect.TypeOf((*MockConnRunner)(nil).ReplaceWithClosed), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceWithClosed", reflect.TypeOf((*MockConnRunner)(nil).ReplaceWithClosed), arg0, arg1, arg2) return &MockConnRunnerReplaceWithClosedCall{Call: call} } @@ -211,13 +212,13 @@ func (c *MockConnRunnerReplaceWithClosedCall) Return() *MockConnRunnerReplaceWit } // Do rewrite *gomock.Call.Do -func (c *MockConnRunnerReplaceWithClosedCall) Do(f func([]protocol.ConnectionID, []byte)) *MockConnRunnerReplaceWithClosedCall { +func (c *MockConnRunnerReplaceWithClosedCall) Do(f func([]protocol.ConnectionID, []byte, time.Duration)) *MockConnRunnerReplaceWithClosedCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockConnRunnerReplaceWithClosedCall) DoAndReturn(f func([]protocol.ConnectionID, []byte)) *MockConnRunnerReplaceWithClosedCall { +func (c *MockConnRunnerReplaceWithClosedCall) DoAndReturn(f func([]protocol.ConnectionID, []byte, time.Duration)) *MockConnRunnerReplaceWithClosedCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/mock_packet_handler_manager_test.go b/mock_packet_handler_manager_test.go index 27c8f3b87..98b2ea172 100644 --- a/mock_packet_handler_manager_test.go +++ b/mock_packet_handler_manager_test.go @@ -11,6 +11,7 @@ package quic import ( reflect "reflect" + time "time" protocol "github.com/quic-go/quic-go/internal/protocol" gomock "go.uber.org/mock/gomock" @@ -339,15 +340,15 @@ func (c *MockPacketHandlerManagerRemoveResetTokenCall) DoAndReturn(f func(protoc } // ReplaceWithClosed mocks base method. -func (m *MockPacketHandlerManager) ReplaceWithClosed(arg0 []protocol.ConnectionID, arg1 []byte) { +func (m *MockPacketHandlerManager) ReplaceWithClosed(arg0 []protocol.ConnectionID, arg1 []byte, arg2 time.Duration) { m.ctrl.T.Helper() - m.ctrl.Call(m, "ReplaceWithClosed", arg0, arg1) + m.ctrl.Call(m, "ReplaceWithClosed", arg0, arg1, arg2) } // ReplaceWithClosed indicates an expected call of ReplaceWithClosed. -func (mr *MockPacketHandlerManagerMockRecorder) ReplaceWithClosed(arg0, arg1 any) *MockPacketHandlerManagerReplaceWithClosedCall { +func (mr *MockPacketHandlerManagerMockRecorder) ReplaceWithClosed(arg0, arg1, arg2 any) *MockPacketHandlerManagerReplaceWithClosedCall { mr.mock.ctrl.T.Helper() - call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceWithClosed", reflect.TypeOf((*MockPacketHandlerManager)(nil).ReplaceWithClosed), arg0, arg1) + call := mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReplaceWithClosed", reflect.TypeOf((*MockPacketHandlerManager)(nil).ReplaceWithClosed), arg0, arg1, arg2) return &MockPacketHandlerManagerReplaceWithClosedCall{Call: call} } @@ -363,13 +364,13 @@ func (c *MockPacketHandlerManagerReplaceWithClosedCall) Return() *MockPacketHand } // Do rewrite *gomock.Call.Do -func (c *MockPacketHandlerManagerReplaceWithClosedCall) Do(f func([]protocol.ConnectionID, []byte)) *MockPacketHandlerManagerReplaceWithClosedCall { +func (c *MockPacketHandlerManagerReplaceWithClosedCall) Do(f func([]protocol.ConnectionID, []byte, time.Duration)) *MockPacketHandlerManagerReplaceWithClosedCall { c.Call = c.Call.Do(f) return c } // DoAndReturn rewrite *gomock.Call.DoAndReturn -func (c *MockPacketHandlerManagerReplaceWithClosedCall) DoAndReturn(f func([]protocol.ConnectionID, []byte)) *MockPacketHandlerManagerReplaceWithClosedCall { +func (c *MockPacketHandlerManagerReplaceWithClosedCall) DoAndReturn(f func([]protocol.ConnectionID, []byte, time.Duration)) *MockPacketHandlerManagerReplaceWithClosedCall { c.Call = c.Call.DoAndReturn(f) return c } diff --git a/packet_handler_map.go b/packet_handler_map.go index 83afdbfd4..ec65ae0b1 100644 --- a/packet_handler_map.go +++ b/packet_handler_map.go @@ -49,8 +49,6 @@ type packetHandlerMap struct { enqueueClosePacket func(closePacket) - deleteRetiredConnsAfter time.Duration - logger utils.Logger } @@ -58,11 +56,10 @@ var _ packetHandlerManager = &packetHandlerMap{} func newPacketHandlerMap(enqueueClosePacket func(closePacket), logger utils.Logger) *packetHandlerMap { return &packetHandlerMap{ - handlers: make(map[protocol.ConnectionID]packetHandler), - resetTokens: make(map[protocol.StatelessResetToken]packetHandler), - deleteRetiredConnsAfter: protocol.RetiredConnectionIDDeleteTimeout, - enqueueClosePacket: enqueueClosePacket, - logger: logger, + handlers: make(map[protocol.ConnectionID]packetHandler), + resetTokens: make(map[protocol.StatelessResetToken]packetHandler), + enqueueClosePacket: enqueueClosePacket, + logger: logger, } } @@ -112,7 +109,7 @@ func (h *packetHandlerMap) Remove(id protocol.ConnectionID) { // Depending on which side closed the connection, we need to: // * remote close: absorb delayed packets // * local close: retransmit the CONNECTION_CLOSE packet, in case it was lost -func (h *packetHandlerMap) ReplaceWithClosed(ids []protocol.ConnectionID, connClosePacket []byte) { +func (h *packetHandlerMap) ReplaceWithClosed(ids []protocol.ConnectionID, connClosePacket []byte, expiry time.Duration) { var handler packetHandler if connClosePacket != nil { handler = newClosedLocalConn( @@ -132,7 +129,7 @@ func (h *packetHandlerMap) ReplaceWithClosed(ids []protocol.ConnectionID, connCl h.mutex.Unlock() h.logger.Debugf("Replacing connection for connection IDs %s with a closed connection.", ids) - time.AfterFunc(h.deleteRetiredConnsAfter, func() { + time.AfterFunc(expiry, func() { h.mutex.Lock() for _, id := range ids { delete(h.handlers, id) diff --git a/packet_handler_map_test.go b/packet_handler_map_test.go index e4442d4f4..a285ba80e 100644 --- a/packet_handler_map_test.go +++ b/packet_handler_map_test.go @@ -74,12 +74,11 @@ func TestPacketHandlerMapReplaceWithLocalClosed(t *testing.T) { utils.DefaultLogger, ) dur := scaleDuration(10 * time.Millisecond) - m.deleteRetiredConnsAfter = dur handler := &mockPacketHandler{} connID := protocol.ParseConnectionID([]byte{4, 3, 2, 1}) require.True(t, m.Add(connID, handler)) - m.ReplaceWithClosed([]protocol.ConnectionID{connID}, []byte("foobar")) + m.ReplaceWithClosed([]protocol.ConnectionID{connID}, []byte("foobar"), dur) h, ok := m.Get(connID) require.True(t, ok) require.NotEqual(t, handler, h) @@ -93,7 +92,7 @@ func TestPacketHandlerMapReplaceWithLocalClosed(t *testing.T) { require.Eventually(t, func() bool { _, ok := m.Get(connID) return !ok - }, time.Second, 10*time.Millisecond) + }, time.Second, dur) } func TestPacketHandlerMapReplaceWithRemoteClosed(t *testing.T) { @@ -102,13 +101,12 @@ func TestPacketHandlerMapReplaceWithRemoteClosed(t *testing.T) { func(p closePacket) { closePackets = append(closePackets, p) }, utils.DefaultLogger, ) - dur := scaleDuration(50 * time.Millisecond) - m.deleteRetiredConnsAfter = dur + dur := scaleDuration(25 * time.Millisecond) handler := &mockPacketHandler{} connID := protocol.ParseConnectionID([]byte{4, 3, 2, 1}) require.True(t, m.Add(connID, handler)) - m.ReplaceWithClosed([]protocol.ConnectionID{connID}, nil) + m.ReplaceWithClosed([]protocol.ConnectionID{connID}, nil, dur) h, ok := m.Get(connID) require.True(t, ok) require.NotEqual(t, handler, h)