github.com/pion/dtls/v2@v2.2.12/errors.go (about)

     1  // SPDX-FileCopyrightText: 2023 The Pion community <https://pion.ly>
     2  // SPDX-License-Identifier: MIT
     3  
     4  package dtls
     5  
     6  import (
     7  	"context"
     8  	"errors"
     9  	"fmt"
    10  	"io"
    11  	"net"
    12  	"os"
    13  
    14  	"github.com/pion/dtls/v2/pkg/protocol"
    15  	"github.com/pion/dtls/v2/pkg/protocol/alert"
    16  )
    17  
    18  // Typed errors
    19  var (
    20  	ErrConnClosed = &FatalError{Err: errors.New("conn is closed")} //nolint:goerr113
    21  
    22  	errDeadlineExceeded   = &TimeoutError{Err: fmt.Errorf("read/write timeout: %w", context.DeadlineExceeded)}
    23  	errInvalidContentType = &TemporaryError{Err: errors.New("invalid content type")} //nolint:goerr113
    24  
    25  	errBufferTooSmall               = &TemporaryError{Err: errors.New("buffer is too small")}                                        //nolint:goerr113
    26  	errContextUnsupported           = &TemporaryError{Err: errors.New("context is not supported for ExportKeyingMaterial")}          //nolint:goerr113
    27  	errHandshakeInProgress          = &TemporaryError{Err: errors.New("handshake is in progress")}                                   //nolint:goerr113
    28  	errReservedExportKeyingMaterial = &TemporaryError{Err: errors.New("ExportKeyingMaterial can not be used with a reserved label")} //nolint:goerr113
    29  	errApplicationDataEpochZero     = &TemporaryError{Err: errors.New("ApplicationData with epoch of 0")}                            //nolint:goerr113
    30  	errUnhandledContextType         = &TemporaryError{Err: errors.New("unhandled contentType")}                                      //nolint:goerr113
    31  
    32  	errCertificateVerifyNoCertificate    = &FatalError{Err: errors.New("client sent certificate verify but we have no certificate to verify")}                      //nolint:goerr113
    33  	errCipherSuiteNoIntersection         = &FatalError{Err: errors.New("client+server do not support any shared cipher suites")}                                    //nolint:goerr113
    34  	errClientCertificateNotVerified      = &FatalError{Err: errors.New("client sent certificate but did not verify it")}                                            //nolint:goerr113
    35  	errClientCertificateRequired         = &FatalError{Err: errors.New("server required client verification, but got none")}                                        //nolint:goerr113
    36  	errClientNoMatchingSRTPProfile       = &FatalError{Err: errors.New("server responded with SRTP Profile we do not support")}                                     //nolint:goerr113
    37  	errClientRequiredButNoServerEMS      = &FatalError{Err: errors.New("client required Extended Master Secret extension, but server does not support it")}         //nolint:goerr113
    38  	errCookieMismatch                    = &FatalError{Err: errors.New("client+server cookie does not match")}                                                      //nolint:goerr113
    39  	errIdentityNoPSK                     = &FatalError{Err: errors.New("PSK Identity Hint provided but PSK is nil")}                                                //nolint:goerr113
    40  	errInvalidCertificate                = &FatalError{Err: errors.New("no certificate provided")}                                                                  //nolint:goerr113
    41  	errInvalidCipherSuite                = &FatalError{Err: errors.New("invalid or unknown cipher suite")}                                                          //nolint:goerr113
    42  	errInvalidECDSASignature             = &FatalError{Err: errors.New("ECDSA signature contained zero or negative values")}                                        //nolint:goerr113
    43  	errInvalidPrivateKey                 = &FatalError{Err: errors.New("invalid private key type")}                                                                 //nolint:goerr113
    44  	errInvalidSignatureAlgorithm         = &FatalError{Err: errors.New("invalid signature algorithm")}                                                              //nolint:goerr113
    45  	errKeySignatureMismatch              = &FatalError{Err: errors.New("expected and actual key signature do not match")}                                           //nolint:goerr113
    46  	errNilNextConn                       = &FatalError{Err: errors.New("Conn can not be created with a nil nextConn")}                                              //nolint:goerr113
    47  	errNoAvailableCipherSuites           = &FatalError{Err: errors.New("connection can not be created, no CipherSuites satisfy this Config")}                       //nolint:goerr113
    48  	errNoAvailablePSKCipherSuite         = &FatalError{Err: errors.New("connection can not be created, pre-shared key present but no compatible CipherSuite")}      //nolint:goerr113
    49  	errNoAvailableCertificateCipherSuite = &FatalError{Err: errors.New("connection can not be created, certificate present but no compatible CipherSuite")}         //nolint:goerr113
    50  	errNoAvailableSignatureSchemes       = &FatalError{Err: errors.New("connection can not be created, no SignatureScheme satisfy this Config")}                    //nolint:goerr113
    51  	errNoCertificates                    = &FatalError{Err: errors.New("no certificates configured")}                                                               //nolint:goerr113
    52  	errNoConfigProvided                  = &FatalError{Err: errors.New("no config provided")}                                                                       //nolint:goerr113
    53  	errNoSupportedEllipticCurves         = &FatalError{Err: errors.New("client requested zero or more elliptic curves that are not supported by the server")}       //nolint:goerr113
    54  	errUnsupportedProtocolVersion        = &FatalError{Err: errors.New("unsupported protocol version")}                                                             //nolint:goerr113
    55  	errPSKAndIdentityMustBeSetForClient  = &FatalError{Err: errors.New("PSK and PSK Identity Hint must both be set for client")}                                    //nolint:goerr113
    56  	errRequestedButNoSRTPExtension       = &FatalError{Err: errors.New("SRTP support was requested but server did not respond with use_srtp extension")}            //nolint:goerr113
    57  	errServerNoMatchingSRTPProfile       = &FatalError{Err: errors.New("client requested SRTP but we have no matching profiles")}                                   //nolint:goerr113
    58  	errServerRequiredButNoClientEMS      = &FatalError{Err: errors.New("server requires the Extended Master Secret extension, but the client does not support it")} //nolint:goerr113
    59  	errVerifyDataMismatch                = &FatalError{Err: errors.New("expected and actual verify data does not match")}                                           //nolint:goerr113
    60  	errNotAcceptableCertificateChain     = &FatalError{Err: errors.New("certificate chain is not signed by an acceptable CA")}                                      //nolint:goerr113
    61  
    62  	errInvalidFlight                     = &InternalError{Err: errors.New("invalid flight number")}                           //nolint:goerr113
    63  	errKeySignatureGenerateUnimplemented = &InternalError{Err: errors.New("unable to generate key signature, unimplemented")} //nolint:goerr113
    64  	errKeySignatureVerifyUnimplemented   = &InternalError{Err: errors.New("unable to verify key signature, unimplemented")}   //nolint:goerr113
    65  	errLengthMismatch                    = &InternalError{Err: errors.New("data length and declared length do not match")}    //nolint:goerr113
    66  	errSequenceNumberOverflow            = &InternalError{Err: errors.New("sequence number overflow")}                        //nolint:goerr113
    67  	errInvalidFSMTransition              = &InternalError{Err: errors.New("invalid state machine transition")}                //nolint:goerr113
    68  	errFailedToAccessPoolReadBuffer      = &InternalError{Err: errors.New("failed to access pool read buffer")}               //nolint:goerr113
    69  	errFragmentBufferOverflow            = &InternalError{Err: errors.New("fragment buffer overflow")}                        //nolint:goerr113
    70  )
    71  
    72  // FatalError indicates that the DTLS connection is no longer available.
    73  // It is mainly caused by wrong configuration of server or client.
    74  type FatalError = protocol.FatalError
    75  
    76  // InternalError indicates and internal error caused by the implementation, and the DTLS connection is no longer available.
    77  // It is mainly caused by bugs or tried to use unimplemented features.
    78  type InternalError = protocol.InternalError
    79  
    80  // TemporaryError indicates that the DTLS connection is still available, but the request was failed temporary.
    81  type TemporaryError = protocol.TemporaryError
    82  
    83  // TimeoutError indicates that the request was timed out.
    84  type TimeoutError = protocol.TimeoutError
    85  
    86  // HandshakeError indicates that the handshake failed.
    87  type HandshakeError = protocol.HandshakeError
    88  
    89  // errInvalidCipherSuite indicates an attempt at using an unsupported cipher suite.
    90  type invalidCipherSuiteError struct {
    91  	id CipherSuiteID
    92  }
    93  
    94  func (e *invalidCipherSuiteError) Error() string {
    95  	return fmt.Sprintf("CipherSuite with id(%d) is not valid", e.id)
    96  }
    97  
    98  func (e *invalidCipherSuiteError) Is(err error) bool {
    99  	var other *invalidCipherSuiteError
   100  	if errors.As(err, &other) {
   101  		return e.id == other.id
   102  	}
   103  	return false
   104  }
   105  
   106  // errAlert wraps DTLS alert notification as an error
   107  type alertError struct {
   108  	*alert.Alert
   109  }
   110  
   111  func (e *alertError) Error() string {
   112  	return fmt.Sprintf("alert: %s", e.Alert.String())
   113  }
   114  
   115  func (e *alertError) IsFatalOrCloseNotify() bool {
   116  	return e.Level == alert.Fatal || e.Description == alert.CloseNotify
   117  }
   118  
   119  func (e *alertError) Is(err error) bool {
   120  	var other *alertError
   121  	if errors.As(err, &other) {
   122  		return e.Level == other.Level && e.Description == other.Description
   123  	}
   124  	return false
   125  }
   126  
   127  // netError translates an error from underlying Conn to corresponding net.Error.
   128  func netError(err error) error {
   129  	switch {
   130  	case errors.Is(err, io.EOF), errors.Is(err, context.Canceled), errors.Is(err, context.DeadlineExceeded):
   131  		// Return io.EOF and context errors as is.
   132  		return err
   133  	}
   134  
   135  	var (
   136  		ne      net.Error
   137  		opError *net.OpError
   138  		se      *os.SyscallError
   139  	)
   140  
   141  	if errors.As(err, &opError) {
   142  		if errors.As(opError, &se) {
   143  			if se.Timeout() {
   144  				return &TimeoutError{Err: err}
   145  			}
   146  			if isOpErrorTemporary(se) {
   147  				return &TemporaryError{Err: err}
   148  			}
   149  		}
   150  	}
   151  
   152  	if errors.As(err, &ne) {
   153  		return err
   154  	}
   155  
   156  	return &FatalError{Err: err}
   157  }