golang.org/x/net@v0.25.1-0.20240516223405-c87a5b62e243/quic/errors.go (about) 1 // Copyright 2023 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build go1.21 6 7 package quic 8 9 import ( 10 "fmt" 11 ) 12 13 // A transportError is a transport error code from RFC 9000 Section 20.1. 14 // 15 // The transportError type doesn't implement the error interface to ensure we always 16 // distinguish between errors sent to and received from the peer. 17 // See the localTransportError and peerTransportError types below. 18 type transportError uint64 19 20 // https://www.rfc-editor.org/rfc/rfc9000.html#section-20.1 21 const ( 22 errNo = transportError(0x00) 23 errInternal = transportError(0x01) 24 errConnectionRefused = transportError(0x02) 25 errFlowControl = transportError(0x03) 26 errStreamLimit = transportError(0x04) 27 errStreamState = transportError(0x05) 28 errFinalSize = transportError(0x06) 29 errFrameEncoding = transportError(0x07) 30 errTransportParameter = transportError(0x08) 31 errConnectionIDLimit = transportError(0x09) 32 errProtocolViolation = transportError(0x0a) 33 errInvalidToken = transportError(0x0b) 34 errApplicationError = transportError(0x0c) 35 errCryptoBufferExceeded = transportError(0x0d) 36 errKeyUpdateError = transportError(0x0e) 37 errAEADLimitReached = transportError(0x0f) 38 errNoViablePath = transportError(0x10) 39 errTLSBase = transportError(0x0100) // 0x0100-0x01ff; base + TLS code 40 ) 41 42 func (e transportError) String() string { 43 switch e { 44 case errNo: 45 return "NO_ERROR" 46 case errInternal: 47 return "INTERNAL_ERROR" 48 case errConnectionRefused: 49 return "CONNECTION_REFUSED" 50 case errFlowControl: 51 return "FLOW_CONTROL_ERROR" 52 case errStreamLimit: 53 return "STREAM_LIMIT_ERROR" 54 case errStreamState: 55 return "STREAM_STATE_ERROR" 56 case errFinalSize: 57 return "FINAL_SIZE_ERROR" 58 case errFrameEncoding: 59 return "FRAME_ENCODING_ERROR" 60 case errTransportParameter: 61 return "TRANSPORT_PARAMETER_ERROR" 62 case errConnectionIDLimit: 63 return "CONNECTION_ID_LIMIT_ERROR" 64 case errProtocolViolation: 65 return "PROTOCOL_VIOLATION" 66 case errInvalidToken: 67 return "INVALID_TOKEN" 68 case errApplicationError: 69 return "APPLICATION_ERROR" 70 case errCryptoBufferExceeded: 71 return "CRYPTO_BUFFER_EXCEEDED" 72 case errKeyUpdateError: 73 return "KEY_UPDATE_ERROR" 74 case errAEADLimitReached: 75 return "AEAD_LIMIT_REACHED" 76 case errNoViablePath: 77 return "NO_VIABLE_PATH" 78 } 79 if e >= 0x0100 && e <= 0x01ff { 80 return fmt.Sprintf("CRYPTO_ERROR(%v)", uint64(e)&0xff) 81 } 82 return fmt.Sprintf("ERROR %d", uint64(e)) 83 } 84 85 // A localTransportError is an error sent to the peer. 86 type localTransportError struct { 87 code transportError 88 reason string 89 } 90 91 func (e localTransportError) Error() string { 92 if e.reason == "" { 93 return fmt.Sprintf("closed connection: %v", e.code) 94 } 95 return fmt.Sprintf("closed connection: %v: %q", e.code, e.reason) 96 } 97 98 // A peerTransportError is an error received from the peer. 99 type peerTransportError struct { 100 code transportError 101 reason string 102 } 103 104 func (e peerTransportError) Error() string { 105 return fmt.Sprintf("peer closed connection: %v: %q", e.code, e.reason) 106 } 107 108 // A StreamErrorCode is an application protocol error code (RFC 9000, Section 20.2) 109 // indicating whay a stream is being closed. 110 type StreamErrorCode uint64 111 112 func (e StreamErrorCode) Error() string { 113 return fmt.Sprintf("stream error code %v", uint64(e)) 114 } 115 116 // An ApplicationError is an application protocol error code (RFC 9000, Section 20.2). 117 // Application protocol errors may be sent when terminating a stream or connection. 118 type ApplicationError struct { 119 Code uint64 120 Reason string 121 } 122 123 func (e *ApplicationError) Error() string { 124 // TODO: Include the Reason string here, but sanitize it first. 125 return fmt.Sprintf("AppError %v", e.Code) 126 } 127 128 // Is reports a match if err is an *ApplicationError with a matching Code. 129 func (e *ApplicationError) Is(err error) bool { 130 e2, ok := err.(*ApplicationError) 131 return ok && e2.Code == e.Code 132 }