From 1f676c2a6c458e6d37a924538f067683d6065fdc Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 10 Jul 2020 11:13:36 +0700 Subject: [PATCH 1/4] use an errors.As comparison to detect stateless resets in the session --- packet_handler_map.go | 4 +--- packet_handler_map_test.go | 12 ++++++++---- session.go | 5 +++-- session_test.go | 17 +++++++++++++++++ 4 files changed, 29 insertions(+), 9 deletions(-) diff --git a/packet_handler_map.go b/packet_handler_map.go index 6831ecfa8..49195c3a3 100644 --- a/packet_handler_map.go +++ b/packet_handler_map.go @@ -19,8 +19,6 @@ type statelessResetErr struct { token *[16]byte } -func (e statelessResetErr) StatelessResetToken() *[16]byte { return e.token } - func (e statelessResetErr) Error() string { return fmt.Sprintf("received a stateless reset with token %x", *e.token) } @@ -319,7 +317,7 @@ func (h *packetHandlerMap) maybeHandleStatelessReset(data []byte) bool { copy(token[:], data[len(data)-16:]) if sess, ok := h.resetTokens[token]; ok { h.logger.Debugf("Received a stateless reset with token %#x. Closing session.", token) - go sess.destroy(&statelessResetErr{token: &token}) + go sess.destroy(statelessResetErr{token: &token}) return true } return false diff --git a/packet_handler_map_test.go b/packet_handler_map_test.go index a110b8d9e..c08c75ac1 100644 --- a/packet_handler_map_test.go +++ b/packet_handler_map_test.go @@ -242,10 +242,12 @@ var _ = Describe("Packet Handler Map", func() { packet = append(packet, token[:]...) destroyed := make(chan struct{}) packetHandler.EXPECT().destroy(gomock.Any()).Do(func(err error) { + defer GinkgoRecover() Expect(err).To(HaveOccurred()) - Expect(err).To(BeAssignableToTypeOf(&statelessResetErr{})) + var resetErr statelessResetErr + Expect(errors.As(err, &resetErr)).To(BeTrue()) Expect(err.Error()).To(ContainSubstring("received a stateless reset")) - Expect(*err.(*statelessResetErr).StatelessResetToken()).To(Equal(token)) + Expect(resetErr.token).To(Equal(&token)) close(destroyed) }) conn.dataToRead <- packet @@ -261,10 +263,12 @@ var _ = Describe("Packet Handler Map", func() { packet = append(packet, token[:]...) destroyed := make(chan struct{}) packetHandler.EXPECT().destroy(gomock.Any()).Do(func(err error) { + defer GinkgoRecover() Expect(err).To(HaveOccurred()) - Expect(err).To(BeAssignableToTypeOf(&statelessResetErr{})) + var resetErr statelessResetErr + Expect(errors.As(err, &resetErr)).To(BeTrue()) Expect(err.Error()).To(ContainSubstring("received a stateless reset")) - Expect(*err.(*statelessResetErr).StatelessResetToken()).To(Equal(token)) + Expect(resetErr.token).To(Equal(&token)) close(destroyed) }) conn.dataToRead <- packet diff --git a/session.go b/session.go index 2af7425c2..09fe0e10d 100644 --- a/session.go +++ b/session.go @@ -1299,8 +1299,9 @@ func (s *session) handleCloseError(closeErr closeError) { if s.tracer != nil { // timeout errors are logged as soon as they occur (to distinguish between handshake and idle timeouts) if nerr, ok := closeErr.err.(net.Error); !ok || !nerr.Timeout() { - if statelessReset, ok := closeErr.err.(interface{ StatelessResetToken() *[16]byte }); ok && s.tracer != nil { - s.tracer.ClosedConnection(logging.NewStatelessResetCloseReason(statelessReset.StatelessResetToken())) + var resetErr statelessResetErr + if errors.As(closeErr.err, &resetErr) { + s.tracer.ClosedConnection(logging.NewStatelessResetCloseReason(resetErr.token)) } else if quicErr.IsApplicationError() { s.tracer.ClosedConnection(logging.NewApplicationCloseReason(quicErr.ErrorCode, closeErr.remote)) } else { diff --git a/session_test.go b/session_test.go index b10050d17..38b50f7c9 100644 --- a/session_test.go +++ b/session_test.go @@ -639,6 +639,23 @@ var _ = Describe("Session", func() { sess.scheduleSending() Eventually(sess.Context().Done()).Should(BeClosed()) }) + + It("closes due to a stateless reset", func() { + token := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + runSession() + gomock.InOrder( + tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(reason logging.CloseReason) { + t, ok := reason.StatelessReset() + Expect(ok).To(BeTrue()) + Expect(t).To(Equal(token)) + }), + tracer.EXPECT().Close(), + ) + streamManager.EXPECT().CloseWithError(gomock.Any()) + sessionRunner.EXPECT().Remove(gomock.Any()).AnyTimes() + cryptoSetup.EXPECT().Close() + sess.destroy(statelessResetErr{token: &token}) + }) }) Context("receiving packets", func() { From 0ef1b2f92e4f7637ddb96b8e4a1c095f26526198 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 10 Jul 2020 11:21:12 +0700 Subject: [PATCH 2/4] pass around the stateless reset token directly, not pointers to it Benchmarks show that it's actually faster to make a copy of this 16 byte array than passing around a pointer to it. --- conn_id_manager.go | 12 ++++++------ conn_id_manager_test.go | 16 +++++++--------- internal/utils/new_connection_id.go | 2 +- packet_handler_map.go | 6 +++--- packet_handler_map_test.go | 4 ++-- session.go | 4 ++-- session_test.go | 2 +- 7 files changed, 22 insertions(+), 24 deletions(-) diff --git a/conn_id_manager.go b/conn_id_manager.go index 92bffe206..46b0d115a 100644 --- a/conn_id_manager.go +++ b/conn_id_manager.go @@ -53,7 +53,7 @@ func newConnIDManager( } } -func (h *connIDManager) AddFromPreferredAddress(connID protocol.ConnectionID, resetToken *[16]byte) error { +func (h *connIDManager) AddFromPreferredAddress(connID protocol.ConnectionID, resetToken [16]byte) error { return h.addConnectionID(1, connID, resetToken) } @@ -98,7 +98,7 @@ func (h *connIDManager) add(f *wire.NewConnectionIDFrame) error { return nil } - if err := h.addConnectionID(f.SequenceNumber, f.ConnectionID, &f.StatelessResetToken); err != nil { + if err := h.addConnectionID(f.SequenceNumber, f.ConnectionID, f.StatelessResetToken); err != nil { return err } @@ -110,7 +110,7 @@ func (h *connIDManager) add(f *wire.NewConnectionIDFrame) error { return nil } -func (h *connIDManager) addConnectionID(seq uint64, connID protocol.ConnectionID, resetToken *[16]byte) error { +func (h *connIDManager) addConnectionID(seq uint64, connID protocol.ConnectionID, resetToken [16]byte) error { // insert a new element at the end if h.queue.Len() == 0 || h.queue.Back().Value.SequenceNumber < seq { h.queue.PushBack(utils.NewConnectionID{ @@ -126,7 +126,7 @@ func (h *connIDManager) addConnectionID(seq uint64, connID protocol.ConnectionID if !el.Value.ConnectionID.Equal(connID) { return fmt.Errorf("received conflicting connection IDs for sequence number %d", seq) } - if *el.Value.StatelessResetToken != *resetToken { + if el.Value.StatelessResetToken != resetToken { return fmt.Errorf("received conflicting stateless reset tokens for sequence number %d", seq) } break @@ -155,7 +155,7 @@ func (h *connIDManager) updateConnectionID() { front := h.queue.Remove(h.queue.Front()) h.activeSequenceNumber = front.SequenceNumber h.activeConnectionID = front.ConnectionID - h.activeStatelessResetToken = front.StatelessResetToken + h.activeStatelessResetToken = &front.StatelessResetToken h.packetsSinceLastChange = 0 h.packetsPerConnectionID = protocol.PacketsPerConnectionID/2 + uint64(h.rand.Int63n(protocol.PacketsPerConnectionID)) h.addStatelessResetToken(*h.activeStatelessResetToken) @@ -190,7 +190,7 @@ func (h *connIDManager) SentPacket() { } func (h *connIDManager) shouldUpdateConnID() bool { - // iniate the first change as early as possible + // initiate the first change as early as possible if h.queue.Len() > 0 && h.activeSequenceNumber == 0 { return true } diff --git a/conn_id_manager_test.go b/conn_id_manager_test.go index 34243f6fc..6287fbde6 100644 --- a/conn_id_manager_test.go +++ b/conn_id_manager_test.go @@ -33,9 +33,9 @@ var _ = Describe("Connection ID Manager", func() { }) }) - get := func() (protocol.ConnectionID, *[16]byte) { + get := func() (protocol.ConnectionID, [16]byte) { if m.queue.Len() == 0 { - return nil, nil + return nil, [16]byte{} } val := m.queue.Remove(m.queue.Front()) return val.ConnectionID, val.StatelessResetToken @@ -70,13 +70,12 @@ var _ = Describe("Connection ID Manager", func() { })).To(Succeed()) c1, rt1 := get() Expect(c1).To(Equal(protocol.ConnectionID{1, 2, 3, 4})) - Expect(*rt1).To(Equal([16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe})) + Expect(rt1).To(Equal([16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe})) c2, rt2 := get() Expect(c2).To(Equal(protocol.ConnectionID{2, 3, 4, 5})) - Expect(*rt2).To(Equal([16]byte{0xe, 0xd, 0xc, 0xb, 0xa, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0})) - c3, rt3 := get() + Expect(rt2).To(Equal([16]byte{0xe, 0xd, 0xc, 0xb, 0xa, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0})) + c3, _ := get() Expect(c3).To(BeNil()) - Expect(rt3).To(BeNil()) }) It("accepts duplicates", func() { @@ -94,10 +93,9 @@ var _ = Describe("Connection ID Manager", func() { Expect(m.Add(f2)).To(Succeed()) c1, rt1 := get() Expect(c1).To(Equal(protocol.ConnectionID{1, 2, 3, 4})) - Expect(*rt1).To(Equal([16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe})) - c2, rt2 := get() + Expect(rt1).To(Equal([16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe})) + c2, _ := get() Expect(c2).To(BeNil()) - Expect(rt2).To(BeNil()) }) It("ignores duplicates for the currently used connection ID", func() { diff --git a/internal/utils/new_connection_id.go b/internal/utils/new_connection_id.go index dd0d8bda8..54ab0149e 100644 --- a/internal/utils/new_connection_id.go +++ b/internal/utils/new_connection_id.go @@ -8,5 +8,5 @@ import ( type NewConnectionID struct { SequenceNumber uint64 ConnectionID protocol.ConnectionID - StatelessResetToken *[16]byte + StatelessResetToken [16]byte } diff --git a/packet_handler_map.go b/packet_handler_map.go index 49195c3a3..041ed4f34 100644 --- a/packet_handler_map.go +++ b/packet_handler_map.go @@ -16,11 +16,11 @@ import ( ) type statelessResetErr struct { - token *[16]byte + token [16]byte } func (e statelessResetErr) Error() string { - return fmt.Sprintf("received a stateless reset with token %x", *e.token) + return fmt.Sprintf("received a stateless reset with token %x", e.token) } // The packetHandlerMap stores packetHandlers, identified by connection ID. @@ -317,7 +317,7 @@ func (h *packetHandlerMap) maybeHandleStatelessReset(data []byte) bool { copy(token[:], data[len(data)-16:]) if sess, ok := h.resetTokens[token]; ok { h.logger.Debugf("Received a stateless reset with token %#x. Closing session.", token) - go sess.destroy(statelessResetErr{token: &token}) + go sess.destroy(statelessResetErr{token: token}) return true } return false diff --git a/packet_handler_map_test.go b/packet_handler_map_test.go index c08c75ac1..0f51d1d0d 100644 --- a/packet_handler_map_test.go +++ b/packet_handler_map_test.go @@ -247,7 +247,7 @@ var _ = Describe("Packet Handler Map", func() { var resetErr statelessResetErr Expect(errors.As(err, &resetErr)).To(BeTrue()) Expect(err.Error()).To(ContainSubstring("received a stateless reset")) - Expect(resetErr.token).To(Equal(&token)) + Expect(resetErr.token).To(Equal(token)) close(destroyed) }) conn.dataToRead <- packet @@ -268,7 +268,7 @@ var _ = Describe("Packet Handler Map", func() { var resetErr statelessResetErr Expect(errors.As(err, &resetErr)).To(BeTrue()) Expect(err.Error()).To(ContainSubstring("received a stateless reset")) - Expect(resetErr.token).To(Equal(&token)) + Expect(resetErr.token).To(Equal(token)) close(destroyed) }) conn.dataToRead <- packet diff --git a/session.go b/session.go index 09fe0e10d..d37da7f8d 100644 --- a/session.go +++ b/session.go @@ -1301,7 +1301,7 @@ func (s *session) handleCloseError(closeErr closeError) { if nerr, ok := closeErr.err.(net.Error); !ok || !nerr.Timeout() { var resetErr statelessResetErr if errors.As(closeErr.err, &resetErr) { - s.tracer.ClosedConnection(logging.NewStatelessResetCloseReason(resetErr.token)) + s.tracer.ClosedConnection(logging.NewStatelessResetCloseReason(&resetErr.token)) } else if quicErr.IsApplicationError() { s.tracer.ClosedConnection(logging.NewApplicationCloseReason(quicErr.ErrorCode, closeErr.remote)) } else { @@ -1408,7 +1408,7 @@ func (s *session) processTransportParametersImpl(params *wire.TransportParameter if params.PreferredAddress != nil { s.logger.Debugf("Server sent preferred_address. Retiring the preferred_address connection ID.") // Retire the connection ID. - s.connIDManager.AddFromPreferredAddress(params.PreferredAddress.ConnectionID, ¶ms.PreferredAddress.StatelessResetToken) + s.connIDManager.AddFromPreferredAddress(params.PreferredAddress.ConnectionID, params.PreferredAddress.StatelessResetToken) } // On the server side, the early session is ready as soon as we processed // the client's transport parameters. diff --git a/session_test.go b/session_test.go index 38b50f7c9..d9f4dc79c 100644 --- a/session_test.go +++ b/session_test.go @@ -654,7 +654,7 @@ var _ = Describe("Session", func() { streamManager.EXPECT().CloseWithError(gomock.Any()) sessionRunner.EXPECT().Remove(gomock.Any()).AnyTimes() cryptoSetup.EXPECT().Close() - sess.destroy(statelessResetErr{token: &token}) + sess.destroy(statelessResetErr{token: token}) }) }) From a4679bc02e49336f82d93bc95b0bdb7531352610 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 10 Jul 2020 11:32:21 +0700 Subject: [PATCH 3/4] also pass the stateless reset token by value to the tracer --- qlog/event.go | 4 ++-- qlog/qlog.go | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/qlog/event.go b/qlog/event.go index 49267da4c..77d59994b 100644 --- a/qlog/event.go +++ b/qlog/event.go @@ -179,7 +179,7 @@ func (e eventVersionNegotiationReceived) MarshalJSONObject(enc *gojay.Encoder) { } type eventStatelessResetReceived struct { - Token *[16]byte + Token [16]byte } func (e eventStatelessResetReceived) Category() category { return categoryTransport } @@ -188,7 +188,7 @@ func (e eventStatelessResetReceived) IsNil() bool { return false } func (e eventStatelessResetReceived) MarshalJSONObject(enc *gojay.Encoder) { enc.StringKey("packet_type", packetType(logging.PacketTypeStatelessReset).String()) - enc.StringKey("stateless_reset_token", fmt.Sprintf("%x", *e.Token)) + enc.StringKey("stateless_reset_token", fmt.Sprintf("%x", e.Token)) } type eventPacketBuffered struct { diff --git a/qlog/qlog.go b/qlog/qlog.go index fc976851f..e0bcf024f 100644 --- a/qlog/qlog.go +++ b/qlog/qlog.go @@ -171,7 +171,7 @@ func (t *connectionTracer) ClosedConnection(r logging.CloseReason) { t.recordEvent(time.Now(), &eventConnectionClosed{Reason: timeoutReason(reason)}) } else if token, ok := r.StatelessReset(); ok { t.recordEvent(time.Now(), &eventStatelessResetReceived{ - Token: &token, + Token: token, }) } } From a1bb39d6ab3b26a14fd46c71eea42e14779363dc Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 10 Jul 2020 11:53:14 +0700 Subject: [PATCH 4/4] introduce a protocol.StatelessResetToken --- conn_id_generator.go | 4 +- conn_id_generator_test.go | 4 +- conn_id_manager.go | 20 +++---- conn_id_manager_test.go | 60 +++++++++---------- fuzzing/frames/main.go | 2 +- internal/handshake/crypto_setup_test.go | 18 +++--- internal/protocol/protocol.go | 3 + internal/utils/new_connection_id.go | 2 +- internal/wire/frame_parser_test.go | 2 +- internal/wire/log_test.go | 2 +- internal/wire/new_connection_id_frame.go | 2 +- internal/wire/new_connection_id_frame_test.go | 4 +- internal/wire/transport_parameter_test.go | 36 ++++++----- internal/wire/transport_parameters.go | 6 +- logging/close_reason.go | 8 +-- logging/close_reason_test.go | 4 +- logging/interface.go | 2 + mock_packet_handler_manager_test.go | 10 ++-- mock_session_runner_test.go | 10 ++-- packet_handler_map.go | 18 +++--- packet_handler_map_test.go | 8 +-- qlog/event.go | 4 +- qlog/frame_test.go | 2 +- qlog/qlog_test.go | 6 +- server.go | 2 +- server_test.go | 30 +++++----- session.go | 16 ++--- session_test.go | 20 +++---- 28 files changed, 154 insertions(+), 151 deletions(-) diff --git a/conn_id_generator.go b/conn_id_generator.go index 80e7ef2e5..dbebe8c84 100644 --- a/conn_id_generator.go +++ b/conn_id_generator.go @@ -17,7 +17,7 @@ type connIDGenerator struct { initialClientDestConnID protocol.ConnectionID addConnectionID func(protocol.ConnectionID) - getStatelessResetToken func(protocol.ConnectionID) [16]byte + getStatelessResetToken func(protocol.ConnectionID) protocol.StatelessResetToken removeConnectionID func(protocol.ConnectionID) retireConnectionID func(protocol.ConnectionID) replaceWithClosed func(protocol.ConnectionID, packetHandler) @@ -28,7 +28,7 @@ func newConnIDGenerator( initialConnectionID protocol.ConnectionID, initialClientDestConnID protocol.ConnectionID, // nil for the client addConnectionID func(protocol.ConnectionID), - getStatelessResetToken func(protocol.ConnectionID) [16]byte, + getStatelessResetToken func(protocol.ConnectionID) protocol.StatelessResetToken, removeConnectionID func(protocol.ConnectionID), retireConnectionID func(protocol.ConnectionID), replaceWithClosed func(protocol.ConnectionID, packetHandler), diff --git a/conn_id_generator_test.go b/conn_id_generator_test.go index 46a500842..5ff7e361a 100644 --- a/conn_id_generator_test.go +++ b/conn_id_generator_test.go @@ -22,8 +22,8 @@ var _ = Describe("Connection ID Generator", func() { initialConnID := protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7} initialClientDestConnID := protocol.ConnectionID{0xa, 0xb, 0xc, 0xd, 0xe} - connIDToToken := func(c protocol.ConnectionID) [16]byte { - return [16]byte{c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0]} + connIDToToken := func(c protocol.ConnectionID) protocol.StatelessResetToken { + return protocol.StatelessResetToken{c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0], c[0]} } BeforeEach(func() { diff --git a/conn_id_manager.go b/conn_id_manager.go index 46b0d115a..8681b54a0 100644 --- a/conn_id_manager.go +++ b/conn_id_manager.go @@ -18,7 +18,7 @@ type connIDManager struct { activeSequenceNumber uint64 highestRetired uint64 activeConnectionID protocol.ConnectionID - activeStatelessResetToken *[16]byte + activeStatelessResetToken *protocol.StatelessResetToken // We change the connection ID after sending on average // protocol.PacketsPerConnectionID packets. The actual value is randomized @@ -27,17 +27,17 @@ type connIDManager struct { rand *mrand.Rand packetsPerConnectionID uint64 - addStatelessResetToken func([16]byte) - removeStatelessResetToken func([16]byte) - retireStatelessResetToken func([16]byte) + addStatelessResetToken func(protocol.StatelessResetToken) + removeStatelessResetToken func(protocol.StatelessResetToken) + retireStatelessResetToken func(protocol.StatelessResetToken) queueControlFrame func(wire.Frame) } func newConnIDManager( initialDestConnID protocol.ConnectionID, - addStatelessResetToken func([16]byte), - removeStatelessResetToken func([16]byte), - retireStatelessResetToken func([16]byte), + addStatelessResetToken func(protocol.StatelessResetToken), + removeStatelessResetToken func(protocol.StatelessResetToken), + retireStatelessResetToken func(protocol.StatelessResetToken), queueControlFrame func(wire.Frame), ) *connIDManager { b := make([]byte, 8) @@ -53,7 +53,7 @@ func newConnIDManager( } } -func (h *connIDManager) AddFromPreferredAddress(connID protocol.ConnectionID, resetToken [16]byte) error { +func (h *connIDManager) AddFromPreferredAddress(connID protocol.ConnectionID, resetToken protocol.StatelessResetToken) error { return h.addConnectionID(1, connID, resetToken) } @@ -110,7 +110,7 @@ func (h *connIDManager) add(f *wire.NewConnectionIDFrame) error { return nil } -func (h *connIDManager) addConnectionID(seq uint64, connID protocol.ConnectionID, resetToken [16]byte) error { +func (h *connIDManager) addConnectionID(seq uint64, connID protocol.ConnectionID, resetToken protocol.StatelessResetToken) error { // insert a new element at the end if h.queue.Len() == 0 || h.queue.Back().Value.SequenceNumber < seq { h.queue.PushBack(utils.NewConnectionID{ @@ -177,7 +177,7 @@ func (h *connIDManager) ChangeInitialConnID(newConnID protocol.ConnectionID) { } // is called when the server provides a stateless reset token in the transport parameters -func (h *connIDManager) SetStatelessResetToken(token [16]byte) { +func (h *connIDManager) SetStatelessResetToken(token protocol.StatelessResetToken) { if h.activeSequenceNumber != 0 { panic("expected first connection ID to have sequence number 0") } diff --git a/conn_id_manager_test.go b/conn_id_manager_test.go index 6287fbde6..9690c6c0c 100644 --- a/conn_id_manager_test.go +++ b/conn_id_manager_test.go @@ -11,9 +11,9 @@ var _ = Describe("Connection ID Manager", func() { var ( m *connIDManager frameQueue []wire.Frame - tokenAdded *[16]byte - retiredTokens [][16]byte - removedTokens [][16]byte + tokenAdded *protocol.StatelessResetToken + retiredTokens []protocol.StatelessResetToken + removedTokens []protocol.StatelessResetToken ) initialConnID := protocol.ConnectionID{0, 0, 0, 0} @@ -24,18 +24,18 @@ var _ = Describe("Connection ID Manager", func() { removedTokens = nil m = newConnIDManager( initialConnID, - func(token [16]byte) { tokenAdded = &token }, - func(token [16]byte) { removedTokens = append(removedTokens, token) }, - func(token [16]byte) { retiredTokens = append(retiredTokens, token) }, + func(token protocol.StatelessResetToken) { tokenAdded = &token }, + func(token protocol.StatelessResetToken) { removedTokens = append(removedTokens, token) }, + func(token protocol.StatelessResetToken) { retiredTokens = append(retiredTokens, token) }, func(f wire.Frame, ) { frameQueue = append(frameQueue, f) }) }) - get := func() (protocol.ConnectionID, [16]byte) { + get := func() (protocol.ConnectionID, protocol.StatelessResetToken) { if m.queue.Len() == 0 { - return nil, [16]byte{} + return nil, protocol.StatelessResetToken{} } val := m.queue.Remove(m.queue.Front()) return val.ConnectionID, val.StatelessResetToken @@ -51,7 +51,7 @@ var _ = Describe("Connection ID Manager", func() { }) It("sets the token for the first connection ID", func() { - token := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + token := protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} m.SetStatelessResetToken(token) Expect(*m.activeStatelessResetToken).To(Equal(token)) Expect(*tokenAdded).To(Equal(token)) @@ -61,19 +61,19 @@ var _ = Describe("Connection ID Manager", func() { Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: 10, ConnectionID: protocol.ConnectionID{2, 3, 4, 5}, - StatelessResetToken: [16]byte{0xe, 0xd, 0xc, 0xb, 0xa, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + StatelessResetToken: protocol.StatelessResetToken{0xe, 0xd, 0xc, 0xb, 0xa, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, })).To(Succeed()) Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: 4, ConnectionID: protocol.ConnectionID{1, 2, 3, 4}, - StatelessResetToken: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe}, + StatelessResetToken: protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe}, })).To(Succeed()) c1, rt1 := get() Expect(c1).To(Equal(protocol.ConnectionID{1, 2, 3, 4})) - Expect(rt1).To(Equal([16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe})) + Expect(rt1).To(Equal(protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe})) c2, rt2 := get() Expect(c2).To(Equal(protocol.ConnectionID{2, 3, 4, 5})) - Expect(rt2).To(Equal([16]byte{0xe, 0xd, 0xc, 0xb, 0xa, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0})) + Expect(rt2).To(Equal(protocol.StatelessResetToken{0xe, 0xd, 0xc, 0xb, 0xa, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0})) c3, _ := get() Expect(c3).To(BeNil()) }) @@ -82,18 +82,18 @@ var _ = Describe("Connection ID Manager", func() { f1 := &wire.NewConnectionIDFrame{ SequenceNumber: 1, ConnectionID: protocol.ConnectionID{1, 2, 3, 4}, - StatelessResetToken: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe}, + StatelessResetToken: protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe}, } f2 := &wire.NewConnectionIDFrame{ SequenceNumber: 1, ConnectionID: protocol.ConnectionID{1, 2, 3, 4}, - StatelessResetToken: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe}, + StatelessResetToken: protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe}, } Expect(m.Add(f1)).To(Succeed()) Expect(m.Add(f2)).To(Succeed()) c1, rt1 := get() Expect(c1).To(Equal(protocol.ConnectionID{1, 2, 3, 4})) - Expect(rt1).To(Equal([16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe})) + Expect(rt1).To(Equal(protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe})) c2, _ := get() Expect(c2).To(BeNil()) }) @@ -102,7 +102,7 @@ var _ = Describe("Connection ID Manager", func() { f := &wire.NewConnectionIDFrame{ SequenceNumber: 1, ConnectionID: protocol.ConnectionID{1, 2, 3, 4}, - StatelessResetToken: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe}, + StatelessResetToken: protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe}, } Expect(m.Add(f)).To(Succeed()) Expect(m.Get()).To(Equal(protocol.ConnectionID{1, 2, 3, 4})) @@ -129,12 +129,12 @@ var _ = Describe("Connection ID Manager", func() { Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: 42, ConnectionID: protocol.ConnectionID{1, 2, 3, 4}, - StatelessResetToken: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe}, + StatelessResetToken: protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe}, })).To(Succeed()) Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: 42, ConnectionID: protocol.ConnectionID{1, 2, 3, 4}, - StatelessResetToken: [16]byte{0xe, 0xd, 0xc, 0xb, 0xa, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, + StatelessResetToken: protocol.StatelessResetToken{0xe, 0xd, 0xc, 0xb, 0xa, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}, })).To(MatchError("received conflicting stateless reset tokens for sequence number 42")) }) @@ -225,13 +225,13 @@ var _ = Describe("Connection ID Manager", func() { Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: uint64(i), ConnectionID: protocol.ConnectionID{i, i, i, i}, - StatelessResetToken: [16]byte{i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i}, + StatelessResetToken: protocol.StatelessResetToken{i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i}, })).To(Succeed()) } Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: uint64(9999), ConnectionID: protocol.ConnectionID{1, 2, 3, 4}, - StatelessResetToken: [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + StatelessResetToken: protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, })).To(MatchError("CONNECTION_ID_LIMIT_ERROR")) }) @@ -240,7 +240,7 @@ var _ = Describe("Connection ID Manager", func() { Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: 1, ConnectionID: protocol.ConnectionID{1, 2, 3, 4}, - StatelessResetToken: [16]byte{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, + StatelessResetToken: protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, })).To(Succeed()) Expect(m.Get()).To(Equal(protocol.ConnectionID{1, 2, 3, 4})) @@ -252,7 +252,7 @@ var _ = Describe("Connection ID Manager", func() { Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: uint64(s), ConnectionID: protocol.ConnectionID{s, s, s, s}, - StatelessResetToken: [16]byte{s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s}, + StatelessResetToken: protocol.StatelessResetToken{s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s}, })).To(Succeed()) } @@ -272,7 +272,7 @@ var _ = Describe("Connection ID Manager", func() { Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: uint64(s), ConnectionID: protocol.ConnectionID{s, s, s, s}, - StatelessResetToken: [16]byte{s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s}, + StatelessResetToken: protocol.StatelessResetToken{s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s}, })).To(Succeed()) s++ } @@ -285,7 +285,7 @@ var _ = Describe("Connection ID Manager", func() { Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: uint64(s), ConnectionID: protocol.ConnectionID{s, s, s, s}, - StatelessResetToken: [16]byte{s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s}, + StatelessResetToken: protocol.StatelessResetToken{s, s, s, s, s, s, s, s, s, s, s, s, s, s, s, s}, })).To(Succeed()) } Expect(m.Get()).To(Equal(protocol.ConnectionID{10, 10, 10, 10})) @@ -302,7 +302,7 @@ var _ = Describe("Connection ID Manager", func() { Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: uint64(5), ConnectionID: protocol.ConnectionID{5, 5, 5, 5}, - StatelessResetToken: [16]byte{5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, + StatelessResetToken: protocol.StatelessResetToken{5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, })).To(Succeed()) Expect(m.queue.Front().Value.ConnectionID).To(Equal(protocol.ConnectionID{12, 12, 12, 12})) Expect(frameQueue).To(HaveLen(1)) @@ -314,7 +314,7 @@ var _ = Describe("Connection ID Manager", func() { Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: uint64(i), ConnectionID: protocol.ConnectionID{i, i, i, i}, - StatelessResetToken: [16]byte{i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i}, + StatelessResetToken: protocol.StatelessResetToken{i, i, i, i, i, i, i, i, i, i, i, i, i, i, i, i}, })).To(Succeed()) } Expect(m.Get()).To(Equal(protocol.ConnectionID{1, 1, 1, 1})) @@ -328,7 +328,7 @@ var _ = Describe("Connection ID Manager", func() { })).To(Succeed()) Expect(m.Get()).To(Equal(protocol.ConnectionID{2, 2, 2, 2})) Expect(retiredTokens).To(HaveLen(1)) - Expect(retiredTokens[0]).To(Equal([16]byte{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})) + Expect(retiredTokens[0]).To(Equal(protocol.StatelessResetToken{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1})) }) It("removes the currently active stateless reset token when it is closed", func() { @@ -338,12 +338,12 @@ var _ = Describe("Connection ID Manager", func() { Expect(m.Add(&wire.NewConnectionIDFrame{ SequenceNumber: 1, ConnectionID: protocol.ConnectionID{1, 2, 3, 4}, - StatelessResetToken: [16]byte{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, + StatelessResetToken: protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, })).To(Succeed()) Expect(m.Get()).To(Equal(protocol.ConnectionID{1, 2, 3, 4})) m.Close() Expect(retiredTokens).To(BeEmpty()) Expect(removedTokens).To(HaveLen(1)) - Expect(removedTokens[0]).To(Equal([16]byte{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1})) + Expect(removedTokens[0]).To(Equal(protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1})) }) }) diff --git a/fuzzing/frames/main.go b/fuzzing/frames/main.go index f6bf2344a..c81bf0f45 100644 --- a/fuzzing/frames/main.go +++ b/fuzzing/frames/main.go @@ -214,7 +214,7 @@ func getFrames() []wire.Frame { seq1 := getRandomNumber() seq2 := getRandomNumber() - var token1, token2 [16]byte + var token1, token2 protocol.StatelessResetToken copy(token1[:], getRandomData(16)) copy(token2[:], getRandomData(16)) frames = append(frames, []wire.Frame{ diff --git a/internal/handshake/crypto_setup_test.go b/internal/handshake/crypto_setup_test.go index 343100afc..3bf8f8260 100644 --- a/internal/handshake/crypto_setup_test.go +++ b/internal/handshake/crypto_setup_test.go @@ -88,7 +88,7 @@ var _ = Describe("Crypto Setup TLS", func() { return &tls.Config{ServerName: ch.ServerName}, nil }, } - var token [16]byte + var token protocol.StatelessResetToken server := NewCryptoSetupServer( &bytes.Buffer{}, &bytes.Buffer{}, @@ -122,7 +122,7 @@ var _ = Describe("Crypto Setup TLS", func() { runner := NewMockHandshakeRunner(mockCtrl) runner.EXPECT().OnError(gomock.Any()).Do(func(e error) { sErrChan <- e }) _, sInitialStream, sHandshakeStream := initStreams() - var token [16]byte + var token protocol.StatelessResetToken server := NewCryptoSetupServer( sInitialStream, sHandshakeStream, @@ -162,7 +162,7 @@ var _ = Describe("Crypto Setup TLS", func() { _, sInitialStream, sHandshakeStream := initStreams() runner := NewMockHandshakeRunner(mockCtrl) runner.EXPECT().OnError(gomock.Any()).Do(func(e error) { sErrChan <- e }) - var token [16]byte + var token protocol.StatelessResetToken server := NewCryptoSetupServer( sInitialStream, sHandshakeStream, @@ -205,7 +205,7 @@ var _ = Describe("Crypto Setup TLS", func() { _, sInitialStream, sHandshakeStream := initStreams() runner := NewMockHandshakeRunner(mockCtrl) runner.EXPECT().OnError(gomock.Any()).Do(func(e error) { sErrChan <- e }) - var token [16]byte + var token protocol.StatelessResetToken server := NewCryptoSetupServer( sInitialStream, sHandshakeStream, @@ -241,7 +241,7 @@ var _ = Describe("Crypto Setup TLS", func() { It("returns Handshake() when it is closed", func() { _, sInitialStream, sHandshakeStream := initStreams() - var token [16]byte + var token protocol.StatelessResetToken server := NewCryptoSetupServer( sInitialStream, sHandshakeStream, @@ -363,7 +363,7 @@ var _ = Describe("Crypto Setup TLS", func() { sRunner.EXPECT().OnError(gomock.Any()).Do(func(e error) { sErrChan <- e }).MaxTimes(1) sRunner.EXPECT().OnHandshakeComplete().Do(func() { sHandshakeComplete = true }).MaxTimes(1) if serverTransportParameters.StatelessResetToken == nil { - var token [16]byte + var token protocol.StatelessResetToken serverTransportParameters.StatelessResetToken = &token } server := NewCryptoSetupServer( @@ -493,7 +493,7 @@ var _ = Describe("Crypto Setup TLS", func() { ) sChunkChan, sInitialStream, sHandshakeStream := initStreams() - var token [16]byte + var token protocol.StatelessResetToken sRunner := NewMockHandshakeRunner(mockCtrl) sRunner.EXPECT().OnReceivedParams(gomock.Any()).Do(func(tp *wire.TransportParameters) { cTransportParametersRcvd = tp }) sRunner.EXPECT().OnHandshakeComplete() @@ -553,7 +553,7 @@ var _ = Describe("Crypto Setup TLS", func() { sRunner := NewMockHandshakeRunner(mockCtrl) sRunner.EXPECT().OnReceivedParams(gomock.Any()) sRunner.EXPECT().OnHandshakeComplete() - var token [16]byte + var token protocol.StatelessResetToken server := NewCryptoSetupServer( sInitialStream, sHandshakeStream, @@ -613,7 +613,7 @@ var _ = Describe("Crypto Setup TLS", func() { sRunner := NewMockHandshakeRunner(mockCtrl) sRunner.EXPECT().OnReceivedParams(gomock.Any()) sRunner.EXPECT().OnHandshakeComplete() - var token [16]byte + var token protocol.StatelessResetToken server := NewCryptoSetupServer( sInitialStream, sHandshakeStream, diff --git a/internal/protocol/protocol.go b/internal/protocol/protocol.go index c23b87da6..aac729563 100644 --- a/internal/protocol/protocol.go +++ b/internal/protocol/protocol.go @@ -43,6 +43,9 @@ const MaxByteCount = ByteCount(1<<62 - 1) // An ApplicationErrorCode is an application-defined error code. type ApplicationErrorCode uint64 +// A StatelessResetToken is a stateless reset token. +type StatelessResetToken [16]byte + // MaxReceivePacketSize maximum packet size of any QUIC packet, based on // ethernet's max size, minus the IP and UDP headers. IPv6 has a 40 byte header, // UDP adds an additional 8 bytes. This is a total overhead of 48 bytes. diff --git a/internal/utils/new_connection_id.go b/internal/utils/new_connection_id.go index 54ab0149e..694ee7aaf 100644 --- a/internal/utils/new_connection_id.go +++ b/internal/utils/new_connection_id.go @@ -8,5 +8,5 @@ import ( type NewConnectionID struct { SequenceNumber uint64 ConnectionID protocol.ConnectionID - StatelessResetToken [16]byte + StatelessResetToken protocol.StatelessResetToken } diff --git a/internal/wire/frame_parser_test.go b/internal/wire/frame_parser_test.go index 1bc4b291d..bfbbfd7ad 100644 --- a/internal/wire/frame_parser_test.go +++ b/internal/wire/frame_parser_test.go @@ -218,7 +218,7 @@ var _ = Describe("Frame parsing", func() { f := &NewConnectionIDFrame{ SequenceNumber: 0x1337, ConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}, - StatelessResetToken: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, + StatelessResetToken: protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15}, } buf := &bytes.Buffer{} Expect(f.Write(buf, versionIETFFrames)).To(Succeed()) diff --git a/internal/wire/log_test.go b/internal/wire/log_test.go index e6e7ce5ec..b0925888e 100644 --- a/internal/wire/log_test.go +++ b/internal/wire/log_test.go @@ -143,7 +143,7 @@ var _ = Describe("Frame logging", func() { LogFrame(logger, &NewConnectionIDFrame{ SequenceNumber: 42, ConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}, - StatelessResetToken: [16]byte{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10}, + StatelessResetToken: protocol.StatelessResetToken{0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf, 0x10}, }, false) Expect(buf.String()).To(ContainSubstring("\t<- &wire.NewConnectionIDFrame{SequenceNumber: 42, ConnectionID: 0xdeadbeef, StatelessResetToken: 0x0102030405060708090a0b0c0d0e0f10}")) }) diff --git a/internal/wire/new_connection_id_frame.go b/internal/wire/new_connection_id_frame.go index 78735b271..8beb79cd2 100644 --- a/internal/wire/new_connection_id_frame.go +++ b/internal/wire/new_connection_id_frame.go @@ -15,7 +15,7 @@ type NewConnectionIDFrame struct { SequenceNumber uint64 RetirePriorTo uint64 ConnectionID protocol.ConnectionID - StatelessResetToken [16]byte + StatelessResetToken protocol.StatelessResetToken } func parseNewConnectionIDFrame(r *bytes.Reader, _ protocol.VersionNumber) (*NewConnectionIDFrame, error) { diff --git a/internal/wire/new_connection_id_frame_test.go b/internal/wire/new_connection_id_frame_test.go index c4cc08079..cacadc697 100644 --- a/internal/wire/new_connection_id_frame_test.go +++ b/internal/wire/new_connection_id_frame_test.go @@ -70,7 +70,7 @@ var _ = Describe("NEW_CONNECTION_ID frame", func() { Context("when writing", func() { It("writes a sample frame", func() { - token := [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} + token := protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} frame := &NewConnectionIDFrame{ SequenceNumber: 0x1337, RetirePriorTo: 0x42, @@ -89,7 +89,7 @@ var _ = Describe("NEW_CONNECTION_ID frame", func() { }) It("has the correct length", func() { - token := [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} + token := protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15} frame := &NewConnectionIDFrame{ SequenceNumber: 0xdecafbad, RetirePriorTo: 0xdeadbeefcafe, diff --git a/internal/wire/transport_parameter_test.go b/internal/wire/transport_parameter_test.go index 652a34283..6a8f44ee1 100644 --- a/internal/wire/transport_parameter_test.go +++ b/internal/wire/transport_parameter_test.go @@ -24,8 +24,6 @@ var _ = Describe("Transport Parameters", func() { rand.Seed(GinkgoRandomSeed()) }) - var token [16]byte - addInitialSourceConnectionID := func(b *bytes.Buffer) { utils.WriteVarInt(b, uint64(initialSourceConnectionIDParameterID)) utils.WriteVarInt(b, 6) @@ -46,7 +44,7 @@ var _ = Describe("Transport Parameters", func() { RetrySourceConnectionID: &protocol.ConnectionID{0xde, 0xad, 0xc0, 0xde}, AckDelayExponent: 14, MaxAckDelay: 37 * time.Millisecond, - StatelessResetToken: &[16]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00}, + StatelessResetToken: &protocol.StatelessResetToken{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00}, ActiveConnectionIDLimit: 123, } Expect(p.String()).To(Equal("&wire.TransportParameters{OriginalDestinationConnectionID: 0xdeadbeef, InitialSourceConnectionID: 0xdecafbad, RetrySourceConnectionID: 0xdeadc0de, InitialMaxStreamDataBidiLocal: 1234, InitialMaxStreamDataBidiRemote: 2345, InitialMaxStreamDataUni: 3456, InitialMaxData: 4567, MaxBidiStreamNum: 1337, MaxUniStreamNum: 7331, MaxIdleTimeout: 42s, AckDelayExponent: 14, MaxAckDelay: 37ms, ActiveConnectionIDLimit: 123, StatelessResetToken: 0x112233445566778899aabbccddeeff00}")) @@ -71,7 +69,7 @@ var _ = Describe("Transport Parameters", func() { }) It("marshals and unmarshals", func() { - var token [16]byte + var token protocol.StatelessResetToken rand.Read(token[:]) params := &TransportParameters{ InitialMaxStreamDataBidiLocal: protocol.ByteCount(getRandomValue()), @@ -113,7 +111,7 @@ var _ = Describe("Transport Parameters", func() { It("doesn't marshal a retry_source_connection_id, if no Retry was performed", func() { data := (&TransportParameters{ - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) p := &TransportParameters{} Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(Succeed()) @@ -123,7 +121,7 @@ var _ = Describe("Transport Parameters", func() { It("marshals a zero-length retry_source_connection_id", func() { data := (&TransportParameters{ RetrySourceConnectionID: &protocol.ConnectionID{}, - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) p := &TransportParameters{} Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(Succeed()) @@ -159,7 +157,7 @@ var _ = Describe("Transport Parameters", func() { b := &bytes.Buffer{} utils.WriteVarInt(b, uint64(statelessResetTokenParameterID)) utils.WriteVarInt(b, 16) - b.Write(token[:]) + b.Write(make([]byte, 16)) addInitialSourceConnectionID(b) Expect((&TransportParameters{}).Unmarshal(b.Bytes(), protocol.PerspectiveServer)).To(MatchError("TRANSPORT_PARAMETER_ERROR: missing original_destination_connection_id")) }) @@ -171,7 +169,7 @@ var _ = Describe("Transport Parameters", func() { It("errors when the max_ack_delay is too large", func() { data := (&TransportParameters{ MaxAckDelay: 1 << 14 * time.Millisecond, - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) p := &TransportParameters{} Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(MatchError("TRANSPORT_PARAMETER_ERROR: invalid value for max_ack_delay: 16384ms (maximum 16383ms)")) @@ -185,12 +183,12 @@ var _ = Describe("Transport Parameters", func() { for i := 0; i < num; i++ { dataDefault := (&TransportParameters{ MaxAckDelay: protocol.DefaultMaxAckDelay, - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) defaultLen += len(dataDefault) data := (&TransportParameters{ MaxAckDelay: maxAckDelay, - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) dataLen += len(data) } @@ -201,7 +199,7 @@ var _ = Describe("Transport Parameters", func() { It("errors when the ack_delay_exponenent is too large", func() { data := (&TransportParameters{ AckDelayExponent: 21, - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) p := &TransportParameters{} Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(MatchError("TRANSPORT_PARAMETER_ERROR: invalid value for ack_delay_exponent: 21 (maximum 20)")) @@ -214,12 +212,12 @@ var _ = Describe("Transport Parameters", func() { for i := 0; i < num; i++ { dataDefault := (&TransportParameters{ AckDelayExponent: protocol.DefaultAckDelayExponent, - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) defaultLen += len(dataDefault) data := (&TransportParameters{ AckDelayExponent: protocol.DefaultAckDelayExponent + 1, - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) dataLen += len(data) } @@ -230,7 +228,7 @@ var _ = Describe("Transport Parameters", func() { It("sets the default value for the ack_delay_exponent, when no value was sent", func() { data := (&TransportParameters{ AckDelayExponent: protocol.DefaultAckDelayExponent, - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) p := &TransportParameters{} Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(Succeed()) @@ -316,7 +314,7 @@ var _ = Describe("Transport Parameters", func() { b := &bytes.Buffer{} utils.WriteVarInt(b, uint64(statelessResetTokenParameterID)) utils.WriteVarInt(b, uint64(utils.VarIntLen(16))) - b.Write(token[:]) + b.Write(make([]byte, 16)) Expect((&TransportParameters{}).Unmarshal(b.Bytes(), protocol.PerspectiveClient)).To(MatchError("TRANSPORT_PARAMETER_ERROR: client sent a stateless_reset_token")) }) @@ -338,14 +336,14 @@ var _ = Describe("Transport Parameters", func() { IPv6: net.IP{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, IPv6Port: 13, ConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}, - StatelessResetToken: [16]byte{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, + StatelessResetToken: protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, } }) It("marshals and unmarshals", func() { data := (&TransportParameters{ PreferredAddress: pa, - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) p := &TransportParameters{} Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(Succeed()) @@ -370,7 +368,7 @@ var _ = Describe("Transport Parameters", func() { pa.ConnectionID = protocol.ConnectionID{} data := (&TransportParameters{ PreferredAddress: pa, - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) p := &TransportParameters{} Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(MatchError("TRANSPORT_PARAMETER_ERROR: invalid connection ID length: 0")) @@ -381,7 +379,7 @@ var _ = Describe("Transport Parameters", func() { Expect(pa.ConnectionID.Len()).To(BeNumerically(">", protocol.MaxConnIDLen)) data := (&TransportParameters{ PreferredAddress: pa, - StatelessResetToken: &token, + StatelessResetToken: &protocol.StatelessResetToken{}, }).Marshal(protocol.PerspectiveServer) p := &TransportParameters{} Expect(p.Unmarshal(data, protocol.PerspectiveServer)).To(MatchError("TRANSPORT_PARAMETER_ERROR: invalid connection ID length: 21")) diff --git a/internal/wire/transport_parameters.go b/internal/wire/transport_parameters.go index 1cf7977bc..9eae574e3 100644 --- a/internal/wire/transport_parameters.go +++ b/internal/wire/transport_parameters.go @@ -51,7 +51,7 @@ type PreferredAddress struct { IPv6 net.IP IPv6Port uint16 ConnectionID protocol.ConnectionID - StatelessResetToken [16]byte + StatelessResetToken protocol.StatelessResetToken } // TransportParameters are parameters sent to the peer during the handshake @@ -79,7 +79,7 @@ type TransportParameters struct { InitialSourceConnectionID protocol.ConnectionID RetrySourceConnectionID *protocol.ConnectionID // use a pointer here to distinguish zero-length connection IDs from missing transport parameters - StatelessResetToken *[16]byte + StatelessResetToken *protocol.StatelessResetToken ActiveConnectionIDLimit uint64 } @@ -160,7 +160,7 @@ func (p *TransportParameters) unmarshal(r *bytes.Reader, sentBy protocol.Perspec if paramLen != 16 { return fmt.Errorf("wrong length for stateless_reset_token: %d (expected 16)", paramLen) } - var token [16]byte + var token protocol.StatelessResetToken r.Read(token[:]) p.StatelessResetToken = &token case originalDestinationConnectionIDParameterID: diff --git a/logging/close_reason.go b/logging/close_reason.go index 6c0e32be9..e35e47425 100644 --- a/logging/close_reason.go +++ b/logging/close_reason.go @@ -12,7 +12,7 @@ type CloseReason struct { transportError *TransportError timeout *TimeoutReason - statelessResetToken *[16]byte + statelessResetToken *StatelessResetToken } // NewApplicationCloseReason creates a new CloseReason for an application error. @@ -31,8 +31,8 @@ func NewTimeoutCloseReason(r TimeoutReason) CloseReason { } // NewStatelessResetCloseReason creates a new CloseReason for a stateless reset. -func NewStatelessResetCloseReason(token *[16]byte) CloseReason { - return CloseReason{statelessResetToken: token} +func NewStatelessResetCloseReason(token StatelessResetToken) CloseReason { + return CloseReason{statelessResetToken: &token} } // ApplicationError gets the application error. @@ -60,7 +60,7 @@ func (r *CloseReason) Timeout() (reason TimeoutReason, ok bool) { } // StatelessReset gets the stateless reset token. -func (r *CloseReason) StatelessReset() (token [16]byte, ok bool) { +func (r *CloseReason) StatelessReset() (token StatelessResetToken, ok bool) { if r.statelessResetToken == nil { return } diff --git a/logging/close_reason_test.go b/logging/close_reason_test.go index 60b1a84ee..80cef958f 100644 --- a/logging/close_reason_test.go +++ b/logging/close_reason_test.go @@ -59,10 +59,10 @@ var _ = Describe("Close Reason", func() { }) It("stateless resets", func() { - r := NewStatelessResetCloseReason(&[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}) + r := NewStatelessResetCloseReason(StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}) token, ok := r.StatelessReset() Expect(ok).To(BeTrue()) - Expect(token).To(Equal([16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})) + Expect(token).To(Equal(StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16})) checkNotApplicationError(r) checkNotTransportError(r) checkNotTimeout(r) diff --git a/logging/interface.go b/logging/interface.go index fb3ee9750..4f22ece03 100644 --- a/logging/interface.go +++ b/logging/interface.go @@ -25,6 +25,8 @@ type ( PacketNumber = protocol.PacketNumber // The Perspective is the role of a QUIC endpoint (client or server). Perspective = protocol.Perspective + // A StatelessResetToken is a stateless reset token. + StatelessResetToken = protocol.StatelessResetToken // The StreamID is the stream ID. StreamID = protocol.StreamID // The StreamNum is the number of the stream. diff --git a/mock_packet_handler_manager_test.go b/mock_packet_handler_manager_test.go index 775156358..57244b0ff 100644 --- a/mock_packet_handler_manager_test.go +++ b/mock_packet_handler_manager_test.go @@ -49,7 +49,7 @@ func (mr *MockPacketHandlerManagerMockRecorder) Add(arg0, arg1 interface{}) *gom } // AddResetToken mocks base method -func (m *MockPacketHandlerManager) AddResetToken(arg0 [16]byte, arg1 packetHandler) { +func (m *MockPacketHandlerManager) AddResetToken(arg0 protocol.StatelessResetToken, arg1 packetHandler) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddResetToken", arg0, arg1) } @@ -101,10 +101,10 @@ func (mr *MockPacketHandlerManagerMockRecorder) Destroy() *gomock.Call { } // GetStatelessResetToken mocks base method -func (m *MockPacketHandlerManager) GetStatelessResetToken(arg0 protocol.ConnectionID) [16]byte { +func (m *MockPacketHandlerManager) GetStatelessResetToken(arg0 protocol.ConnectionID) protocol.StatelessResetToken { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStatelessResetToken", arg0) - ret0, _ := ret[0].([16]byte) + ret0, _ := ret[0].(protocol.StatelessResetToken) return ret0 } @@ -127,7 +127,7 @@ func (mr *MockPacketHandlerManagerMockRecorder) Remove(arg0 interface{}) *gomock } // RemoveResetToken mocks base method -func (m *MockPacketHandlerManager) RemoveResetToken(arg0 [16]byte) { +func (m *MockPacketHandlerManager) RemoveResetToken(arg0 protocol.StatelessResetToken) { m.ctrl.T.Helper() m.ctrl.Call(m, "RemoveResetToken", arg0) } @@ -163,7 +163,7 @@ func (mr *MockPacketHandlerManagerMockRecorder) Retire(arg0 interface{}) *gomock } // RetireResetToken mocks base method -func (m *MockPacketHandlerManager) RetireResetToken(arg0 [16]byte) { +func (m *MockPacketHandlerManager) RetireResetToken(arg0 protocol.StatelessResetToken) { m.ctrl.T.Helper() m.ctrl.Call(m, "RetireResetToken", arg0) } diff --git a/mock_session_runner_test.go b/mock_session_runner_test.go index 704272c65..ead35109d 100644 --- a/mock_session_runner_test.go +++ b/mock_session_runner_test.go @@ -49,7 +49,7 @@ func (mr *MockSessionRunnerMockRecorder) Add(arg0, arg1 interface{}) *gomock.Cal } // AddResetToken mocks base method -func (m *MockSessionRunner) AddResetToken(arg0 [16]byte, arg1 packetHandler) { +func (m *MockSessionRunner) AddResetToken(arg0 protocol.StatelessResetToken, arg1 packetHandler) { m.ctrl.T.Helper() m.ctrl.Call(m, "AddResetToken", arg0, arg1) } @@ -61,10 +61,10 @@ func (mr *MockSessionRunnerMockRecorder) AddResetToken(arg0, arg1 interface{}) * } // GetStatelessResetToken mocks base method -func (m *MockSessionRunner) GetStatelessResetToken(arg0 protocol.ConnectionID) [16]byte { +func (m *MockSessionRunner) GetStatelessResetToken(arg0 protocol.ConnectionID) protocol.StatelessResetToken { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "GetStatelessResetToken", arg0) - ret0, _ := ret[0].([16]byte) + ret0, _ := ret[0].(protocol.StatelessResetToken) return ret0 } @@ -87,7 +87,7 @@ func (mr *MockSessionRunnerMockRecorder) Remove(arg0 interface{}) *gomock.Call { } // RemoveResetToken mocks base method -func (m *MockSessionRunner) RemoveResetToken(arg0 [16]byte) { +func (m *MockSessionRunner) RemoveResetToken(arg0 protocol.StatelessResetToken) { m.ctrl.T.Helper() m.ctrl.Call(m, "RemoveResetToken", arg0) } @@ -123,7 +123,7 @@ func (mr *MockSessionRunnerMockRecorder) Retire(arg0 interface{}) *gomock.Call { } // RetireResetToken mocks base method -func (m *MockSessionRunner) RetireResetToken(arg0 [16]byte) { +func (m *MockSessionRunner) RetireResetToken(arg0 protocol.StatelessResetToken) { m.ctrl.T.Helper() m.ctrl.Call(m, "RetireResetToken", arg0) } diff --git a/packet_handler_map.go b/packet_handler_map.go index 041ed4f34..bd9b6f7cd 100644 --- a/packet_handler_map.go +++ b/packet_handler_map.go @@ -16,7 +16,7 @@ import ( ) type statelessResetErr struct { - token [16]byte + token protocol.StatelessResetToken } func (e statelessResetErr) Error() string { @@ -34,7 +34,7 @@ type packetHandlerMap struct { connIDLen int handlers map[string] /* string(ConnectionID)*/ packetHandler - resetTokens map[[16]byte] /* stateless reset token */ packetHandler + resetTokens map[protocol.StatelessResetToken] /* stateless reset token */ packetHandler server unknownPacketHandler listening chan struct{} // is closed when listen returns @@ -62,7 +62,7 @@ func newPacketHandlerMap( connIDLen: connIDLen, listening: make(chan struct{}), handlers: make(map[string]packetHandler), - resetTokens: make(map[[16]byte]packetHandler), + resetTokens: make(map[protocol.StatelessResetToken]packetHandler), deleteRetiredSessionsAfter: protocol.RetiredConnectionIDDeleteTimeout, statelessResetEnabled: len(statelessResetKey) > 0, statelessResetHasher: hmac.New(sha256.New, statelessResetKey), @@ -167,19 +167,19 @@ func (h *packetHandlerMap) ReplaceWithClosed(id protocol.ConnectionID, handler p }) } -func (h *packetHandlerMap) AddResetToken(token [16]byte, handler packetHandler) { +func (h *packetHandlerMap) AddResetToken(token protocol.StatelessResetToken, handler packetHandler) { h.mutex.Lock() h.resetTokens[token] = handler h.mutex.Unlock() } -func (h *packetHandlerMap) RemoveResetToken(token [16]byte) { +func (h *packetHandlerMap) RemoveResetToken(token protocol.StatelessResetToken) { h.mutex.Lock() delete(h.resetTokens, token) h.mutex.Unlock() } -func (h *packetHandlerMap) RetireResetToken(token [16]byte) { +func (h *packetHandlerMap) RetireResetToken(token protocol.StatelessResetToken) { time.AfterFunc(h.deleteRetiredSessionsAfter, func() { h.mutex.Lock() delete(h.resetTokens, token) @@ -313,7 +313,7 @@ func (h *packetHandlerMap) maybeHandleStatelessReset(data []byte) bool { return false } - var token [16]byte + var token protocol.StatelessResetToken copy(token[:], data[len(data)-16:]) if sess, ok := h.resetTokens[token]; ok { h.logger.Debugf("Received a stateless reset with token %#x. Closing session.", token) @@ -323,8 +323,8 @@ func (h *packetHandlerMap) maybeHandleStatelessReset(data []byte) bool { return false } -func (h *packetHandlerMap) GetStatelessResetToken(connID protocol.ConnectionID) [16]byte { - var token [16]byte +func (h *packetHandlerMap) GetStatelessResetToken(connID protocol.ConnectionID) protocol.StatelessResetToken { + var token protocol.StatelessResetToken if !h.statelessResetEnabled { // Return a random stateless reset token. // This token will be sent in the server's transport parameters. diff --git a/packet_handler_map_test.go b/packet_handler_map_test.go index 0f51d1d0d..08f6c86c2 100644 --- a/packet_handler_map_test.go +++ b/packet_handler_map_test.go @@ -236,7 +236,7 @@ var _ = Describe("Packet Handler Map", func() { Context("handling", func() { It("handles stateless resets", func() { packetHandler := NewMockPacketHandler(mockCtrl) - token := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + token := protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} handler.AddResetToken(token, packetHandler) packet := append([]byte{0x40} /* short header packet */, make([]byte, 50)...) packet = append(packet, token[:]...) @@ -257,7 +257,7 @@ var _ = Describe("Packet Handler Map", func() { It("handles stateless resets for 0-length connection IDs", func() { handler.connIDLen = 0 packetHandler := NewMockPacketHandler(mockCtrl) - token := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + token := protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} handler.AddResetToken(token, packetHandler) packet := append([]byte{0x40} /* short header packet */, make([]byte, 50)...) packet = append(packet, token[:]...) @@ -280,7 +280,7 @@ var _ = Describe("Packet Handler Map", func() { connID := protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef, 0x42} packetHandler := NewMockPacketHandler(mockCtrl) handler.Add(connID, packetHandler) - token := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + token := protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} handler.AddResetToken(token, NewMockPacketHandler(mockCtrl)) handler.RetireResetToken(token) packetHandler.EXPECT().handlePacket(gomock.Any()) @@ -295,7 +295,7 @@ var _ = Describe("Packet Handler Map", func() { It("ignores packets too small to contain a stateless reset", func() { handler.connIDLen = 0 packetHandler := NewMockPacketHandler(mockCtrl) - token := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + token := protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} handler.AddResetToken(token, packetHandler) packet := append([]byte{0x40} /* short header packet */, token[:15]...) done := make(chan struct{}) diff --git a/qlog/event.go b/qlog/event.go index 77d59994b..8c1935dd6 100644 --- a/qlog/event.go +++ b/qlog/event.go @@ -179,7 +179,7 @@ func (e eventVersionNegotiationReceived) MarshalJSONObject(enc *gojay.Encoder) { } type eventStatelessResetReceived struct { - Token [16]byte + Token protocol.StatelessResetToken } func (e eventStatelessResetReceived) Category() category { return categoryTransport } @@ -332,7 +332,7 @@ type eventTransportParameters struct { InitialSourceConnectionID protocol.ConnectionID RetrySourceConnectionID *protocol.ConnectionID - StatelessResetToken *[16]byte + StatelessResetToken *protocol.StatelessResetToken DisableActiveMigration bool MaxIdleTimeout time.Duration MaxUDPPayloadSize protocol.ByteCount diff --git a/qlog/frame_test.go b/qlog/frame_test.go index 2bd9a9ed6..159ad4705 100644 --- a/qlog/frame_test.go +++ b/qlog/frame_test.go @@ -257,7 +257,7 @@ var _ = Describe("Frames", func() { SequenceNumber: 42, RetirePriorTo: 24, ConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}, - StatelessResetToken: [16]byte{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}, + StatelessResetToken: protocol.StatelessResetToken{0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 0xa, 0xb, 0xc, 0xd, 0xe, 0xf}, }, map[string]interface{}{ "frame_type": "new_connection_id", diff --git a/qlog/qlog_test.go b/qlog/qlog_test.go index 554f8cd6c..a3f367317 100644 --- a/qlog/qlog_test.go +++ b/qlog/qlog_test.go @@ -183,7 +183,7 @@ var _ = Describe("Tracing", func() { }) It("records a received stateless reset packet", func() { - tracer.ClosedConnection(logging.NewStatelessResetCloseReason(&[16]byte{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff})) + tracer.ClosedConnection(logging.NewStatelessResetCloseReason(logging.StatelessResetToken{0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff})) entry := exportAndParseSingle() Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) Expect(entry.Category).To(Equal("transport")) @@ -206,7 +206,7 @@ var _ = Describe("Tracing", func() { DisableActiveMigration: true, MaxUDPPayloadSize: 1234, MaxIdleTimeout: 321 * time.Millisecond, - StatelessResetToken: &[16]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00}, + StatelessResetToken: &protocol.StatelessResetToken{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00}, OriginalDestinationConnectionID: protocol.ConnectionID{0xde, 0xad, 0xc0, 0xde}, InitialSourceConnectionID: protocol.ConnectionID{0xde, 0xad, 0xbe, 0xef}, RetrySourceConnectionID: &protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad}, @@ -249,7 +249,7 @@ var _ = Describe("Tracing", func() { It("records transport parameters without retry_source_connection_id", func() { tracer.SentTransportParameters(&logging.TransportParameters{ - StatelessResetToken: &[16]byte{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00}, + StatelessResetToken: &protocol.StatelessResetToken{0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77, 0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff, 0x00}, }) entry := exportAndParseSingle() Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) diff --git a/server.go b/server.go index 83e356874..75781aac7 100644 --- a/server.go +++ b/server.go @@ -81,7 +81,7 @@ type baseServer struct { protocol.ConnectionID, /* client dest connection ID */ protocol.ConnectionID, /* destination connection ID */ protocol.ConnectionID, /* source connection ID */ - [16]byte, + protocol.StatelessResetToken, *Config, *tls.Config, *handshake.TokenGenerator, diff --git a/server_test.go b/server_test.go index 569d14971..c7a695a7a 100644 --- a/server_test.go +++ b/server_test.go @@ -308,13 +308,13 @@ var _ = Describe("Server", func() { } p := getPacket(hdr, make([]byte, protocol.MinInitialPacketSize)) run := make(chan struct{}) - var token [16]byte + var token protocol.StatelessResetToken rand.Read(token[:]) var newConnID protocol.ConnectionID phm.EXPECT().AddWithConnID(protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, gomock.Any(), gomock.Any()).DoAndReturn(func(_, c protocol.ConnectionID, fn func() packetHandler) bool { newConnID = c - phm.EXPECT().GetStatelessResetToken(gomock.Any()).DoAndReturn(func(c protocol.ConnectionID) [16]byte { + phm.EXPECT().GetStatelessResetToken(gomock.Any()).DoAndReturn(func(c protocol.ConnectionID) protocol.StatelessResetToken { newConnID = c return token }) @@ -330,7 +330,7 @@ var _ = Describe("Server", func() { clientDestConnID protocol.ConnectionID, destConnID protocol.ConnectionID, srcConnID protocol.ConnectionID, - tokenP [16]byte, + tokenP protocol.StatelessResetToken, _ *Config, _ *tls.Config, _ *handshake.TokenGenerator, @@ -481,13 +481,13 @@ var _ = Describe("Server", func() { } p := getPacket(hdr, make([]byte, protocol.MinInitialPacketSize)) run := make(chan struct{}) - var token [16]byte + var token protocol.StatelessResetToken rand.Read(token[:]) var newConnID protocol.ConnectionID phm.EXPECT().AddWithConnID(protocol.ConnectionID{1, 2, 3, 4, 5, 6, 7, 8, 9, 10}, gomock.Any(), gomock.Any()).DoAndReturn(func(_, c protocol.ConnectionID, fn func() packetHandler) bool { newConnID = c - phm.EXPECT().GetStatelessResetToken(gomock.Any()).DoAndReturn(func(c protocol.ConnectionID) [16]byte { + phm.EXPECT().GetStatelessResetToken(gomock.Any()).DoAndReturn(func(c protocol.ConnectionID) protocol.StatelessResetToken { newConnID = c return token }) @@ -504,7 +504,7 @@ var _ = Describe("Server", func() { clientDestConnID protocol.ConnectionID, destConnID protocol.ConnectionID, srcConnID protocol.ConnectionID, - tokenP [16]byte, + tokenP protocol.StatelessResetToken, _ *Config, _ *tls.Config, _ *handshake.TokenGenerator, @@ -571,7 +571,7 @@ var _ = Describe("Server", func() { _ protocol.ConnectionID, _ protocol.ConnectionID, _ protocol.ConnectionID, - _ [16]byte, + _ protocol.StatelessResetToken, _ *Config, _ *tls.Config, _ *handshake.TokenGenerator, @@ -614,7 +614,7 @@ var _ = Describe("Server", func() { _ protocol.ConnectionID, _ protocol.ConnectionID, _ protocol.ConnectionID, - _ [16]byte, + _ protocol.StatelessResetToken, _ *Config, _ *tls.Config, _ *handshake.TokenGenerator, @@ -665,7 +665,7 @@ var _ = Describe("Server", func() { _ protocol.ConnectionID, _ protocol.ConnectionID, _ protocol.ConnectionID, - _ [16]byte, + _ protocol.StatelessResetToken, _ *Config, _ *tls.Config, _ *handshake.TokenGenerator, @@ -695,7 +695,7 @@ var _ = Describe("Server", func() { _ protocol.ConnectionID, _ protocol.ConnectionID, _ protocol.ConnectionID, - _ [16]byte, + _ protocol.StatelessResetToken, _ *Config, _ *tls.Config, _ *handshake.TokenGenerator, @@ -760,7 +760,7 @@ var _ = Describe("Server", func() { _ protocol.ConnectionID, _ protocol.ConnectionID, _ protocol.ConnectionID, - _ [16]byte, + _ protocol.StatelessResetToken, _ *Config, _ *tls.Config, _ *handshake.TokenGenerator, @@ -868,7 +868,7 @@ var _ = Describe("Server", func() { _ protocol.ConnectionID, _ protocol.ConnectionID, _ protocol.ConnectionID, - _ [16]byte, + _ protocol.StatelessResetToken, _ *Config, _ *tls.Config, _ *handshake.TokenGenerator, @@ -935,7 +935,7 @@ var _ = Describe("Server", func() { _ protocol.ConnectionID, _ protocol.ConnectionID, _ protocol.ConnectionID, - _ [16]byte, + _ protocol.StatelessResetToken, _ *Config, _ *tls.Config, _ *handshake.TokenGenerator, @@ -973,7 +973,7 @@ var _ = Describe("Server", func() { _ protocol.ConnectionID, _ protocol.ConnectionID, _ protocol.ConnectionID, - _ [16]byte, + _ protocol.StatelessResetToken, _ *Config, _ *tls.Config, _ *handshake.TokenGenerator, @@ -1032,7 +1032,7 @@ var _ = Describe("Server", func() { _ protocol.ConnectionID, _ protocol.ConnectionID, _ protocol.ConnectionID, - _ [16]byte, + _ protocol.StatelessResetToken, _ *Config, _ *tls.Config, _ *handshake.TokenGenerator, diff --git a/session.go b/session.go index d37da7f8d..d3aeff7a5 100644 --- a/session.go +++ b/session.go @@ -78,13 +78,13 @@ func (p *receivedPacket) Clone() *receivedPacket { type sessionRunner interface { Add(protocol.ConnectionID, packetHandler) bool - GetStatelessResetToken(protocol.ConnectionID) [16]byte + GetStatelessResetToken(protocol.ConnectionID) protocol.StatelessResetToken Retire(protocol.ConnectionID) Remove(protocol.ConnectionID) ReplaceWithClosed(protocol.ConnectionID, packetHandler) - AddResetToken([16]byte, packetHandler) - RemoveResetToken([16]byte) - RetireResetToken([16]byte) + AddResetToken(protocol.StatelessResetToken, packetHandler) + RemoveResetToken(protocol.StatelessResetToken) + RetireResetToken(protocol.StatelessResetToken) } type handshakeRunner struct { @@ -221,7 +221,7 @@ var newSession = func( clientDestConnID protocol.ConnectionID, destConnID protocol.ConnectionID, srcConnID protocol.ConnectionID, - statelessResetToken [16]byte, + statelessResetToken protocol.StatelessResetToken, conf *Config, tlsConf *tls.Config, tokenGenerator *handshake.TokenGenerator, @@ -250,7 +250,7 @@ var newSession = func( } s.connIDManager = newConnIDManager( destConnID, - func(token [16]byte) { runner.AddResetToken(token, s) }, + func(token protocol.StatelessResetToken) { runner.AddResetToken(token, s) }, runner.RemoveResetToken, runner.RetireResetToken, s.queueControlFrame, @@ -372,7 +372,7 @@ var newClientSession = func( } s.connIDManager = newConnIDManager( destConnID, - func(token [16]byte) { runner.AddResetToken(token, s) }, + func(token protocol.StatelessResetToken) { runner.AddResetToken(token, s) }, runner.RemoveResetToken, runner.RetireResetToken, s.queueControlFrame, @@ -1301,7 +1301,7 @@ func (s *session) handleCloseError(closeErr closeError) { if nerr, ok := closeErr.err.(net.Error); !ok || !nerr.Timeout() { var resetErr statelessResetErr if errors.As(closeErr.err, &resetErr) { - s.tracer.ClosedConnection(logging.NewStatelessResetCloseReason(&resetErr.token)) + s.tracer.ClosedConnection(logging.NewStatelessResetCloseReason(resetErr.token)) } else if quicErr.IsApplicationError() { s.tracer.ClosedConnection(logging.NewApplicationCloseReason(quicErr.ErrorCode, closeErr.remote)) } else { diff --git a/session_test.go b/session_test.go index d9f4dc79c..b0150d153 100644 --- a/session_test.go +++ b/session_test.go @@ -99,7 +99,7 @@ var _ = Describe("Session", func() { clientDestConnID, destConnID, srcConnID, - [16]byte{}, + protocol.StatelessResetToken{}, populateServerConfig(&Config{}), nil, // tls.Config tokenGenerator, @@ -641,7 +641,7 @@ var _ = Describe("Session", func() { }) It("closes due to a stateless reset", func() { - token := [16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} + token := protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16} runSession() gomock.InOrder( tracer.EXPECT().ClosedConnection(gomock.Any()).Do(func(reason logging.CloseReason) { @@ -2452,7 +2452,7 @@ var _ = Describe("Client Session", func() { IPv4: net.IPv4(127, 0, 0, 1), IPv6: net.IP{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, ConnectionID: protocol.ConnectionID{1, 2, 3, 4}, - StatelessResetToken: [16]byte{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, + StatelessResetToken: protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, }, } packer.EXPECT().HandleTransportParameters(gomock.Any()) @@ -2462,10 +2462,10 @@ var _ = Describe("Client Session", func() { // make sure the connection ID is not retired cf, _ := sess.framer.AppendControlFrames(nil, protocol.MaxByteCount) Expect(cf).To(BeEmpty()) - sessionRunner.EXPECT().AddResetToken([16]byte{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, sess) + sessionRunner.EXPECT().AddResetToken(protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}, sess) Expect(sess.connIDManager.Get()).To(Equal(protocol.ConnectionID{1, 2, 3, 4})) // shut down - sessionRunner.EXPECT().RemoveResetToken([16]byte{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}) + sessionRunner.EXPECT().RemoveResetToken(protocol.StatelessResetToken{16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1}) expectClose() }) @@ -2487,7 +2487,7 @@ var _ = Describe("Client Session", func() { params := &wire.TransportParameters{ OriginalDestinationConnectionID: destConnID, InitialSourceConnectionID: protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad}, - StatelessResetToken: &[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + StatelessResetToken: &protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, } expectClose() tracer.EXPECT().ReceivedTransportParameters(params) @@ -2500,7 +2500,7 @@ var _ = Describe("Client Session", func() { params := &wire.TransportParameters{ OriginalDestinationConnectionID: destConnID, InitialSourceConnectionID: destConnID, - StatelessResetToken: &[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + StatelessResetToken: &protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, } expectClose() tracer.EXPECT().ReceivedTransportParameters(params) @@ -2514,7 +2514,7 @@ var _ = Describe("Client Session", func() { OriginalDestinationConnectionID: destConnID, InitialSourceConnectionID: destConnID, RetrySourceConnectionID: &protocol.ConnectionID{0xde, 0xad, 0xc0, 0xde}, - StatelessResetToken: &[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + StatelessResetToken: &protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, } expectClose() tracer.EXPECT().ReceivedTransportParameters(params) @@ -2527,7 +2527,7 @@ var _ = Describe("Client Session", func() { OriginalDestinationConnectionID: destConnID, InitialSourceConnectionID: destConnID, RetrySourceConnectionID: &protocol.ConnectionID{0xde, 0xad, 0xc0, 0xde}, - StatelessResetToken: &[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + StatelessResetToken: &protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, } expectClose() tracer.EXPECT().ReceivedTransportParameters(params) @@ -2540,7 +2540,7 @@ var _ = Describe("Client Session", func() { params := &wire.TransportParameters{ OriginalDestinationConnectionID: protocol.ConnectionID{0xde, 0xca, 0xfb, 0xad}, InitialSourceConnectionID: sess.handshakeDestConnID, - StatelessResetToken: &[16]byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, + StatelessResetToken: &protocol.StatelessResetToken{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}, } expectClose() tracer.EXPECT().ReceivedTransportParameters(params)