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
//! Public error type returned by the high-level DTLS API.
#[derive(Debug)]
#[non_exhaustive]
/// Errors returned by DTLS processing functions.
pub enum Error {
/// Unexpected DTLS message
UnexpectedMessage(String),
/// Local state was missing data required for the requested operation
InvalidState(String),
/// Cryptographic operation failed
CryptoError(String),
/// Certificate validation failed
CertificateError(String),
/// Security policy violation
SecurityError(String),
/// PSK (Pre-Shared Key) error
PskError(String),
/// Incoming queue exceeded capacity
ReceiveQueueFull,
/// Outgoing queue exceeded capacity
TransmitQueueFull,
/// Missing fields when parsing ServerHello
IncompleteServerHello,
/// Something timed out
Timeout(&'static str),
/// Configuration error (e.g., invalid crypto provider)
ConfigError(String),
/// Peer attempted renegotiation (not supported)
RenegotiationAttempt,
/// Application data cannot be sent because the handshake is not yet complete.
///
/// For auto-sense instances this means the version has not yet been
/// resolved. Callers should buffer the data and retry once the
/// handshake advances.
HandshakePending,
/// The connection has been closed (close_notify sent or received).
ConnectionClosed,
/// If we are in auto-sense mode for a server and we received too
/// many client hello fragments that haven't made a packet.
TooManyClientHelloFragments,
/// The DTLS 1.3 server received a ClientHello that does not offer
/// DTLS 1.3 in `supported_versions`. In auto-sense mode the caller
/// should fall back to a DTLS 1.2 server and replay the buffered
/// packets.
///
/// This value should never be seen outside dimpl. It's an internal
/// value to communicate from dtls13/server.rs to lib.rs
#[doc(hidden)]
Dtls12Fallback,
/// Parser requested more data
#[doc(hidden)]
ParseIncomplete,
/// Parser encountered an error kind from nom
#[doc(hidden)]
ParseError(nom::error::ErrorKind),
/// Too many records in a single packet
#[doc(hidden)]
TooManyRecords,
}
impl Error {
pub(crate) fn is_transient(&self) -> bool {
matches!(
self,
Error::ParseIncomplete | Error::ParseError(_) | Error::TooManyRecords
)
}
}
impl<'a> From<nom::Err<nom::error::Error<&'a [u8]>>> for Error {
fn from(value: nom::Err<nom::error::Error<&'a [u8]>>) -> Self {
match value {
nom::Err::Incomplete(_) => Error::ParseIncomplete,
nom::Err::Error(x) => Error::ParseError(x.code),
nom::Err::Failure(x) => Error::ParseError(x.code),
}
}
}
impl std::error::Error for Error {}
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Error::UnexpectedMessage(msg) => write!(f, "unexpected message: {}", msg),
Error::InvalidState(msg) => write!(f, "invalid state: {}", msg),
Error::CryptoError(msg) => write!(f, "crypto error: {}", msg),
Error::CertificateError(msg) => write!(f, "certificate error: {}", msg),
Error::SecurityError(msg) => write!(f, "security error: {}", msg),
Error::PskError(msg) => write!(f, "psk error: {}", msg),
Error::ReceiveQueueFull => write!(f, "receive queue full"),
Error::TransmitQueueFull => write!(f, "transmit queue full"),
Error::IncompleteServerHello => write!(f, "incomplete ServerHello"),
Error::Timeout(what) => write!(f, "timeout: {}", what),
Error::ConfigError(msg) => write!(f, "config error: {}", msg),
Error::RenegotiationAttempt => write!(f, "peer attempted renegotiation"),
Error::HandshakePending => {
write!(f, "handshake pending: cannot send application data yet")
}
Error::TooManyClientHelloFragments => write!(f, "too many client hello fragments"),
Error::ConnectionClosed => write!(f, "connection closed"),
Error::Dtls12Fallback => {
write!(f, "dtls 1.2 fallback (internal)")
}
Error::ParseIncomplete => write!(f, "parse incomplete"),
Error::ParseError(kind) => write!(f, "parse error: {:?}", kind),
Error::TooManyRecords => write!(f, "too many records in packet"),
}
}
}