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  }