diff --git a/client.go b/client.go index 1ceb071a..773e1821 100644 --- a/client.go +++ b/client.go @@ -11,6 +11,7 @@ import ( "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/utils" + "github.com/lucas-clemente/quic-go/logging" "github.com/lucas-clemente/quic-go/qlog" ) @@ -40,7 +41,7 @@ type client struct { session quicSession - qlogger qlog.Tracer + qlogger logging.Tracer logger utils.Logger } diff --git a/client_test.go b/client_test.go index 6742ba06..a84d1a1e 100644 --- a/client_test.go +++ b/client_test.go @@ -12,7 +12,7 @@ import ( "os" "time" - "github.com/lucas-clemente/quic-go/qlog" + "github.com/lucas-clemente/quic-go/logging" "github.com/golang/mock/gomock" "github.com/lucas-clemente/quic-go/internal/mocks" @@ -48,11 +48,11 @@ var _ = Describe("Client", func() { initialVersion protocol.VersionNumber, enable0RTT bool, hasNegotiatedVersion bool, - qlogger qlog.Tracer, + qlogger logging.Tracer, logger utils.Logger, v protocol.VersionNumber, ) quicSession - originalQlogConstructor func(io.WriteCloser, protocol.Perspective, protocol.ConnectionID) qlog.Tracer + originalQlogConstructor func(io.WriteCloser, protocol.Perspective, protocol.ConnectionID) logging.Tracer ) // generate a packet sent by the server that accepts the QUIC version suggested by the client @@ -72,7 +72,7 @@ var _ = Describe("Client", func() { originalClientSessConstructor = newClientSession originalQlogConstructor = newQlogger qlogger = mocks.NewMockTracer(mockCtrl) - newQlogger = func(io.WriteCloser, protocol.Perspective, protocol.ConnectionID) qlog.Tracer { + newQlogger = func(io.WriteCloser, protocol.Perspective, protocol.ConnectionID) logging.Tracer { return qlogger } config = &Config{ @@ -161,7 +161,7 @@ var _ = Describe("Client", func() { _ protocol.VersionNumber, _ bool, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -194,7 +194,7 @@ var _ = Describe("Client", func() { _ protocol.VersionNumber, _ bool, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -227,7 +227,7 @@ var _ = Describe("Client", func() { _ protocol.VersionNumber, _ bool, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -266,7 +266,7 @@ var _ = Describe("Client", func() { _ protocol.VersionNumber, enable0RTT bool, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -309,7 +309,7 @@ var _ = Describe("Client", func() { _ protocol.VersionNumber, enable0RTT bool, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -357,7 +357,7 @@ var _ = Describe("Client", func() { _ protocol.VersionNumber, _ bool, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -401,7 +401,7 @@ var _ = Describe("Client", func() { _ protocol.VersionNumber, _ bool, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -453,7 +453,7 @@ var _ = Describe("Client", func() { _ protocol.VersionNumber, _ bool, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -574,7 +574,7 @@ var _ = Describe("Client", func() { _ protocol.VersionNumber, /* initial version */ _ bool, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, versionP protocol.VersionNumber, ) quicSession { @@ -616,7 +616,7 @@ var _ = Describe("Client", func() { version protocol.VersionNumber, _ bool, hasNegotiatedVersion bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, versionP protocol.VersionNumber, ) quicSession { diff --git a/internal/ackhandler/ackhandler.go b/internal/ackhandler/ackhandler.go index 8a58e5db..4c3dde74 100644 --- a/internal/ackhandler/ackhandler.go +++ b/internal/ackhandler/ackhandler.go @@ -4,16 +4,17 @@ import ( "github.com/lucas-clemente/quic-go/internal/congestion" "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/utils" - "github.com/lucas-clemente/quic-go/qlog" + "github.com/lucas-clemente/quic-go/logging" "github.com/lucas-clemente/quic-go/quictrace" ) +// NewAckHandler creates a new SentPacketHandler and a new ReceivedPacketHandler func NewAckHandler( initialPacketNumber protocol.PacketNumber, rttStats *congestion.RTTStats, pers protocol.Perspective, traceCallback func(quictrace.Event), - qlogger qlog.Tracer, + qlogger logging.Tracer, logger utils.Logger, version protocol.VersionNumber, ) (SentPacketHandler, ReceivedPacketHandler) { diff --git a/internal/ackhandler/sent_packet_handler.go b/internal/ackhandler/sent_packet_handler.go index acf7e0ba..0739f3ee 100644 --- a/internal/ackhandler/sent_packet_handler.go +++ b/internal/ackhandler/sent_packet_handler.go @@ -10,7 +10,7 @@ import ( "github.com/lucas-clemente/quic-go/internal/qerr" "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/internal/wire" - "github.com/lucas-clemente/quic-go/qlog" + "github.com/lucas-clemente/quic-go/logging" "github.com/lucas-clemente/quic-go/quictrace" ) @@ -84,7 +84,7 @@ type sentPacketHandler struct { perspective protocol.Perspective traceCallback func(quictrace.Event) - qlogger qlog.Tracer + qlogger logging.Tracer logger utils.Logger } @@ -96,7 +96,7 @@ func newSentPacketHandler( rttStats *congestion.RTTStats, pers protocol.Perspective, traceCallback func(quictrace.Event), - qlogger qlog.Tracer, + qlogger logging.Tracer, logger utils.Logger, ) *sentPacketHandler { congestion := congestion.NewCubicSender( @@ -477,7 +477,7 @@ func (h *sentPacketHandler) setLossDetectionTimer() { // Early retransmit timer or time loss detection. h.alarm = lossTime if h.qlogger != nil && h.alarm != oldAlarm { - h.qlogger.SetLossTimer(qlog.TimerTypeACK, encLevel, h.alarm) + h.qlogger.SetLossTimer(logging.TimerTypeACK, encLevel, h.alarm) } return } @@ -496,7 +496,7 @@ func (h *sentPacketHandler) setLossDetectionTimer() { ptoTime, encLevel := h.getPTOTimeAndSpace() h.alarm = ptoTime if h.qlogger != nil && h.alarm != oldAlarm { - h.qlogger.SetLossTimer(qlog.TimerTypePTO, encLevel, h.alarm) + h.qlogger.SetLossTimer(logging.TimerTypePTO, encLevel, h.alarm) } } @@ -522,12 +522,12 @@ func (h *sentPacketHandler) detectAndRemoveLostPackets(now time.Time, encLevel p if packet.SendTime.Before(lostSendTime) { lostPackets = append(lostPackets, packet) if h.qlogger != nil { - h.qlogger.LostPacket(packet.EncryptionLevel, packet.PacketNumber, qlog.PacketLossTimeThreshold) + h.qlogger.LostPacket(packet.EncryptionLevel, packet.PacketNumber, logging.PacketLossTimeThreshold) } } else if pnSpace.largestAcked >= packet.PacketNumber+packetThreshold { lostPackets = append(lostPackets, packet) if h.qlogger != nil { - h.qlogger.LostPacket(packet.EncryptionLevel, packet.PacketNumber, qlog.PacketLossReorderingThreshold) + h.qlogger.LostPacket(packet.EncryptionLevel, packet.PacketNumber, logging.PacketLossReorderingThreshold) } } else if pnSpace.lossTime.IsZero() { // Note: This conditional is only entered once per call @@ -599,7 +599,7 @@ func (h *sentPacketHandler) onVerifiedLossDetectionTimeout() error { h.logger.Debugf("Loss detection alarm fired in loss timer mode. Loss time: %s", earliestLossTime) } if h.qlogger != nil { - h.qlogger.LossTimerExpired(qlog.TimerTypeACK, encLevel) + h.qlogger.LossTimerExpired(logging.TimerTypeACK, encLevel) } // Early retransmit or time loss detection priorInFlight := h.bytesInFlight @@ -621,7 +621,7 @@ func (h *sentPacketHandler) onVerifiedLossDetectionTimeout() error { h.logger.Debugf("Loss detection alarm for %s fired in PTO mode. PTO count: %d", encLevel, h.ptoCount) } if h.qlogger != nil { - h.qlogger.LossTimerExpired(qlog.TimerTypePTO, encLevel) + h.qlogger.LossTimerExpired(logging.TimerTypePTO, encLevel) h.qlogger.UpdatedPTOCount(h.ptoCount) } h.numProbesToSend += 2 diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index bb7fb784..600636ca 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -15,7 +15,7 @@ import ( "github.com/lucas-clemente/quic-go/internal/qerr" "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/internal/wire" - "github.com/lucas-clemente/quic-go/qlog" + "github.com/lucas-clemente/quic-go/logging" "github.com/marten-seemann/qtls" ) @@ -94,7 +94,7 @@ type cryptoSetup struct { rttStats *congestion.RTTStats - qlogger qlog.Tracer + qlogger logging.Tracer logger utils.Logger perspective protocol.Perspective @@ -137,7 +137,7 @@ func NewCryptoSetupClient( tlsConf *tls.Config, enable0RTT bool, rttStats *congestion.RTTStats, - qlogger qlog.Tracer, + qlogger logging.Tracer, logger utils.Logger, ) (CryptoSetup, <-chan *wire.TransportParameters /* ClientHello written. Receive nil for non-0-RTT */) { cs, clientHelloWritten := newCryptoSetup( @@ -169,7 +169,7 @@ func NewCryptoSetupServer( tlsConf *tls.Config, enable0RTT bool, rttStats *congestion.RTTStats, - qlogger qlog.Tracer, + qlogger logging.Tracer, logger utils.Logger, ) CryptoSetup { cs, _ := newCryptoSetup( @@ -198,7 +198,7 @@ func newCryptoSetup( tlsConf *tls.Config, enable0RTT bool, rttStats *congestion.RTTStats, - qlogger qlog.Tracer, + qlogger logging.Tracer, logger utils.Logger, perspective protocol.Perspective, ) (*cryptoSetup, <-chan *wire.TransportParameters /* ClientHello written. Receive nil for non-0-RTT */) { diff --git a/internal/handshake/updatable_aead.go b/internal/handshake/updatable_aead.go index feaffe7e..4fba8ec8 100644 --- a/internal/handshake/updatable_aead.go +++ b/internal/handshake/updatable_aead.go @@ -12,7 +12,7 @@ import ( "github.com/lucas-clemente/quic-go/internal/congestion" "github.com/lucas-clemente/quic-go/internal/qerr" "github.com/lucas-clemente/quic-go/internal/utils" - "github.com/lucas-clemente/quic-go/qlog" + "github.com/lucas-clemente/quic-go/logging" "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/marten-seemann/qtls" @@ -74,7 +74,7 @@ type updatableAEAD struct { rttStats *congestion.RTTStats - qlogger qlog.Tracer + qlogger logging.Tracer logger utils.Logger // use a single slice to avoid allocations @@ -84,7 +84,7 @@ type updatableAEAD struct { var _ ShortHeaderOpener = &updatableAEAD{} var _ ShortHeaderSealer = &updatableAEAD{} -func newUpdatableAEAD(rttStats *congestion.RTTStats, qlogger qlog.Tracer, logger utils.Logger) *updatableAEAD { +func newUpdatableAEAD(rttStats *congestion.RTTStats, qlogger logging.Tracer, logger utils.Logger) *updatableAEAD { return &updatableAEAD{ firstPacketNumber: protocol.InvalidPacketNumber, largestAcked: protocol.InvalidPacketNumber, diff --git a/internal/mocks/qlog.go b/internal/mocks/logging.go similarity index 94% rename from internal/mocks/qlog.go rename to internal/mocks/logging.go index a12feadf..d5df1267 100644 --- a/internal/mocks/qlog.go +++ b/internal/mocks/logging.go @@ -1,5 +1,5 @@ // Code generated by MockGen. DO NOT EDIT. -// Source: github.com/lucas-clemente/quic-go/qlog (interfaces: Tracer) +// Source: github.com/lucas-clemente/quic-go/logging (interfaces: Tracer) // Package mocks is a generated GoMock package. package mocks @@ -13,7 +13,7 @@ import ( congestion "github.com/lucas-clemente/quic-go/internal/congestion" protocol "github.com/lucas-clemente/quic-go/internal/protocol" wire "github.com/lucas-clemente/quic-go/internal/wire" - qlog "github.com/lucas-clemente/quic-go/qlog" + logging "github.com/lucas-clemente/quic-go/logging" ) // MockTracer is a mock of Tracer interface @@ -40,7 +40,7 @@ func (m *MockTracer) EXPECT() *MockTracerMockRecorder { } // BufferedPacket mocks base method -func (m *MockTracer) BufferedPacket(arg0 qlog.PacketType) { +func (m *MockTracer) BufferedPacket(arg0 logging.PacketType) { m.ctrl.T.Helper() m.ctrl.Call(m, "BufferedPacket", arg0) } @@ -52,7 +52,7 @@ func (mr *MockTracerMockRecorder) BufferedPacket(arg0 interface{}) *gomock.Call } // ClosedConnection mocks base method -func (m *MockTracer) ClosedConnection(arg0 qlog.CloseReason) { +func (m *MockTracer) ClosedConnection(arg0 logging.CloseReason) { m.ctrl.T.Helper() m.ctrl.Call(m, "ClosedConnection", arg0) } @@ -76,7 +76,7 @@ func (mr *MockTracerMockRecorder) DroppedEncryptionLevel(arg0 interface{}) *gomo } // DroppedPacket mocks base method -func (m *MockTracer) DroppedPacket(arg0 qlog.PacketType, arg1 protocol.ByteCount, arg2 qlog.PacketDropReason) { +func (m *MockTracer) DroppedPacket(arg0 logging.PacketType, arg1 protocol.ByteCount, arg2 logging.PacketDropReason) { m.ctrl.T.Helper() m.ctrl.Call(m, "DroppedPacket", arg0, arg1, arg2) } @@ -114,7 +114,7 @@ func (mr *MockTracerMockRecorder) LossTimerCanceled() *gomock.Call { } // LossTimerExpired mocks base method -func (m *MockTracer) LossTimerExpired(arg0 qlog.TimerType, arg1 protocol.EncryptionLevel) { +func (m *MockTracer) LossTimerExpired(arg0 logging.TimerType, arg1 protocol.EncryptionLevel) { m.ctrl.T.Helper() m.ctrl.Call(m, "LossTimerExpired", arg0, arg1) } @@ -126,7 +126,7 @@ func (mr *MockTracerMockRecorder) LossTimerExpired(arg0, arg1 interface{}) *gomo } // LostPacket mocks base method -func (m *MockTracer) LostPacket(arg0 protocol.EncryptionLevel, arg1 protocol.PacketNumber, arg2 qlog.PacketLossReason) { +func (m *MockTracer) LostPacket(arg0 protocol.EncryptionLevel, arg1 protocol.PacketNumber, arg2 logging.PacketLossReason) { m.ctrl.T.Helper() m.ctrl.Call(m, "LostPacket", arg0, arg1, arg2) } @@ -222,7 +222,7 @@ func (mr *MockTracerMockRecorder) SentTransportParameters(arg0 interface{}) *gom } // SetLossTimer mocks base method -func (m *MockTracer) SetLossTimer(arg0 qlog.TimerType, arg1 protocol.EncryptionLevel, arg2 time.Time) { +func (m *MockTracer) SetLossTimer(arg0 logging.TimerType, arg1 protocol.EncryptionLevel, arg2 time.Time) { m.ctrl.T.Helper() m.ctrl.Call(m, "SetLossTimer", arg0, arg1, arg2) } diff --git a/internal/mocks/mockgen.go b/internal/mocks/mockgen.go index a1cbbc26..dc7524d1 100644 --- a/internal/mocks/mockgen.go +++ b/internal/mocks/mockgen.go @@ -3,7 +3,7 @@ package mocks //go:generate sh -c "mockgen -package mockquic -destination quic/stream.go github.com/lucas-clemente/quic-go Stream && goimports -w quic/stream.go" //go:generate sh -c "mockgen -package mockquic -destination quic/early_session.go github.com/lucas-clemente/quic-go EarlySession && goimports -w quic/early_session.go" //go:generate sh -c "mockgen -package mockquic -destination quic/early_listener.go github.com/lucas-clemente/quic-go EarlyListener && goimports -w quic/early_listener.go" -//go:generate sh -c "mockgen -package mocks -destination qlog.go github.com/lucas-clemente/quic-go/qlog Tracer && goimports -w qlog.go" +//go:generate sh -c "mockgen -package mocks -destination logging.go github.com/lucas-clemente/quic-go/logging Tracer && goimports -w logging.go" //go:generate sh -c "mockgen -package mocks -destination short_header_sealer.go github.com/lucas-clemente/quic-go/internal/handshake ShortHeaderSealer && goimports -w short_header_sealer.go" //go:generate sh -c "mockgen -package mocks -destination short_header_opener.go github.com/lucas-clemente/quic-go/internal/handshake ShortHeaderOpener && goimports -w short_header_opener.go" //go:generate sh -c "mockgen -package mocks -destination long_header_opener.go github.com/lucas-clemente/quic-go/internal/handshake LongHeaderOpener && goimports -w long_header_opener.go" diff --git a/logging/interface.go b/logging/interface.go new file mode 100644 index 00000000..7a1aa0a1 --- /dev/null +++ b/logging/interface.go @@ -0,0 +1,37 @@ +// Package logging defines a logging interface for quic-go. +// This package should not be considered stable +package logging + +import ( + "net" + "time" + + "github.com/lucas-clemente/quic-go/internal/congestion" + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +// A Tracer records events. +type Tracer interface { + Export() error + StartedConnection(local, remote net.Addr, version protocol.VersionNumber, srcConnID, destConnID protocol.ConnectionID) + ClosedConnection(CloseReason) + SentTransportParameters(*wire.TransportParameters) + ReceivedTransportParameters(*wire.TransportParameters) + SentPacket(hdr *wire.ExtendedHeader, packetSize protocol.ByteCount, ack *wire.AckFrame, frames []wire.Frame) + ReceivedVersionNegotiationPacket(*wire.Header) + ReceivedRetry(*wire.Header) + ReceivedPacket(hdr *wire.ExtendedHeader, packetSize protocol.ByteCount, frames []wire.Frame) + ReceivedStatelessReset(token *[16]byte) + BufferedPacket(PacketType) + DroppedPacket(PacketType, protocol.ByteCount, PacketDropReason) + UpdatedMetrics(rttStats *congestion.RTTStats, cwnd protocol.ByteCount, bytesInFLight protocol.ByteCount, packetsInFlight int) + LostPacket(protocol.EncryptionLevel, protocol.PacketNumber, PacketLossReason) + UpdatedPTOCount(value uint32) + UpdatedKeyFromTLS(protocol.EncryptionLevel, protocol.Perspective) + UpdatedKey(generation protocol.KeyPhase, remote bool) + DroppedEncryptionLevel(protocol.EncryptionLevel) + SetLossTimer(TimerType, protocol.EncryptionLevel, time.Time) + LossTimerExpired(TimerType, protocol.EncryptionLevel) + LossTimerCanceled() +} diff --git a/logging/logging_sutie_test.go b/logging/logging_sutie_test.go new file mode 100644 index 00000000..f4c51257 --- /dev/null +++ b/logging/logging_sutie_test.go @@ -0,0 +1,13 @@ +package logging + +import ( + "testing" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +func TestLoggingt(t *testing.T) { + RegisterFailHandler(Fail) + RunSpecs(t, "Logging Suite") +} diff --git a/logging/packet_header.go b/logging/packet_header.go new file mode 100644 index 00000000..abd72b06 --- /dev/null +++ b/logging/packet_header.go @@ -0,0 +1,43 @@ +package logging + +import ( + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" +) + +// PacketTypeFromHeader determines the packet type from a *wire.Header. +func PacketTypeFromHeader(hdr *wire.Header) PacketType { + if !hdr.IsLongHeader { + return PacketType1RTT + } + if hdr.Version == 0 { + return PacketTypeVersionNegotiation + } + switch hdr.Type { + case protocol.PacketTypeInitial: + return PacketTypeInitial + case protocol.PacketTypeHandshake: + return PacketTypeHandshake + case protocol.PacketType0RTT: + return PacketType0RTT + case protocol.PacketTypeRetry: + return PacketTypeRetry + default: + return PacketTypeNotDetermined + } +} + +// PacketHeader is a QUIC packet header. +type PacketHeader struct { + PacketType PacketType + + PacketNumber protocol.PacketNumber + PayloadLength protocol.ByteCount + // Size of the QUIC packet (QUIC header + payload). + // See https://github.com/quiclog/internet-drafts/issues/40. + PacketSize protocol.ByteCount + + Version protocol.VersionNumber + SrcConnectionID protocol.ConnectionID + DestConnectionID protocol.ConnectionID +} diff --git a/logging/packet_header_test.go b/logging/packet_header_test.go new file mode 100644 index 00000000..c33acb7c --- /dev/null +++ b/logging/packet_header_test.go @@ -0,0 +1,60 @@ +package logging + +import ( + "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/internal/wire" + + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Packet Header", func() { + Context("determining the packet type from the header", func() { + It("recognizes Initial packets", func() { + Expect(PacketTypeFromHeader(&wire.Header{ + IsLongHeader: true, + Type: protocol.PacketTypeInitial, + Version: protocol.VersionTLS, + })).To(Equal(PacketTypeInitial)) + }) + + It("recognizes Handshake packets", func() { + Expect(PacketTypeFromHeader(&wire.Header{ + IsLongHeader: true, + Type: protocol.PacketTypeHandshake, + Version: protocol.VersionTLS, + })).To(Equal(PacketTypeHandshake)) + }) + + It("recognizes Retry packets", func() { + Expect(PacketTypeFromHeader(&wire.Header{ + IsLongHeader: true, + Type: protocol.PacketTypeRetry, + Version: protocol.VersionTLS, + })).To(Equal(PacketTypeRetry)) + }) + + It("recognizes 0-RTT packets", func() { + Expect(PacketTypeFromHeader(&wire.Header{ + IsLongHeader: true, + Type: protocol.PacketType0RTT, + Version: protocol.VersionTLS, + })).To(Equal(PacketType0RTT)) + }) + + It("recognizes Version Negotiation packets", func() { + Expect(PacketTypeFromHeader(&wire.Header{IsLongHeader: true})).To(Equal(PacketTypeVersionNegotiation)) + }) + + It("recognizes 1-RTT packets", func() { + Expect(PacketTypeFromHeader(&wire.Header{})).To(Equal(PacketType1RTT)) + }) + + It("handles unrecognized packet types", func() { + Expect(PacketTypeFromHeader(&wire.Header{ + IsLongHeader: true, + Version: protocol.VersionTLS, + })).To(Equal(PacketTypeNotDetermined)) + }) + }) +}) diff --git a/logging/types.go b/logging/types.go new file mode 100644 index 00000000..0132cad4 --- /dev/null +++ b/logging/types.go @@ -0,0 +1,170 @@ +package logging + +import ( + "github.com/lucas-clemente/quic-go/internal/protocol" +) + +// PacketType is the packet type of a QUIC packet +type PacketType protocol.PacketType + +const ( + // PacketTypeInitial is the packet type of an Initial packet + PacketTypeInitial PacketType = iota + // PacketTypeHandshake is the packet type of a Handshake packet + PacketTypeHandshake + // PacketTypeRetry is the packet type of a Retry packet + PacketTypeRetry + // PacketType0RTT is the packet type of a 0-RTT packet + PacketType0RTT + // PacketTypeVersionNegotiation is the packet type of a Version Negotiation packet + PacketTypeVersionNegotiation + // PacketType1RTT is a 1-RTT packet + PacketType1RTT + // PacketTypeStatelessReset is a stateless reset + PacketTypeStatelessReset + // PacketTypeNotDetermined is the packet type when it could not be determined + PacketTypeNotDetermined +) + +func (t PacketType) String() string { + switch t { + case PacketTypeInitial: + return "initial" + case PacketTypeHandshake: + return "handshake" + case PacketTypeRetry: + return "retry" + case PacketType0RTT: + return "0RTT" + case PacketTypeVersionNegotiation: + return "version_negotiation" + case PacketTypeStatelessReset: + return "stateless_reset" + case PacketType1RTT: + return "1RTT" + case PacketTypeNotDetermined: + return "" + default: + panic("unknown packet type") + } +} + +type PacketLossReason uint8 + +const ( + // PacketLossReorderingThreshold: when a packet is deemed lost due to reordering threshold + PacketLossReorderingThreshold PacketLossReason = iota + // PacketLossTimeThreshold: when a packet is deemed lost due to time threshold + PacketLossTimeThreshold +) + +func (r PacketLossReason) String() string { + switch r { + case PacketLossReorderingThreshold: + return "reordering_threshold" + case PacketLossTimeThreshold: + return "time_threshold" + default: + panic("unknown loss reason") + } +} + +type PacketDropReason uint8 + +const ( + // PacketDropKeyUnavailable is used when a packet is dropped because keys are unavailable + PacketDropKeyUnavailable PacketDropReason = iota + // PacketDropUnknownConnectionID is used when a packet is dropped because the connection ID is unknown + PacketDropUnknownConnectionID + // PacketDropHeaderParseError is used when a packet is dropped because header parsing failed + PacketDropHeaderParseError + // PacketDropPayloadDecryptError is used when a packet is dropped because decrypting the payload failed + PacketDropPayloadDecryptError + // PacketDropProtocolViolation is used when a packet is dropped due to a protocol violation + PacketDropProtocolViolation + // PacketDropDOSPrevention is used when a packet is dropped to mitigate a DoS attack + PacketDropDOSPrevention + // PacketDropUnsupportedVersion is used when a packet is dropped because the version is not supported + PacketDropUnsupportedVersion + // PacketDropUnexpectedPacket is used when an unexpected packet is received + PacketDropUnexpectedPacket + // PacketDropUnexpectedSourceConnectionID is used when a packet with an unexpected source connection ID is received + PacketDropUnexpectedSourceConnectionID + // PacketDropUnexpectedVersion is used when a packet with an unexpected version is received + PacketDropUnexpectedVersion + // PacketDropDuplicate is used when a duplicate packet is received + PacketDropDuplicate +) + +func (r PacketDropReason) String() string { + switch r { + case PacketDropKeyUnavailable: + return "key_unavailable" + case PacketDropUnknownConnectionID: + return "unknown_connection_id" + case PacketDropHeaderParseError: + return "header_parse_error" + case PacketDropPayloadDecryptError: + return "payload_decrypt_error" + case PacketDropProtocolViolation: + return "protocol_violation" + case PacketDropDOSPrevention: + return "dos_prevention" + case PacketDropUnsupportedVersion: + return "unsupported_version" + case PacketDropUnexpectedPacket: + return "unexpected_packet" + case PacketDropUnexpectedSourceConnectionID: + return "unexpected_source_connection_id" + case PacketDropUnexpectedVersion: + return "unexpected_version" + case PacketDropDuplicate: + return "duplicate" + default: + panic("unknown packet drop reason") + } +} + +// TimerType is the type of the loss detection timer +type TimerType uint8 + +const ( + // TimerTypeACK is the timer type for the early retransmit timer + TimerTypeACK TimerType = iota + // TimerTypePTO is the timer type for the PTO retransmit timer + TimerTypePTO +) + +func (t TimerType) String() string { + switch t { + case TimerTypeACK: + return "ack" + case TimerTypePTO: + return "pto" + default: + panic("unknown timer type") + } +} + +// CloseReason is the reason why a session is closed +type CloseReason uint8 + +const ( + // CloseReasonHandshakeTimeout is used when the session is closed due to a handshake timeout + // This reason is not defined in the qlog draft, but very useful for debugging. + CloseReasonHandshakeTimeout CloseReason = iota + // CloseReasonIdleTimeout is used when the session is closed due to an idle timeout + // This reason is not defined in the qlog draft, but very useful for debugging. + CloseReasonIdleTimeout +) + +func (r CloseReason) String() string { + switch r { + case CloseReasonHandshakeTimeout: + return "handshake_timeout" + case CloseReasonIdleTimeout: + return "idle_timeout" + default: + panic("unknown close reason") + } +} diff --git a/logging/types_test.go b/logging/types_test.go new file mode 100644 index 00000000..ebb8a62d --- /dev/null +++ b/logging/types_test.go @@ -0,0 +1,42 @@ +package logging + +import ( + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" +) + +var _ = Describe("Types", func() { + It("has a string representation for the packet type", func() { + Expect(PacketTypeInitial.String()).To(Equal("initial")) + Expect(PacketTypeHandshake.String()).To(Equal("handshake")) + Expect(PacketType0RTT.String()).To(Equal("0RTT")) + Expect(PacketType1RTT.String()).To(Equal("1RTT")) + Expect(PacketTypeStatelessReset.String()).To(Equal("stateless_reset")) + Expect(PacketTypeRetry.String()).To(Equal("retry")) + Expect(PacketTypeVersionNegotiation.String()).To(Equal("version_negotiation")) + Expect(PacketTypeNotDetermined.String()).To(BeEmpty()) + }) + + It("has a string representation for the packet drop reason", func() { + Expect(PacketDropKeyUnavailable.String()).To(Equal("key_unavailable")) + Expect(PacketDropUnknownConnectionID.String()).To(Equal("unknown_connection_id")) + Expect(PacketDropHeaderParseError.String()).To(Equal("header_parse_error")) + Expect(PacketDropPayloadDecryptError.String()).To(Equal("payload_decrypt_error")) + Expect(PacketDropProtocolViolation.String()).To(Equal("protocol_violation")) + Expect(PacketDropDOSPrevention.String()).To(Equal("dos_prevention")) + Expect(PacketDropUnsupportedVersion.String()).To(Equal("unsupported_version")) + Expect(PacketDropUnexpectedPacket.String()).To(Equal("unexpected_packet")) + Expect(PacketDropUnexpectedSourceConnectionID.String()).To(Equal("unexpected_source_connection_id")) + Expect(PacketDropUnexpectedVersion.String()).To(Equal("unexpected_version")) + }) + + It("has a string representation for the timer type", func() { + Expect(TimerTypeACK.String()).To(Equal("ack")) + Expect(TimerTypePTO.String()).To(Equal("pto")) + }) + + It("has a string representation for the close reason", func() { + Expect(CloseReasonHandshakeTimeout.String()).To(Equal("handshake_timeout")) + Expect(CloseReasonIdleTimeout.String()).To(Equal("idle_timeout")) + }) +}) diff --git a/qlog/event.go b/qlog/event.go index 09fa8a74..e3264fd7 100644 --- a/qlog/event.go +++ b/qlog/event.go @@ -6,6 +6,7 @@ import ( "time" "github.com/lucas-clemente/quic-go/internal/protocol" + "github.com/lucas-clemente/quic-go/logging" "github.com/francoispqt/gojay" ) @@ -93,7 +94,7 @@ func (e eventConnectionStarted) MarshalJSONObject(enc *gojay.Encoder) { } type eventConnectionClosed struct { - Reason CloseReason + Reason logging.CloseReason } func (e eventConnectionClosed) Category() category { return categoryTransport } @@ -106,7 +107,7 @@ func (e eventConnectionClosed) MarshalJSONObject(enc *gojay.Encoder) { } type eventPacketSent struct { - PacketType PacketType + PacketType logging.PacketType Header packetHeader Frames frames IsCoalesced bool @@ -128,7 +129,7 @@ func (e eventPacketSent) MarshalJSONObject(enc *gojay.Encoder) { } type eventPacketReceived struct { - PacketType PacketType + PacketType logging.PacketType Header packetHeader Frames frames IsCoalesced bool @@ -158,7 +159,7 @@ func (e eventRetryReceived) Name() string { return "packet_received" } func (e eventRetryReceived) IsNil() bool { return false } func (e eventRetryReceived) MarshalJSONObject(enc *gojay.Encoder) { - enc.StringKey("packet_type", PacketTypeRetry.String()) + enc.StringKey("packet_type", logging.PacketTypeRetry.String()) enc.ObjectKey("header", e.Header) } @@ -172,7 +173,7 @@ func (e eventVersionNegotiationReceived) Name() string { return "packet_re func (e eventVersionNegotiationReceived) IsNil() bool { return false } func (e eventVersionNegotiationReceived) MarshalJSONObject(enc *gojay.Encoder) { - enc.StringKey("packet_type", PacketTypeVersionNegotiation.String()) + enc.StringKey("packet_type", logging.PacketTypeVersionNegotiation.String()) enc.ObjectKey("header", e.Header) enc.ArrayKey("supported_versions", versions(e.SupportedVersions)) } @@ -186,12 +187,12 @@ func (e eventStatelessResetReceived) Name() string { return "packet_receiv func (e eventStatelessResetReceived) IsNil() bool { return false } func (e eventStatelessResetReceived) MarshalJSONObject(enc *gojay.Encoder) { - enc.StringKey("packet_type", PacketTypeStatelessReset.String()) + enc.StringKey("packet_type", logging.PacketTypeStatelessReset.String()) enc.StringKey("stateless_reset_token", fmt.Sprintf("%x", *e.Token)) } type eventPacketBuffered struct { - PacketType PacketType + PacketType logging.PacketType } func (e eventPacketBuffered) Category() category { return categoryTransport } @@ -204,9 +205,9 @@ func (e eventPacketBuffered) MarshalJSONObject(enc *gojay.Encoder) { } type eventPacketDropped struct { - PacketType PacketType + PacketType logging.PacketType PacketSize protocol.ByteCount - Trigger PacketDropReason + Trigger logging.PacketDropReason } func (e eventPacketDropped) Category() category { return categoryTransport } @@ -277,9 +278,9 @@ func (e eventUpdatedPTO) MarshalJSONObject(enc *gojay.Encoder) { } type eventPacketLost struct { - PacketType PacketType + PacketType logging.PacketType PacketNumber protocol.PacketNumber - Trigger PacketLossReason + Trigger logging.PacketLossReason } func (e eventPacketLost) Category() category { return categoryRecovery } @@ -381,7 +382,7 @@ func (e eventTransportParameters) MarshalJSONObject(enc *gojay.Encoder) { } type eventLossTimerSet struct { - TimerType TimerType + TimerType logging.TimerType EncLevel protocol.EncryptionLevel Delta time.Duration } @@ -398,7 +399,7 @@ func (e eventLossTimerSet) MarshalJSONObject(enc *gojay.Encoder) { } type eventLossTimerExpired struct { - TimerType TimerType + TimerType logging.TimerType EncLevel protocol.EncryptionLevel } diff --git a/qlog/packet_header.go b/qlog/packet_header.go index dc343629..df9d2a12 100644 --- a/qlog/packet_header.go +++ b/qlog/packet_header.go @@ -2,43 +2,21 @@ package qlog import ( "github.com/francoispqt/gojay" - "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/wire" + "github.com/lucas-clemente/quic-go/logging" ) -// PacketTypeFromHeader determines the packet type from a *wire.Header. -func PacketTypeFromHeader(hdr *wire.Header) PacketType { - if !hdr.IsLongHeader { - return PacketType1RTT - } - if hdr.Version == 0 { - return PacketTypeVersionNegotiation - } - switch hdr.Type { - case protocol.PacketTypeInitial: - return PacketTypeInitial - case protocol.PacketTypeHandshake: - return PacketTypeHandshake - case protocol.PacketType0RTT: - return PacketType0RTT - case protocol.PacketTypeRetry: - return PacketTypeRetry - default: - return PacketTypeNotDetermined - } -} - -func getPacketTypeFromEncryptionLevel(encLevel protocol.EncryptionLevel) PacketType { +func getPacketTypeFromEncryptionLevel(encLevel protocol.EncryptionLevel) logging.PacketType { switch encLevel { case protocol.EncryptionInitial: - return PacketTypeInitial + return logging.PacketTypeInitial case protocol.EncryptionHandshake: - return PacketTypeHandshake + return logging.PacketTypeHandshake case protocol.Encryption0RTT: - return PacketType0RTT + return logging.PacketType0RTT case protocol.Encryption1RTT: - return PacketType1RTT + return logging.PacketType1RTT default: panic("unknown encryption level") } @@ -46,7 +24,7 @@ func getPacketTypeFromEncryptionLevel(encLevel protocol.EncryptionLevel) PacketT func transformHeader(hdr *wire.Header) *packetHeader { return &packetHeader{ - PacketType: PacketTypeFromHeader(hdr), + PacketType: logging.PacketTypeFromHeader(hdr), PayloadLength: hdr.Length, SrcConnectionID: hdr.SrcConnectionID, DestConnectionID: hdr.DestConnectionID, @@ -60,23 +38,11 @@ func transformExtendedHeader(hdr *wire.ExtendedHeader) *packetHeader { return h } -type packetHeader struct { - // We don't log the packet type as a part of the header yet, see https://github.com/quiclog/internet-drafts/issues/40. - PacketType PacketType - - PacketNumber protocol.PacketNumber - PayloadLength protocol.ByteCount - // Size of the QUIC packet (QUIC header + payload). - // See https://github.com/quiclog/internet-drafts/issues/40. - PacketSize protocol.ByteCount - - Version protocol.VersionNumber - SrcConnectionID protocol.ConnectionID - DestConnectionID protocol.ConnectionID -} +// We don't log the packet type as a part of the header yet, see https://github.com/quiclog/internet-drafts/issues/40. +type packetHeader logging.PacketHeader func (h packetHeader) MarshalJSONObject(enc *gojay.Encoder) { - if h.PacketType != PacketTypeRetry && h.PacketType != PacketTypeVersionNegotiation { + if h.PacketType != logging.PacketTypeRetry && h.PacketType != logging.PacketTypeVersionNegotiation { enc.Int64Key("packet_number", int64(h.PacketNumber)) } enc.Int64KeyOmitEmpty("payload_length", int64(h.PayloadLength)) @@ -84,7 +50,7 @@ func (h packetHeader) MarshalJSONObject(enc *gojay.Encoder) { if h.Version != 0 { enc.StringKey("version", versionNumber(h.Version).String()) } - if h.PacketType != PacketType1RTT { + if h.PacketType != logging.PacketType1RTT { enc.IntKey("scil", h.SrcConnectionID.Len()) if h.SrcConnectionID.Len() > 0 { enc.StringKey("scid", connectionID(h.SrcConnectionID).String()) @@ -95,5 +61,3 @@ func (h packetHeader) MarshalJSONObject(enc *gojay.Encoder) { enc.StringKey("dcid", connectionID(h.DestConnectionID).String()) } } - -func (packetHeader) IsNil() bool { return false } diff --git a/qlog/packet_header_test.go b/qlog/packet_header_test.go index 5b90a61c..f9ee17f7 100644 --- a/qlog/packet_header_test.go +++ b/qlog/packet_header_test.go @@ -8,6 +8,7 @@ import ( "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/wire" + "github.com/lucas-clemente/quic-go/logging" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -15,59 +16,10 @@ import ( var _ = Describe("Packet Header", func() { It("determines the packet type from the encryption level", func() { - Expect(getPacketTypeFromEncryptionLevel(protocol.EncryptionInitial)).To(Equal(PacketTypeInitial)) - Expect(getPacketTypeFromEncryptionLevel(protocol.EncryptionHandshake)).To(Equal(PacketTypeHandshake)) - Expect(getPacketTypeFromEncryptionLevel(protocol.Encryption0RTT)).To(Equal(PacketType0RTT)) - Expect(getPacketTypeFromEncryptionLevel(protocol.Encryption1RTT)).To(Equal(PacketType1RTT)) - }) - - Context("determining the packet type from the header", func() { - It("recognizes Initial packets", func() { - Expect(PacketTypeFromHeader(&wire.Header{ - IsLongHeader: true, - Type: protocol.PacketTypeInitial, - Version: protocol.VersionTLS, - })).To(Equal(PacketTypeInitial)) - }) - - It("recognizes Handshake packets", func() { - Expect(PacketTypeFromHeader(&wire.Header{ - IsLongHeader: true, - Type: protocol.PacketTypeHandshake, - Version: protocol.VersionTLS, - })).To(Equal(PacketTypeHandshake)) - }) - - It("recognizes Retry packets", func() { - Expect(PacketTypeFromHeader(&wire.Header{ - IsLongHeader: true, - Type: protocol.PacketTypeRetry, - Version: protocol.VersionTLS, - })).To(Equal(PacketTypeRetry)) - }) - - It("recognizes 0-RTT packets", func() { - Expect(PacketTypeFromHeader(&wire.Header{ - IsLongHeader: true, - Type: protocol.PacketType0RTT, - Version: protocol.VersionTLS, - })).To(Equal(PacketType0RTT)) - }) - - It("recognizes Version Negotiation packets", func() { - Expect(PacketTypeFromHeader(&wire.Header{IsLongHeader: true})).To(Equal(PacketTypeVersionNegotiation)) - }) - - It("recognizes 1-RTT packets", func() { - Expect(PacketTypeFromHeader(&wire.Header{})).To(Equal(PacketType1RTT)) - }) - - It("handles unrecognized packet types", func() { - Expect(PacketTypeFromHeader(&wire.Header{ - IsLongHeader: true, - Version: protocol.VersionTLS, - })).To(Equal(PacketTypeNotDetermined)) - }) + Expect(getPacketTypeFromEncryptionLevel(protocol.EncryptionInitial)).To(Equal(logging.PacketTypeInitial)) + Expect(getPacketTypeFromEncryptionLevel(protocol.EncryptionHandshake)).To(Equal(logging.PacketTypeHandshake)) + Expect(getPacketTypeFromEncryptionLevel(protocol.Encryption0RTT)).To(Equal(logging.PacketType0RTT)) + Expect(getPacketTypeFromEncryptionLevel(protocol.Encryption1RTT)).To(Equal(logging.PacketType1RTT)) }) Context("marshalling", func() { diff --git a/qlog/qlog.go b/qlog/qlog.go index 889dc9a6..58576768 100644 --- a/qlog/qlog.go +++ b/qlog/qlog.go @@ -11,37 +11,13 @@ import ( "github.com/lucas-clemente/quic-go/internal/congestion" "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/wire" + "github.com/lucas-clemente/quic-go/logging" "github.com/francoispqt/gojay" ) const eventChanSize = 50 -// A Tracer records events to be exported to a qlog. -type Tracer interface { - Export() error - StartedConnection(local, remote net.Addr, version protocol.VersionNumber, srcConnID, destConnID protocol.ConnectionID) - ClosedConnection(CloseReason) - SentTransportParameters(*wire.TransportParameters) - ReceivedTransportParameters(*wire.TransportParameters) - SentPacket(hdr *wire.ExtendedHeader, packetSize protocol.ByteCount, ack *wire.AckFrame, frames []wire.Frame) - ReceivedVersionNegotiationPacket(*wire.Header) - ReceivedRetry(*wire.Header) - ReceivedPacket(hdr *wire.ExtendedHeader, packetSize protocol.ByteCount, frames []wire.Frame) - ReceivedStatelessReset(token *[16]byte) - BufferedPacket(PacketType) - DroppedPacket(PacketType, protocol.ByteCount, PacketDropReason) - UpdatedMetrics(rttStats *congestion.RTTStats, cwnd protocol.ByteCount, bytesInFLight protocol.ByteCount, packetsInFlight int) - LostPacket(protocol.EncryptionLevel, protocol.PacketNumber, PacketLossReason) - UpdatedPTOCount(value uint32) - UpdatedKeyFromTLS(protocol.EncryptionLevel, protocol.Perspective) - UpdatedKey(generation protocol.KeyPhase, remote bool) - DroppedEncryptionLevel(protocol.EncryptionLevel) - SetLossTimer(TimerType, protocol.EncryptionLevel, time.Time) - LossTimerExpired(TimerType, protocol.EncryptionLevel) - LossTimerCanceled() -} - type tracer struct { mutex sync.Mutex @@ -58,10 +34,10 @@ type tracer struct { lastMetrics *metrics } -var _ Tracer = &tracer{} +var _ logging.Tracer = &tracer{} // NewTracer creates a new tracer to record a qlog. -func NewTracer(w io.WriteCloser, p protocol.Perspective, odcid protocol.ConnectionID) Tracer { +func NewTracer(w io.WriteCloser, p protocol.Perspective, odcid protocol.ConnectionID) logging.Tracer { t := &tracer{ w: w, perspective: p, @@ -155,7 +131,7 @@ func (t *tracer) StartedConnection(local, remote net.Addr, version protocol.Vers t.mutex.Unlock() } -func (t *tracer) ClosedConnection(r CloseReason) { +func (t *tracer) ClosedConnection(r logging.CloseReason) { t.mutex.Lock() t.recordEvent(time.Now(), &eventConnectionClosed{Reason: r}) t.mutex.Unlock() @@ -214,7 +190,7 @@ func (t *tracer) SentPacket(hdr *wire.ExtendedHeader, packetSize protocol.ByteCo header.PacketSize = packetSize t.mutex.Lock() t.recordEvent(time.Now(), &eventPacketSent{ - PacketType: PacketTypeFromHeader(&hdr.Header), + PacketType: logging.PacketTypeFromHeader(&hdr.Header), Header: header, Frames: fs, }) @@ -230,7 +206,7 @@ func (t *tracer) ReceivedPacket(hdr *wire.ExtendedHeader, packetSize protocol.By header.PacketSize = packetSize t.mutex.Lock() t.recordEvent(time.Now(), &eventPacketReceived{ - PacketType: PacketTypeFromHeader(&hdr.Header), + PacketType: logging.PacketTypeFromHeader(&hdr.Header), Header: header, Frames: fs, }) @@ -266,13 +242,13 @@ func (t *tracer) ReceivedStatelessReset(token *[16]byte) { t.mutex.Unlock() } -func (t *tracer) BufferedPacket(packetType PacketType) { +func (t *tracer) BufferedPacket(packetType logging.PacketType) { t.mutex.Lock() t.recordEvent(time.Now(), &eventPacketBuffered{PacketType: packetType}) t.mutex.Unlock() } -func (t *tracer) DroppedPacket(packetType PacketType, size protocol.ByteCount, dropReason PacketDropReason) { +func (t *tracer) DroppedPacket(packetType logging.PacketType, size protocol.ByteCount, dropReason logging.PacketDropReason) { t.mutex.Lock() t.recordEvent(time.Now(), &eventPacketDropped{ PacketType: packetType, @@ -301,7 +277,7 @@ func (t *tracer) UpdatedMetrics(rttStats *congestion.RTTStats, cwnd, bytesInFlig t.mutex.Unlock() } -func (t *tracer) LostPacket(encLevel protocol.EncryptionLevel, pn protocol.PacketNumber, lossReason PacketLossReason) { +func (t *tracer) LostPacket(encLevel protocol.EncryptionLevel, pn protocol.PacketNumber, lossReason logging.PacketLossReason) { t.mutex.Lock() t.recordEvent(time.Now(), &eventPacketLost{ PacketType: getPacketTypeFromEncryptionLevel(encLevel), @@ -354,7 +330,7 @@ func (t *tracer) DroppedEncryptionLevel(encLevel protocol.EncryptionLevel) { t.mutex.Unlock() } -func (t *tracer) SetLossTimer(tt TimerType, encLevel protocol.EncryptionLevel, timeout time.Time) { +func (t *tracer) SetLossTimer(tt logging.TimerType, encLevel protocol.EncryptionLevel, timeout time.Time) { t.mutex.Lock() now := time.Now() t.recordEvent(now, &eventLossTimerSet{ @@ -365,7 +341,7 @@ func (t *tracer) SetLossTimer(tt TimerType, encLevel protocol.EncryptionLevel, t t.mutex.Unlock() } -func (t *tracer) LossTimerExpired(tt TimerType, encLevel protocol.EncryptionLevel) { +func (t *tracer) LossTimerExpired(tt logging.TimerType, encLevel protocol.EncryptionLevel) { t.mutex.Lock() t.recordEvent(time.Now(), &eventLossTimerExpired{ TimerType: tt, diff --git a/qlog/qlog_test.go b/qlog/qlog_test.go index 2f590274..52407830 100644 --- a/qlog/qlog_test.go +++ b/qlog/qlog_test.go @@ -11,6 +11,7 @@ import ( "github.com/lucas-clemente/quic-go/internal/congestion" "github.com/lucas-clemente/quic-go/internal/protocol" "github.com/lucas-clemente/quic-go/internal/wire" + "github.com/lucas-clemente/quic-go/logging" . "github.com/onsi/ginkgo" . "github.com/onsi/gomega" @@ -48,7 +49,7 @@ type entry struct { var _ = Describe("Tracer", func() { var ( - tracer Tracer + tracer logging.Tracer buf *bytes.Buffer ) @@ -159,7 +160,7 @@ var _ = Describe("Tracer", func() { }) It("records connection closes", func() { - tracer.ClosedConnection(CloseReasonIdleTimeout) + tracer.ClosedConnection(logging.CloseReasonIdleTimeout) entry := exportAndParseSingle() Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) Expect(entry.Category).To(Equal("transport")) @@ -402,7 +403,7 @@ var _ = Describe("Tracer", func() { }) It("records buffered packets", func() { - tracer.BufferedPacket(PacketTypeHandshake) + tracer.BufferedPacket(logging.PacketTypeHandshake) entry := exportAndParseSingle() Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) Expect(entry.Category).To(Equal("transport")) @@ -413,7 +414,7 @@ var _ = Describe("Tracer", func() { }) It("records dropped packets", func() { - tracer.DroppedPacket(PacketTypeHandshake, 1337, PacketDropPayloadDecryptError) + tracer.DroppedPacket(logging.PacketTypeHandshake, 1337, logging.PacketDropPayloadDecryptError) entry := exportAndParseSingle() Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) Expect(entry.Category).To(Equal("transport")) @@ -503,7 +504,7 @@ var _ = Describe("Tracer", func() { }) It("records lost packets", func() { - tracer.LostPacket(protocol.EncryptionHandshake, 42, PacketLossReorderingThreshold) + tracer.LostPacket(protocol.EncryptionHandshake, 42, logging.PacketLossReorderingThreshold) entry := exportAndParseSingle() Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) Expect(entry.Category).To(Equal("recovery")) @@ -576,7 +577,7 @@ var _ = Describe("Tracer", func() { It("records when the timer is set", func() { timeout := time.Now().Add(137 * time.Millisecond) - tracer.SetLossTimer(TimerTypePTO, protocol.EncryptionHandshake, timeout) + tracer.SetLossTimer(logging.TimerTypePTO, protocol.EncryptionHandshake, timeout) entry := exportAndParseSingle() Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) Expect(entry.Category).To(Equal("recovery")) @@ -592,7 +593,7 @@ var _ = Describe("Tracer", func() { }) It("records when the loss timer expires", func() { - tracer.LossTimerExpired(TimerTypeACK, protocol.Encryption1RTT) + tracer.LossTimerExpired(logging.TimerTypeACK, protocol.Encryption1RTT) entry := exportAndParseSingle() Expect(entry.Time).To(BeTemporally("~", time.Now(), scaleDuration(10*time.Millisecond))) Expect(entry.Category).To(Equal("recovery")) diff --git a/qlog/types.go b/qlog/types.go index 236b6633..74dcbfe2 100644 --- a/qlog/types.go +++ b/qlog/types.go @@ -25,12 +25,6 @@ func (o owner) String() string { } } -type versionNumber protocol.VersionNumber - -func (v versionNumber) String() string { - return fmt.Sprintf("%x", uint32(v)) -} - type streamType protocol.StreamType func (s streamType) String() string { @@ -75,51 +69,14 @@ func (c category) String() string { } } -// PacketType is the packet type of a QUIC packet -type PacketType protocol.PacketType +type versionNumber protocol.VersionNumber -const ( - // PacketTypeInitial is the packet type of an Initial packet - PacketTypeInitial PacketType = iota - // PacketTypeHandshake is the packet type of a Handshake packet - PacketTypeHandshake - // PacketTypeRetry is the packet type of a Retry packet - PacketTypeRetry - // PacketType0RTT is the packet type of a 0-RTT packet - PacketType0RTT - // PacketTypeVersionNegotiation is the packet type of a Version Negotiation packet - PacketTypeVersionNegotiation - // PacketType1RTT is a 1-RTT packet - PacketType1RTT - // PacketTypeStatelessReset is a stateless reset - PacketTypeStatelessReset - // PacketTypeNotDetermined is the packet type when it could not be determined - PacketTypeNotDetermined -) - -func (t PacketType) String() string { - switch t { - case PacketTypeInitial: - return "initial" - case PacketTypeHandshake: - return "handshake" - case PacketTypeRetry: - return "retry" - case PacketType0RTT: - return "0RTT" - case PacketTypeVersionNegotiation: - return "version_negotiation" - case PacketTypeStatelessReset: - return "stateless_reset" - case PacketType1RTT: - return "1RTT" - case PacketTypeNotDetermined: - return "" - default: - panic("unknown packet type") - } +func (v versionNumber) String() string { + return fmt.Sprintf("%x", uint32(v)) } +func (packetHeader) IsNil() bool { return false } + func encLevelToPacketNumberSpace(encLevel protocol.EncryptionLevel) string { switch encLevel { case protocol.EncryptionInitial: @@ -133,26 +90,6 @@ func encLevelToPacketNumberSpace(encLevel protocol.EncryptionLevel) string { } } -type PacketLossReason uint8 - -const ( - // PacketLossReorderingThreshold: when a packet is deemed lost due to reordering threshold - PacketLossReorderingThreshold PacketLossReason = iota - // PacketLossTimeThreshold: when a packet is deemed lost due to time threshold - PacketLossTimeThreshold -) - -func (r PacketLossReason) String() string { - switch r { - case PacketLossReorderingThreshold: - return "reordering_threshold" - case PacketLossTimeThreshold: - return "time_threshold" - default: - panic("unknown loss reason") - } -} - type keyType uint8 const ( @@ -239,62 +176,6 @@ func (t keyUpdateTrigger) String() string { } } -type PacketDropReason uint8 - -const ( - // PacketDropKeyUnavailable is used when a packet is dropped because keys are unavailable - PacketDropKeyUnavailable PacketDropReason = iota - // PacketDropUnknownConnectionID is used when a packet is dropped because the connection ID is unknown - PacketDropUnknownConnectionID - // PacketDropHeaderParseError is used when a packet is dropped because header parsing failed - PacketDropHeaderParseError - // PacketDropPayloadDecryptError is used when a packet is dropped because decrypting the payload failed - PacketDropPayloadDecryptError - // PacketDropProtocolViolation is used when a packet is dropped due to a protocol violation - PacketDropProtocolViolation - // PacketDropDOSPrevention is used when a packet is dropped to mitigate a DoS attack - PacketDropDOSPrevention - // PacketDropUnsupportedVersion is used when a packet is dropped because the version is not supported - PacketDropUnsupportedVersion - // PacketDropUnexpectedPacket is used when an unexpected packet is received - PacketDropUnexpectedPacket - // PacketDropUnexpectedSourceConnectionID is used when a packet with an unexpected source connection ID is received - PacketDropUnexpectedSourceConnectionID - // PacketDropUnexpectedVersion is used when a packet with an unexpected version is received - PacketDropUnexpectedVersion - // PacketDropDuplicate is used when a duplicate packet is received - PacketDropDuplicate -) - -func (r PacketDropReason) String() string { - switch r { - case PacketDropKeyUnavailable: - return "key_unavailable" - case PacketDropUnknownConnectionID: - return "unknown_connection_id" - case PacketDropHeaderParseError: - return "header_parse_error" - case PacketDropPayloadDecryptError: - return "payload_decrypt_error" - case PacketDropProtocolViolation: - return "protocol_violation" - case PacketDropDOSPrevention: - return "dos_prevention" - case PacketDropUnsupportedVersion: - return "unsupported_version" - case PacketDropUnexpectedPacket: - return "unexpected_packet" - case PacketDropUnexpectedSourceConnectionID: - return "unexpected_source_connection_id" - case PacketDropUnexpectedVersion: - return "unexpected_version" - case PacketDropDuplicate: - return "duplicate" - default: - panic("unknown packet drop reason") - } -} - type transportError uint64 func (e transportError) String() string { @@ -331,47 +212,3 @@ func (e transportError) String() string { return "" } } - -// TimerType is the type of the loss detection timer -type TimerType uint8 - -const ( - // TimerTypeACK is the timer type for the early retransmit timer - TimerTypeACK TimerType = iota - // TimerTypePTO is the timer type for the PTO retransmit timer - TimerTypePTO -) - -func (t TimerType) String() string { - switch t { - case TimerTypeACK: - return "ack" - case TimerTypePTO: - return "pto" - default: - panic("unknown timer type") - } -} - -// CloseReason is the reason why a session is closed -type CloseReason uint8 - -const ( - // CloseReasonHandshakeTimeout is used when the session is closed due to a handshake timeout - // This reason is not defined in the qlog draft, but very useful for debugging. - CloseReasonHandshakeTimeout CloseReason = iota - // CloseReasonIdleTimeout is used when the session is closed due to an idle timeout - // This reason is not defined in the qlog draft, but very useful for debugging. - CloseReasonIdleTimeout -) - -func (r CloseReason) String() string { - switch r { - case CloseReasonHandshakeTimeout: - return "handshake_timeout" - case CloseReasonIdleTimeout: - return "idle_timeout" - default: - panic("unknown close reason") - } -} diff --git a/qlog/types_test.go b/qlog/types_test.go index 0be04099..d87c9209 100644 --- a/qlog/types_test.go +++ b/qlog/types_test.go @@ -28,17 +28,6 @@ var _ = Describe("Types", func() { Expect(categorySecurity.String()).To(Equal("security")) }) - It("has a string representation for the packet type", func() { - Expect(PacketTypeInitial.String()).To(Equal("initial")) - Expect(PacketTypeHandshake.String()).To(Equal("handshake")) - Expect(PacketType0RTT.String()).To(Equal("0RTT")) - Expect(PacketType1RTT.String()).To(Equal("1RTT")) - Expect(PacketTypeStatelessReset.String()).To(Equal("stateless_reset")) - Expect(PacketTypeRetry.String()).To(Equal("retry")) - Expect(PacketTypeVersionNegotiation.String()).To(Equal("version_negotiation")) - Expect(PacketTypeNotDetermined.String()).To(BeEmpty()) - }) - It("has a string representation for the key type", func() { Expect(encLevelToKeyType(protocol.EncryptionInitial, protocol.PerspectiveClient).String()).To(Equal("client_initial_secret")) Expect(encLevelToKeyType(protocol.EncryptionInitial, protocol.PerspectiveServer).String()).To(Equal("server_initial_secret")) @@ -63,19 +52,6 @@ var _ = Describe("Types", func() { Expect(encLevelToPacketNumberSpace(protocol.Encryption1RTT)).To(Equal("application_data")) }) - It("has a string representation for the packet drop reason", func() { - Expect(PacketDropKeyUnavailable.String()).To(Equal("key_unavailable")) - Expect(PacketDropUnknownConnectionID.String()).To(Equal("unknown_connection_id")) - Expect(PacketDropHeaderParseError.String()).To(Equal("header_parse_error")) - Expect(PacketDropPayloadDecryptError.String()).To(Equal("payload_decrypt_error")) - Expect(PacketDropProtocolViolation.String()).To(Equal("protocol_violation")) - Expect(PacketDropDOSPrevention.String()).To(Equal("dos_prevention")) - Expect(PacketDropUnsupportedVersion.String()).To(Equal("unsupported_version")) - Expect(PacketDropUnexpectedPacket.String()).To(Equal("unexpected_packet")) - Expect(PacketDropUnexpectedSourceConnectionID.String()).To(Equal("unexpected_source_connection_id")) - Expect(PacketDropUnexpectedVersion.String()).To(Equal("unexpected_version")) - }) - Context("transport errors", func() { It("has a string representation for every error code", func() { // We parse the error code file, extract all constants, and verify that @@ -113,14 +89,4 @@ var _ = Describe("Types", func() { Expect(transportError(1337).String()).To(BeEmpty()) }) }) - - It("has a string representation for the timer type", func() { - Expect(TimerTypeACK.String()).To(Equal("ack")) - Expect(TimerTypePTO.String()).To(Equal("pto")) - }) - - It("has a string representation for the close reason", func() { - Expect(CloseReasonHandshakeTimeout.String()).To(Equal("handshake_timeout")) - Expect(CloseReasonIdleTimeout.String()).To(Equal("idle_timeout")) - }) }) diff --git a/server.go b/server.go index 35f6fdb7..d2a3a05d 100644 --- a/server.go +++ b/server.go @@ -16,6 +16,7 @@ import ( "github.com/lucas-clemente/quic-go/internal/qerr" "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/internal/wire" + "github.com/lucas-clemente/quic-go/logging" "github.com/lucas-clemente/quic-go/qlog" ) @@ -86,7 +87,7 @@ type baseServer struct { *tls.Config, *handshake.TokenGenerator, bool, /* enable 0-RTT */ - qlog.Tracer, + logging.Tracer, utils.Logger, protocol.VersionNumber, ) quicSession @@ -446,7 +447,7 @@ func (s *baseServer) createNewSession( ) quicSession { var sess quicSession if added := s.sessionHandler.AddWithConnID(clientDestConnID, srcConnID, func() packetHandler { - var qlogger qlog.Tracer + var qlogger logging.Tracer if s.config.GetLogWriter != nil { // Use the same connection ID that is passed to the client's GetLogWriter callback. connID := clientDestConnID diff --git a/server_test.go b/server_test.go index ff7756a7..5620a070 100644 --- a/server_test.go +++ b/server_test.go @@ -20,7 +20,7 @@ import ( "github.com/lucas-clemente/quic-go/internal/testdata" "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/internal/wire" - "github.com/lucas-clemente/quic-go/qlog" + "github.com/lucas-clemente/quic-go/logging" "github.com/lucas-clemente/quic-go/quictrace" "github.com/golang/mock/gomock" @@ -335,7 +335,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, enable0RTT bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -508,7 +508,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, enable0RTT bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -575,7 +575,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -618,7 +618,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -666,7 +666,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -696,7 +696,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -761,7 +761,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -869,7 +869,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -936,7 +936,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, enable0RTT bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -974,7 +974,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { @@ -1033,7 +1033,7 @@ var _ = Describe("Server", func() { _ *tls.Config, _ *handshake.TokenGenerator, _ bool, - _ qlog.Tracer, + _ logging.Tracer, _ utils.Logger, _ protocol.VersionNumber, ) quicSession { diff --git a/session.go b/session.go index e9ff537e..5cfdc2a4 100644 --- a/session.go +++ b/session.go @@ -20,7 +20,7 @@ import ( "github.com/lucas-clemente/quic-go/internal/qerr" "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/internal/wire" - "github.com/lucas-clemente/quic-go/qlog" + "github.com/lucas-clemente/quic-go/logging" "github.com/lucas-clemente/quic-go/quictrace" ) @@ -204,7 +204,7 @@ type session struct { traceCallback func(quictrace.Event) logID string - qlogger qlog.Tracer + qlogger logging.Tracer logger utils.Logger } @@ -225,7 +225,7 @@ var newSession = func( tlsConf *tls.Config, tokenGenerator *handshake.TokenGenerator, enable0RTT bool, - qlogger qlog.Tracer, + qlogger logging.Tracer, logger utils.Logger, v protocol.VersionNumber, ) quicSession { @@ -350,7 +350,7 @@ var newClientSession = func( initialVersion protocol.VersionNumber, enable0RTT bool, hasNegotiatedVersion bool, - qlogger qlog.Tracer, + qlogger logging.Tracer, logger utils.Logger, v protocol.VersionNumber, ) quicSession { @@ -592,13 +592,13 @@ runLoop: s.keepAlivePingSent = true } else if !s.handshakeComplete && now.Sub(s.sessionCreationTime) >= s.config.HandshakeTimeout { if s.qlogger != nil { - s.qlogger.ClosedConnection(qlog.CloseReasonHandshakeTimeout) + s.qlogger.ClosedConnection(logging.CloseReasonHandshakeTimeout) } s.destroyImpl(qerr.NewTimeoutError("Handshake did not complete in time")) continue } else if s.handshakeComplete && now.Sub(s.idleTimeoutStartTime()) >= s.idleTimeout { if s.qlogger != nil { - s.qlogger.ClosedConnection(qlog.CloseReasonIdleTimeout) + s.qlogger.ClosedConnection(logging.CloseReasonIdleTimeout) } s.destroyImpl(qerr.NewTimeoutError("No recent network activity")) continue @@ -727,11 +727,11 @@ func (s *session) handlePacketImpl(rp *receivedPacket) bool { hdr, packetData, rest, err := wire.ParsePacket(p.data, s.srcConnIDLen) if err != nil { if s.qlogger != nil { - dropReason := qlog.PacketDropHeaderParseError + dropReason := logging.PacketDropHeaderParseError if err == wire.ErrUnsupportedVersion { - dropReason = qlog.PacketDropUnsupportedVersion + dropReason = logging.PacketDropUnsupportedVersion } - s.qlogger.DroppedPacket(qlog.PacketTypeNotDetermined, protocol.ByteCount(len(data)), dropReason) + s.qlogger.DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(data)), dropReason) } s.logger.Debugf("error parsing packet: %s", err) break @@ -739,7 +739,7 @@ func (s *session) handlePacketImpl(rp *receivedPacket) bool { if hdr.IsLongHeader && hdr.Version != s.version { if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeFromHeader(hdr), protocol.ByteCount(len(data)), qlog.PacketDropUnexpectedVersion) + s.qlogger.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(data)), logging.PacketDropUnexpectedVersion) } s.logger.Debugf("Dropping packet with version %x. Expected %x.", hdr.Version, s.version) break @@ -747,7 +747,7 @@ func (s *session) handlePacketImpl(rp *receivedPacket) bool { if counter > 0 && !hdr.DestConnectionID.Equal(lastConnID) { if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeFromHeader(hdr), protocol.ByteCount(len(data)), qlog.PacketDropUnknownConnectionID) + s.qlogger.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(data)), logging.PacketDropUnknownConnectionID) } s.logger.Debugf("coalesced packet has different destination connection ID: %s, expected %s", hdr.DestConnectionID, lastConnID) break @@ -791,14 +791,14 @@ func (s *session) handleSinglePacket(p *receivedPacket, hdr *wire.Header) bool / // After this, all packets with a different source connection have to be ignored. if s.receivedFirstPacket && hdr.IsLongHeader && !hdr.SrcConnectionID.Equal(s.handshakeDestConnID) { if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeFromHeader(hdr), protocol.ByteCount(len(p.data)), qlog.PacketDropUnknownConnectionID) + s.qlogger.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(p.data)), logging.PacketDropUnknownConnectionID) } s.logger.Debugf("Dropping %s packet (%d bytes) with unexpected source connection ID: %s (expected %s)", hdr.PacketType(), len(p.data), hdr.SrcConnectionID, s.handshakeDestConnID) return false } // drop 0-RTT packets, if we are a client if s.perspective == protocol.PerspectiveClient && hdr.Type == protocol.PacketType0RTT { - s.qlogger.DroppedPacket(qlog.PacketType0RTT, protocol.ByteCount(len(p.data)), qlog.PacketDropKeyUnavailable) + s.qlogger.DroppedPacket(logging.PacketType0RTT, protocol.ByteCount(len(p.data)), logging.PacketDropKeyUnavailable) return false } @@ -807,7 +807,7 @@ func (s *session) handleSinglePacket(p *receivedPacket, hdr *wire.Header) bool / switch err { case handshake.ErrKeysDropped: if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeFromHeader(hdr), protocol.ByteCount(len(p.data)), qlog.PacketDropKeyUnavailable) + s.qlogger.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(p.data)), logging.PacketDropKeyUnavailable) } s.logger.Debugf("Dropping %s packet (%d bytes) because we already dropped the keys.", hdr.PacketType(), len(p.data)) case handshake.ErrKeysNotYetAvailable: @@ -821,7 +821,7 @@ func (s *session) handleSinglePacket(p *receivedPacket, hdr *wire.Header) bool / // This might be a packet injected by an attacker. // Drop it. if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeFromHeader(hdr), protocol.ByteCount(len(p.data)), qlog.PacketDropPayloadDecryptError) + s.qlogger.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(p.data)), logging.PacketDropPayloadDecryptError) } s.logger.Debugf("Dropping %s packet (%d bytes) that could not be unpacked. Error: %s", hdr.PacketType(), len(p.data), err) } @@ -836,7 +836,7 @@ func (s *session) handleSinglePacket(p *receivedPacket, hdr *wire.Header) bool / if s.receivedPacketHandler.IsPotentiallyDuplicate(packet.packetNumber, packet.encryptionLevel) { s.logger.Debugf("Dropping (potentially) duplicate packet.") if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeFromHeader(hdr), protocol.ByteCount(len(p.data)), qlog.PacketDropDuplicate) + s.qlogger.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(p.data)), logging.PacketDropDuplicate) } return false } @@ -852,14 +852,14 @@ func (s *session) handleRetryPacket(hdr *wire.Header, data []byte) bool /* was t (&wire.ExtendedHeader{Header: *hdr}).Log(s.logger) if s.perspective == protocol.PerspectiveServer { if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(data)), qlog.PacketDropUnexpectedPacket) + s.qlogger.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) } s.logger.Debugf("Ignoring Retry.") return false } if s.receivedFirstPacket { if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(data)), qlog.PacketDropUnexpectedPacket) + s.qlogger.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) } s.logger.Debugf("Ignoring Retry, since we already received a packet.") return false @@ -867,7 +867,7 @@ func (s *session) handleRetryPacket(hdr *wire.Header, data []byte) bool /* was t destConnID := s.connIDManager.Get() if hdr.SrcConnectionID.Equal(destConnID) { if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(data)), qlog.PacketDropUnexpectedPacket) + s.qlogger.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropUnexpectedPacket) } s.logger.Debugf("Ignoring Retry, since the server didn't change the Source Connection ID.") return false @@ -882,7 +882,7 @@ func (s *session) handleRetryPacket(hdr *wire.Header, data []byte) bool /* was t tag := handshake.GetRetryIntegrityTag(data[:len(data)-16], destConnID) if !bytes.Equal(data[len(data)-16:], tag[:]) { if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(data)), qlog.PacketDropPayloadDecryptError) + s.qlogger.DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(data)), logging.PacketDropPayloadDecryptError) } s.logger.Debugf("Ignoring spoofed Retry. Integrity Tag doesn't match.") return false @@ -912,7 +912,7 @@ func (s *session) handleVersionNegotiationPacket(p *receivedPacket) { if s.perspective == protocol.PerspectiveServer || // servers never receive version negotiation packets s.receivedFirstPacket || s.versionNegotiated { // ignore delayed / duplicated version negotiation packets if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeVersionNegotiation, protocol.ByteCount(len(p.data)), qlog.PacketDropUnexpectedPacket) + s.qlogger.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.ByteCount(len(p.data)), logging.PacketDropUnexpectedPacket) } return } @@ -920,7 +920,7 @@ func (s *session) handleVersionNegotiationPacket(p *receivedPacket) { hdr, _, _, err := wire.ParsePacket(p.data, 0) if err != nil { if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeVersionNegotiation, protocol.ByteCount(len(p.data)), qlog.PacketDropHeaderParseError) + s.qlogger.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.ByteCount(len(p.data)), logging.PacketDropHeaderParseError) } s.logger.Debugf("Error parsing Version Negotiation packet: %s", err) return @@ -929,7 +929,7 @@ func (s *session) handleVersionNegotiationPacket(p *receivedPacket) { for _, v := range hdr.SupportedVersions { if v == s.version { if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeVersionNegotiation, protocol.ByteCount(len(p.data)), qlog.PacketDropUnexpectedVersion) + s.qlogger.DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.ByteCount(len(p.data)), logging.PacketDropUnexpectedVersion) } // The Version Negotiation packet contains the version that we offered. // This might be a packet sent by an attacker, or it was corrupted. @@ -1677,14 +1677,14 @@ func (s *session) scheduleSending() { func (s *session) tryQueueingUndecryptablePacket(p *receivedPacket, hdr *wire.Header) { if len(s.undecryptablePackets)+1 > protocol.MaxUndecryptablePackets { if s.qlogger != nil { - s.qlogger.DroppedPacket(qlog.PacketTypeFromHeader(hdr), protocol.ByteCount(len(p.data)), qlog.PacketDropDOSPrevention) + s.qlogger.DroppedPacket(logging.PacketTypeFromHeader(hdr), protocol.ByteCount(len(p.data)), logging.PacketDropDOSPrevention) } s.logger.Infof("Dropping undecryptable packet (%d bytes). Undecryptable packet queue full.", len(p.data)) return } s.logger.Infof("Queueing packet (%d bytes) for later decryption", len(p.data)) if s.qlogger != nil { - s.qlogger.BufferedPacket(qlog.PacketTypeFromHeader(hdr)) + s.qlogger.BufferedPacket(logging.PacketTypeFromHeader(hdr)) } s.undecryptablePackets = append(s.undecryptablePackets, p) } diff --git a/session_test.go b/session_test.go index 49a111e5..37f6ab49 100644 --- a/session_test.go +++ b/session_test.go @@ -21,7 +21,7 @@ import ( "github.com/lucas-clemente/quic-go/internal/testutils" "github.com/lucas-clemente/quic-go/internal/utils" "github.com/lucas-clemente/quic-go/internal/wire" - "github.com/lucas-clemente/quic-go/qlog" + "github.com/lucas-clemente/quic-go/logging" "github.com/golang/mock/gomock" @@ -587,14 +587,14 @@ var _ = Describe("Session", func() { Version: sess.version, Token: []byte("foobar"), }}, make([]byte, 16) /* Retry integrity tag */) - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(p.data)), qlog.PacketDropUnexpectedPacket) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(p.data)), logging.PacketDropUnexpectedPacket) Expect(sess.handlePacketImpl(p)).To(BeFalse()) }) It("drops Version Negotiation packets", func() { b, err := wire.ComposeVersionNegotiation(srcConnID, destConnID, sess.config.Versions) Expect(err).ToNot(HaveOccurred()) - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeVersionNegotiation, protocol.ByteCount(len(b)), qlog.PacketDropUnexpectedPacket) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.ByteCount(len(b)), logging.PacketDropUnexpectedPacket) Expect(sess.handlePacketImpl(&receivedPacket{ data: b, buffer: getPacketBuffer(), @@ -611,7 +611,7 @@ var _ = Describe("Session", func() { PacketNumberLen: protocol.PacketNumberLen2, }, nil) p.data[0] ^= 0x40 // unset the QUIC bit - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeNotDetermined, protocol.ByteCount(len(p.data)), qlog.PacketDropHeaderParseError) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(p.data)), logging.PacketDropHeaderParseError) Expect(sess.handlePacketImpl(p)).To(BeFalse()) }) @@ -624,7 +624,7 @@ var _ = Describe("Session", func() { }, PacketNumberLen: protocol.PacketNumberLen2, }, nil) - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeNotDetermined, protocol.ByteCount(len(p.data)), qlog.PacketDropUnsupportedVersion) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeNotDetermined, protocol.ByteCount(len(p.data)), logging.PacketDropUnsupportedVersion) Expect(sess.handlePacketImpl(p)).To(BeFalse()) }) @@ -646,7 +646,7 @@ var _ = Describe("Session", func() { }, PacketNumberLen: protocol.PacketNumberLen2, }, nil) - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeHandshake, protocol.ByteCount(len(p.data)), qlog.PacketDropUnexpectedVersion) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeHandshake, protocol.ByteCount(len(p.data)), logging.PacketDropUnexpectedVersion) Expect(sess.handlePacketImpl(p)).To(BeFalse()) }) @@ -720,7 +720,7 @@ var _ = Describe("Session", func() { rph := mockackhandler.NewMockReceivedPacketHandler(mockCtrl) rph.EXPECT().IsPotentiallyDuplicate(protocol.PacketNumber(0x1337), protocol.Encryption1RTT).Return(true) sess.receivedPacketHandler = rph - qlogger.EXPECT().DroppedPacket(qlog.PacketType1RTT, protocol.ByteCount(len(packet.data)), qlog.PacketDropDuplicate) + qlogger.EXPECT().DroppedPacket(logging.PacketType1RTT, protocol.ByteCount(len(packet.data)), logging.PacketDropDuplicate) Expect(sess.handlePacketImpl(packet)).To(BeFalse()) }) @@ -746,7 +746,7 @@ var _ = Describe("Session", func() { PacketNumber: 0x1337, PacketNumberLen: protocol.PacketNumberLen2, }, []byte("foobar")) - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeHandshake, protocol.ByteCount(len(p.data)), qlog.PacketDropPayloadDecryptError) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeHandshake, protocol.ByteCount(len(p.data)), logging.PacketDropPayloadDecryptError) sess.handlePacket(p) Consistently(sess.Context().Done()).ShouldNot(BeClosed()) // make the go routine return @@ -794,7 +794,7 @@ var _ = Describe("Session", func() { runErr <- sess.run() }() expectReplaceWithClosed() - qlogger.EXPECT().DroppedPacket(qlog.PacketType1RTT, gomock.Any(), qlog.PacketDropPayloadDecryptError) + qlogger.EXPECT().DroppedPacket(logging.PacketType1RTT, gomock.Any(), logging.PacketDropPayloadDecryptError) sess.handlePacket(getPacket(&wire.ExtendedHeader{ Header: wire.Header{DestConnectionID: srcConnID}, PacketNumberLen: protocol.PacketNumberLen1, @@ -872,7 +872,7 @@ var _ = Describe("Session", func() { Expect(sess.handlePacketImpl(p1)).To(BeTrue()) // The next packet has to be ignored, since the source connection ID doesn't match. p2 := getPacket(hdr2, nil) - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeHandshake, protocol.ByteCount(len(p2.data)), qlog.PacketDropUnknownConnectionID) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeHandshake, protocol.ByteCount(len(p2.data)), logging.PacketDropUnknownConnectionID) Expect(sess.handlePacketImpl(p2)).To(BeFalse()) }) @@ -892,7 +892,7 @@ var _ = Describe("Session", func() { } unpacker.EXPECT().Unpack(gomock.Any(), gomock.Any(), gomock.Any()).Return(nil, handshake.ErrKeysNotYetAvailable) packet := getPacket(hdr, nil) - qlogger.EXPECT().BufferedPacket(qlog.PacketTypeHandshake) + qlogger.EXPECT().BufferedPacket(logging.PacketTypeHandshake) Expect(sess.handlePacketImpl(packet)).To(BeFalse()) Expect(sess.undecryptablePackets).To(Equal([]*receivedPacket{packet})) }) @@ -1023,7 +1023,7 @@ var _ = Describe("Session", func() { // don't EXPECT any more calls to unpacker.Unpack() gomock.InOrder( qlogger.EXPECT().ReceivedPacket(gomock.Any(), protocol.ByteCount(len(packet1.data)), gomock.Any()), - qlogger.EXPECT().DroppedPacket(gomock.Any(), protocol.ByteCount(len(packet2.data)), qlog.PacketDropUnknownConnectionID), + qlogger.EXPECT().DroppedPacket(gomock.Any(), protocol.ByteCount(len(packet2.data)), logging.PacketDropUnknownConnectionID), ) packet1.data = append(packet1.data, packet2.data...) Expect(sess.handlePacketImpl(packet1)).To(BeTrue()) @@ -1789,7 +1789,7 @@ var _ = Describe("Session", func() { done := make(chan struct{}) cryptoSetup.EXPECT().Close() gomock.InOrder( - qlogger.EXPECT().ClosedConnection(qlog.CloseReasonIdleTimeout), + qlogger.EXPECT().ClosedConnection(logging.CloseReasonIdleTimeout), qlogger.EXPECT().Export(), ) go func() { @@ -1811,7 +1811,7 @@ var _ = Describe("Session", func() { sessionRunner.EXPECT().Remove(gomock.Any()).Times(2) cryptoSetup.EXPECT().Close() gomock.InOrder( - qlogger.EXPECT().ClosedConnection(qlog.CloseReasonHandshakeTimeout), + qlogger.EXPECT().ClosedConnection(logging.CloseReasonHandshakeTimeout), qlogger.EXPECT().Export(), ) done := make(chan struct{}) @@ -1861,7 +1861,7 @@ var _ = Describe("Session", func() { ) cryptoSetup.EXPECT().Close() gomock.InOrder( - qlogger.EXPECT().ClosedConnection(qlog.CloseReasonIdleTimeout), + qlogger.EXPECT().ClosedConnection(logging.CloseReasonIdleTimeout), qlogger.EXPECT().Export(), ) sess.idleTimeout = 0 @@ -2195,14 +2195,14 @@ var _ = Describe("Client Session", func() { It("ignores Version Negotiation packets that offer the current version", func() { p := getVNP(sess.version) - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeVersionNegotiation, protocol.ByteCount(len(p.data)), qlog.PacketDropUnexpectedVersion) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.ByteCount(len(p.data)), logging.PacketDropUnexpectedVersion) Expect(sess.handlePacketImpl(p)).To(BeFalse()) }) It("ignores unparseable Version Negotiation packets", func() { p := getVNP(sess.version) p.data = p.data[:len(p.data)-2] - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeVersionNegotiation, protocol.ByteCount(len(p.data)), qlog.PacketDropHeaderParseError) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeVersionNegotiation, protocol.ByteCount(len(p.data)), logging.PacketDropHeaderParseError) Expect(sess.handlePacketImpl(p)).To(BeFalse()) }) }) @@ -2249,14 +2249,14 @@ var _ = Describe("Client Session", func() { It("ignores Retry packets after receiving a regular packet", func() { sess.receivedFirstPacket = true p := getPacket(retryHdr, getRetryTag(retryHdr)) - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(p.data)), qlog.PacketDropUnexpectedPacket) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(p.data)), logging.PacketDropUnexpectedPacket) Expect(sess.handlePacketImpl(p)).To(BeFalse()) }) It("ignores Retry packets if the server didn't change the connection ID", func() { retryHdr.SrcConnectionID = destConnID p := getPacket(retryHdr, getRetryTag(retryHdr)) - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(p.data)), qlog.PacketDropUnexpectedPacket) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(p.data)), logging.PacketDropUnexpectedPacket) Expect(sess.handlePacketImpl(p)).To(BeFalse()) }) @@ -2264,7 +2264,7 @@ var _ = Describe("Client Session", func() { tag := getRetryTag(retryHdr) tag[0]++ p := getPacket(retryHdr, tag) - qlogger.EXPECT().DroppedPacket(qlog.PacketTypeRetry, protocol.ByteCount(len(p.data)), qlog.PacketDropPayloadDecryptError) + qlogger.EXPECT().DroppedPacket(logging.PacketTypeRetry, protocol.ByteCount(len(p.data)), logging.PacketDropPayloadDecryptError) Expect(sess.handlePacketImpl(p)).To(BeFalse()) }) }) @@ -2490,7 +2490,7 @@ var _ = Describe("Client Session", func() { PacketNumber: 0x42, PacketNumberLen: protocol.PacketNumberLen2, }, []byte("foobar")) - qlogger.EXPECT().DroppedPacket(qlog.PacketType0RTT, protocol.ByteCount(len(p.data)), gomock.Any()) + qlogger.EXPECT().DroppedPacket(logging.PacketType0RTT, protocol.ByteCount(len(p.data)), gomock.Any()) Expect(sess.handlePacketImpl(p)).To(BeFalse()) })