forked from pion/dtls
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy patherrors.go
More file actions
229 lines (189 loc) · 10.5 KB
/
errors.go
File metadata and controls
229 lines (189 loc) · 10.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
package dtls
import (
"context"
"errors"
"fmt"
"io"
"net"
"os"
"golang.org/x/xerrors"
)
// Typed errors
var (
ErrConnClosed = &FatalError{errors.New("conn is closed")}
errDeadlineExceeded = &TimeoutError{xerrors.Errorf("read/write timeout: %w", context.DeadlineExceeded)}
errBufferTooSmall = &TemporaryError{errors.New("buffer is too small")}
errContextUnsupported = &TemporaryError{errors.New("context is not supported for ExportKeyingMaterial")}
errDTLSPacketInvalidLength = &TemporaryError{errors.New("packet is too short")}
errHandshakeInProgress = &TemporaryError{errors.New("handshake is in progress")}
errInvalidContentType = &TemporaryError{errors.New("invalid content type")}
errInvalidMAC = &TemporaryError{errors.New("invalid mac")}
errInvalidPacketLength = &TemporaryError{errors.New("packet length and declared length do not match")}
errReservedExportKeyingMaterial = &TemporaryError{errors.New("ExportKeyingMaterial can not be used with a reserved label")}
errCertificateVerifyNoCertificate = &FatalError{errors.New("client sent certificate verify but we have no certificate to verify")}
errCipherSuiteNoIntersection = &FatalError{errors.New("client+server do not support any shared cipher suites")}
errCipherSuiteUnset = &FatalError{errors.New("server hello can not be created without a cipher suite")}
errClientCertificateNotVerified = &FatalError{errors.New("client sent certificate but did not verify it")}
errClientCertificateRequired = &FatalError{errors.New("server required client verification, but got none")}
errClientNoMatchingSRTPProfile = &FatalError{errors.New("server responded with SRTP Profile we do not support")}
errClientRequiredButNoServerEMS = &FatalError{errors.New("client required Extended Master Secret extension, but server does not support it")}
errCompressionMethodUnset = &FatalError{errors.New("server hello can not be created without a compression method")}
errCookieMismatch = &FatalError{errors.New("client+server cookie does not match")}
errCookieTooLong = &FatalError{errors.New("cookie must not be longer then 255 bytes")}
errIdentityNoPSK = &FatalError{errors.New("PSK Identity Hint provided but PSK is nil")}
errInvalidCertificate = &FatalError{errors.New("no certificate provided")}
errInvalidCipherSpec = &FatalError{errors.New("cipher spec invalid")}
errInvalidCipherSuite = &FatalError{errors.New("invalid or unknown cipher suite")}
errInvalidClientKeyExchange = &FatalError{errors.New("unable to determine if ClientKeyExchange is a public key or PSK Identity")}
errInvalidCompressionMethod = &FatalError{errors.New("invalid or unknown compression method")}
errInvalidECDSASignature = &FatalError{errors.New("ECDSA signature contained zero or negative values")}
errInvalidEllipticCurveType = &FatalError{errors.New("invalid or unknown elliptic curve type")}
errInvalidExtensionType = &FatalError{errors.New("invalid extension type")}
errInvalidHashAlgorithm = &FatalError{errors.New("invalid hash algorithm")}
errInvalidNamedCurve = &FatalError{errors.New("invalid named curve")}
errInvalidPrivateKey = &FatalError{errors.New("invalid private key type")}
errInvalidSNIFormat = &FatalError{errors.New("invalid server name format")}
errInvalidSignatureAlgorithm = &FatalError{errors.New("invalid signature algorithm")}
errKeySignatureMismatch = &FatalError{errors.New("expected and actual key signature do not match")}
errNilNextConn = &FatalError{errors.New("Conn can not be created with a nil nextConn")}
errNoAvailableCipherSuites = &FatalError{errors.New("connection can not be created, no CipherSuites satisfy this Config")}
errNoAvailableSignatureSchemes = &FatalError{errors.New("connection can not be created, no SignatureScheme satisfy this Config")}
errNoCertificates = &FatalError{errors.New("no certificates configured")}
errNoConfigProvided = &FatalError{errors.New("no config provided")}
errNoSupportedEllipticCurves = &FatalError{errors.New("client requested zero or more elliptic curves that are not supported by the server")}
errUnsupportedProtocolVersion = &FatalError{errors.New("unsupported protocol version")}
errPSKAndCertificate = &FatalError{errors.New("Certificate and PSK provided")} // nolint:stylecheck
errPSKAndIdentityMustBeSetForClient = &FatalError{errors.New("PSK and PSK Identity Hint must both be set for client")}
errRequestedButNoSRTPExtension = &FatalError{errors.New("SRTP support was requested but server did not respond with use_srtp extension")}
errServerMustHaveCertificate = &FatalError{errors.New("Certificate is mandatory for server")} // nolint:stylecheck
errServerNoMatchingSRTPProfile = &FatalError{errors.New("client requested SRTP but we have no matching profiles")}
errServerRequiredButNoClientEMS = &FatalError{errors.New("server requires the Extended Master Secret extension, but the client does not support it")}
errVerifyDataMismatch = &FatalError{errors.New("expected and actual verify data does not match")}
errHandshakeMessageUnset = &InternalError{errors.New("handshake message unset, unable to marshal")}
errInvalidFlight = &InternalError{errors.New("invalid flight number")}
errKeySignatureGenerateUnimplemented = &InternalError{errors.New("unable to generate key signature, unimplemented")}
errKeySignatureVerifyUnimplemented = &InternalError{errors.New("unable to verify key signature, unimplemented")}
errLengthMismatch = &InternalError{errors.New("data length and declared length do not match")}
errNotEnoughRoomForNonce = &InternalError{errors.New("buffer not long enough to contain nonce")}
errNotImplemented = &InternalError{errors.New("feature has not been implemented yet")}
errSequenceNumberOverflow = &InternalError{errors.New("sequence number overflow")}
errUnableToMarshalFragmented = &InternalError{errors.New("unable to marshal fragmented handshakes")}
)
// FatalError indicates that the DTLS connection is no longer available.
// It is mainly caused by wrong configuration of server or client.
type FatalError struct {
Err error
}
// InternalError indicates and internal error caused by the implementation, and the DTLS connection is no longer available.
// It is mainly caused by bugs or tried to use unimplemented features.
type InternalError struct {
Err error
}
// TemporaryError indicates that the DTLS connection is still available, but the request was failed temporary.
type TemporaryError struct {
Err error
}
// TimeoutError indicates that the request was timed out.
type TimeoutError struct {
Err error
}
// HandshakeError indicates that the handshake failed.
type HandshakeError struct {
Err error
}
// invalidCipherSuite indicates an attempt at using an unsupported cipher suite.
type invalidCipherSuite struct {
id CipherSuiteID
}
func (e *invalidCipherSuite) Error() string {
return fmt.Sprintf("CipherSuite with id(%d) is not valid", e.id)
}
func (e *invalidCipherSuite) Is(err error) bool {
if other, ok := err.(*invalidCipherSuite); ok {
return e.id == other.id
}
return false
}
// Timeout implements net.Error.Timeout()
func (*FatalError) Timeout() bool { return false }
// Temporary implements net.Error.Temporary()
func (*FatalError) Temporary() bool { return false }
// Unwrap implements Go1.13 error unwrapper.
func (e *FatalError) Unwrap() error { return e.Err }
func (e *FatalError) Error() string { return fmt.Sprintf("dtls fatal: %v", e.Err) }
// Timeout implements net.Error.Timeout()
func (*InternalError) Timeout() bool { return false }
// Temporary implements net.Error.Temporary()
func (*InternalError) Temporary() bool { return false }
// Unwrap implements Go1.13 error unwrapper.
func (e *InternalError) Unwrap() error { return e.Err }
func (e *InternalError) Error() string { return fmt.Sprintf("dtls internal: %v", e.Err) }
// Timeout implements net.Error.Timeout()
func (*TemporaryError) Timeout() bool { return false }
// Temporary implements net.Error.Temporary()
func (*TemporaryError) Temporary() bool { return true }
// Unwrap implements Go1.13 error unwrapper.
func (e *TemporaryError) Unwrap() error { return e.Err }
func (e *TemporaryError) Error() string { return fmt.Sprintf("dtls temporary: %v", e.Err) }
// Timeout implements net.Error.Timeout()
func (*TimeoutError) Timeout() bool { return true }
// Temporary implements net.Error.Temporary()
func (*TimeoutError) Temporary() bool { return true }
// Unwrap implements Go1.13 error unwrapper.
func (e *TimeoutError) Unwrap() error { return e.Err }
func (e *TimeoutError) Error() string { return fmt.Sprintf("dtls timeout: %v", e.Err) }
// Timeout implements net.Error.Timeout()
func (e *HandshakeError) Timeout() bool {
if netErr, ok := e.Err.(net.Error); ok {
return netErr.Timeout()
}
return false
}
// Temporary implements net.Error.Temporary()
func (e *HandshakeError) Temporary() bool {
if netErr, ok := e.Err.(net.Error); ok {
return netErr.Temporary()
}
return false
}
// Unwrap implements Go1.13 error unwrapper.
func (e *HandshakeError) Unwrap() error { return e.Err }
func (e *HandshakeError) Error() string { return fmt.Sprintf("handshake error: %v", e.Err) }
// errAlert wraps DTLS alert notification as an error
type errAlert struct {
*alert
}
func (e *errAlert) Error() string {
return fmt.Sprintf("alert: %s", e.alert.String())
}
func (e *errAlert) IsFatalOrCloseNotify() bool {
return e.alertLevel == alertLevelFatal || e.alertDescription == alertCloseNotify
}
func (e *errAlert) Is(err error) bool {
if other, ok := err.(*errAlert); ok {
return e.alertLevel == other.alertLevel && e.alertDescription == other.alertDescription
}
return false
}
// netError translates an error from underlying Conn to corresponding net.Error.
func netError(err error) error {
switch err {
case io.EOF, context.Canceled, context.DeadlineExceeded:
// Return io.EOF and context errors as is.
return err
}
switch e := err.(type) {
case (*net.OpError):
if se, ok := e.Err.(*os.SyscallError); ok {
if se.Timeout() {
return &TimeoutError{err}
}
if isOpErrorTemporary(se) {
return &TemporaryError{err}
}
}
case (net.Error):
return err
}
return &FatalError{err}
}