diff --git a/internal/handshake/crypto_setup.go b/internal/handshake/crypto_setup.go index 9a19224a..f928d17d 100644 --- a/internal/handshake/crypto_setup.go +++ b/internal/handshake/crypto_setup.go @@ -340,7 +340,7 @@ func (h *cryptoSetup) onError(alert uint8, message string) { if alert == 0 { err = &qerr.TransportError{ErrorCode: qerr.InternalError, ErrorMessage: message} } else { - err = qerr.NewCryptoError(alert, message) + err = qerr.NewLocalCryptoError(alert, message) } h.runner.OnError(err) } diff --git a/internal/qerr/error_codes.go b/internal/qerr/error_codes.go index bee42d51..f56f91a2 100644 --- a/internal/qerr/error_codes.go +++ b/internal/qerr/error_codes.go @@ -81,7 +81,7 @@ func (e TransportErrorCode) String() string { return "NO_VIABLE_PATH" default: if e.IsCryptoError() { - return fmt.Sprintf("CRYPTO_ERROR (%#x)", uint16(e)) + return fmt.Sprintf("CRYPTO_ERROR %#x", uint16(e)) } return fmt.Sprintf("unknown error code: %#x", uint16(e)) } diff --git a/internal/qerr/errors.go b/internal/qerr/errors.go index 8b1cff98..3f0208d6 100644 --- a/internal/qerr/errors.go +++ b/internal/qerr/errors.go @@ -21,8 +21,8 @@ type TransportError struct { var _ error = &TransportError{} -// NewCryptoError create a new TransportError instance for a crypto error -func NewCryptoError(tlsAlert uint8, errorMessage string) *TransportError { +// NewLocalCryptoError create a new TransportError instance for a crypto error +func NewLocalCryptoError(tlsAlert uint8, errorMessage string) *TransportError { return &TransportError{ ErrorCode: 0x100 + TransportErrorCode(tlsAlert), ErrorMessage: errorMessage, @@ -30,7 +30,7 @@ func NewCryptoError(tlsAlert uint8, errorMessage string) *TransportError { } func (e *TransportError) Error() string { - str := e.ErrorCode.String() + str := fmt.Sprintf("%s (%s)", e.ErrorCode.String(), getRole(e.Remote)) if e.FrameType != 0 { str += fmt.Sprintf(" (frame type: %#x)", e.FrameType) } @@ -68,9 +68,9 @@ var _ error = &ApplicationError{} func (e *ApplicationError) Error() string { if len(e.ErrorMessage) == 0 { - return fmt.Sprintf("Application error %#x", e.ErrorCode) + return fmt.Sprintf("Application error %#x (%s)", e.ErrorCode, getRole(e.Remote)) } - return fmt.Sprintf("Application error %#x: %s", e.ErrorCode, e.ErrorMessage) + return fmt.Sprintf("Application error %#x (%s): %s", e.ErrorCode, getRole(e.Remote), e.ErrorMessage) } type IdleTimeoutError struct{} @@ -122,3 +122,10 @@ func (e *StatelessResetError) Is(target error) bool { func (e *StatelessResetError) Timeout() bool { return false } func (e *StatelessResetError) Temporary() bool { return true } + +func getRole(remote bool) string { + if remote { + return "remote" + } + return "local" +} diff --git a/internal/qerr/errors_test.go b/internal/qerr/errors_test.go index 62566dd7..a31eb6e9 100644 --- a/internal/qerr/errors_test.go +++ b/internal/qerr/errors_test.go @@ -15,18 +15,19 @@ var _ = Describe("QUIC Errors", func() { Expect((&TransportError{ ErrorCode: FlowControlError, ErrorMessage: "foobar", - }).Error()).To(Equal("FLOW_CONTROL_ERROR: foobar")) + }).Error()).To(Equal("FLOW_CONTROL_ERROR (local): foobar")) }) It("has a string representation for empty error phrases", func() { - Expect((&TransportError{ErrorCode: FlowControlError}).Error()).To(Equal("FLOW_CONTROL_ERROR")) + Expect((&TransportError{ErrorCode: FlowControlError}).Error()).To(Equal("FLOW_CONTROL_ERROR (local)")) }) It("includes the frame type, for errors without a message", func() { Expect((&TransportError{ + Remote: true, ErrorCode: FlowControlError, FrameType: 0x1337, - }).Error()).To(Equal("FLOW_CONTROL_ERROR (frame type: 0x1337)")) + }).Error()).To(Equal("FLOW_CONTROL_ERROR (remote) (frame type: 0x1337)")) }) It("includes the frame type, for errors with a message", func() { @@ -34,18 +35,18 @@ var _ = Describe("QUIC Errors", func() { ErrorCode: FlowControlError, FrameType: 0x1337, ErrorMessage: "foobar", - }).Error()).To(Equal("FLOW_CONTROL_ERROR (frame type: 0x1337): foobar")) + }).Error()).To(Equal("FLOW_CONTROL_ERROR (local) (frame type: 0x1337): foobar")) }) Context("crypto errors", func() { It("has a string representation for errors with a message", func() { - err := NewCryptoError(0x42, "foobar") - Expect(err.Error()).To(Equal("CRYPTO_ERROR (0x142): foobar")) + err := NewLocalCryptoError(0x42, "foobar") + Expect(err.Error()).To(Equal("CRYPTO_ERROR 0x142 (local): foobar")) }) It("has a string representation for errors without a message", func() { - err := NewCryptoError(0x2a, "") - Expect(err.Error()).To(Equal("CRYPTO_ERROR (0x12a): tls: bad certificate")) + err := NewLocalCryptoError(0x2a, "") + Expect(err.Error()).To(Equal("CRYPTO_ERROR 0x12a (local): tls: bad certificate")) }) }) }) @@ -55,13 +56,14 @@ var _ = Describe("QUIC Errors", func() { Expect((&ApplicationError{ ErrorCode: 0x42, ErrorMessage: "foobar", - }).Error()).To(Equal("Application error 0x42: foobar")) + }).Error()).To(Equal("Application error 0x42 (local): foobar")) }) It("has a string representation for errors without a message", func() { Expect((&ApplicationError{ ErrorCode: 0x42, - }).Error()).To(Equal("Application error 0x42")) + Remote: true, + }).Error()).To(Equal("Application error 0x42 (remote)")) }) }) diff --git a/packet_packer_test.go b/packet_packer_test.go index c13d2e09..093f10d2 100644 --- a/packet_packer_test.go +++ b/packet_packer_test.go @@ -344,7 +344,7 @@ var _ = Describe("Packet packer", func() { sealingManager.EXPECT().GetInitialSealer().Return(nil, handshake.ErrKeysDropped) sealingManager.EXPECT().GetHandshakeSealer().Return(getSealer(), nil) sealingManager.EXPECT().Get1RTTSealer().Return(nil, handshake.ErrKeysNotYetAvailable) - quicErr := qerr.NewCryptoError(0x42, "crypto error") + quicErr := qerr.NewLocalCryptoError(0x42, "crypto error") quicErr.FrameType = 0x1234 p, err := packer.PackConnectionClose(quicErr) Expect(err).ToNot(HaveOccurred())