1use serde::Serialize;
30use serde::Serializer;
31
32use crate::quic;
33use crate::BoxError;
34
35#[derive(Clone, Eq, Hash, PartialEq, Serialize)]
37#[serde(rename_all = "lowercase")]
38pub enum QuicHandshakeStage {
39 QueueWaiting,
42 HandshakeProtocol,
46 HandshakeResponse,
51}
52
53#[derive(Clone, Eq, Hash, PartialEq, Serialize)]
55#[serde(rename_all = "lowercase")]
56pub enum QuicWriteError {
57 Err,
58 Partial,
59 WouldBlock,
60}
61
62#[derive(Clone, Eq, Hash, PartialEq, Serialize)]
64#[serde(rename_all = "lowercase")]
65pub enum HandshakeError {
66 CryptoFail,
67 TlsFail,
68 Timeout,
69 Disconnect,
70 Other,
71}
72
73impl From<&quiche::Error> for HandshakeError {
74 fn from(err: &quiche::Error) -> Self {
75 match err {
76 quiche::Error::CryptoFail => Self::CryptoFail,
77 quiche::Error::TlsFail => Self::TlsFail,
78 _ => Self::Other,
79 }
80 }
81}
82
83impl From<&quic::HandshakeError> for HandshakeError {
84 fn from(err: &quic::HandshakeError) -> Self {
85 match err {
86 quic::HandshakeError::Timeout => Self::Timeout,
87 quic::HandshakeError::ConnectionClosed => Self::Disconnect,
88 }
89 }
90}
91
92impl From<&BoxError> for HandshakeError {
93 fn from(err: &BoxError) -> Self {
94 if let Some(e) = err.downcast_ref::<quic::HandshakeError>() {
95 Self::from(e)
96 } else if let Some(e) = err.downcast_ref::<quiche::Error>() {
97 Self::from(e)
98 } else {
99 Self::Other
100 }
101 }
102}
103
104#[derive(Clone, Debug, Eq, PartialEq)]
106pub enum QuicInvalidInitialPacketError {
107 TokenValidationFail,
108 FailedToParse,
109 WrongType(quiche::Type),
110 AcceptQueueOverflow,
111 Unexpected,
112}
113
114impl std::fmt::Display for QuicInvalidInitialPacketError {
115 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
116 match self {
117 Self::FailedToParse => f.write_str("failed to parse packet"),
118 Self::TokenValidationFail => f.write_str("token validation fail"),
119 Self::WrongType(ty) => write!(f, "wrong type: {ty:?}"),
120 Self::AcceptQueueOverflow => f.write_str("accept queue overflow"),
121 Self::Unexpected => f.write_str("unexpected error"),
122 }
123 }
124}
125
126impl Serialize for QuicInvalidInitialPacketError {
127 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
128 serializer.collect_str(self)
129 }
130}
131
132impl std::hash::Hash for QuicInvalidInitialPacketError {
133 fn hash<H>(&self, state: &mut H)
134 where
135 H: std::hash::Hasher,
136 {
137 std::mem::discriminant(self).hash(state);
138 if let Self::WrongType(ty) = self {
139 std::mem::discriminant(ty).hash(state);
140 }
141 }
142}
143
144impl std::error::Error for QuicInvalidInitialPacketError {}
145
146impl From<QuicInvalidInitialPacketError> for std::io::Error {
147 fn from(e: QuicInvalidInitialPacketError) -> Self {
148 std::io::Error::other(e)
149 }
150}
151
152#[derive(Clone, Eq, Hash, PartialEq)]
154pub struct H3Error(u64);
155
156impl Serialize for H3Error {
157 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
158 let code = self.0;
159
160 let v = if code > 0x21 && (code - 0x21) % 0x1f == 0 {
162 "H3_GREASE"
163 } else {
164 match code {
165 0x33 => "H3_DATAGRAM_ERROR",
166
167 0x100 => "H3_NO_ERROR",
168 0x101 => "H3_GENERAL_PROTOCOL_ERROR",
169 0x102 => "H3_INTERNAL_ERROR",
170 0x103 => "H3_STREAM_CREATION_ERROR",
171 0x104 => "H3_CLOSED_CRITICAL_STREAM",
172 0x105 => "H3_FRAME_UNEXPECTED",
173 0x106 => "H3_FRAME_ERROR",
174 0x107 => "H3_EXCESSIVE_LOAD",
175 0x108 => "H3_ID_ERROR",
176 0x109 => "H3_SETTINGS_ERROR",
177 0x10a => "H3_MISSING_SETTINGS",
178 0x10b => "H3_REQUEST_REJECTED",
179 0x10c => "H3_REQUEST_CANCELLED",
180 0x10d => "H3_REQUEST_INCOMPLETE",
181 0x10e => "H3_MESSAGE_ERROR",
182 0x10f => "H3_CONNECT_ERROR",
183 0x110 => "H3_VERSION_FALLBACK",
184
185 0x200 => "QPACK_DECOMPRESSION_FAILED",
186 0x201 => "QPACK_ENCODER_STREAM_ERROR",
187 0x202 => "QPACK_DECODER_STREAM_ERROR",
188
189 _ => "H3_UNKNOWN",
190 }
191 };
192 serializer.serialize_str(v)
193 }
194}
195
196impl From<u64> for H3Error {
197 fn from(code: u64) -> Self {
198 Self(code)
199 }
200}
201
202#[derive(Clone, Eq, Hash, PartialEq)]
204pub struct QuicError(u64);
205
206impl Serialize for QuicError {
207 fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
208 let v = match self.0 {
210 0x0 => "NO_ERROR",
211 0x1 => "INTERNAL_ERROR",
212 0x2 => "CONNECTION_REFUSED",
213 0x3 => "FLOW_CONTROL_ERROR",
214 0x4 => "STREAM_LIMIT_ERROR",
215 0x5 => "STREAM_STATE_ERROR",
216 0x6 => "FINAL_SIZE_ERROR",
217 0x7 => "FRAME_ENCODING_ERROR",
218 0x8 => "TRANSPORT_PARAMETER_ERROR",
219 0x9 => "CONNECTION_ID_LIMIT_ERROR",
220 0xa => "PROTOCOL_VIOLATION",
221 0xb => "INVALID_TOKEN",
222 0xc => "APPLICATION_ERROR",
223 0xd => "CRYPTO_BUFFER_EXCEEDED",
224 0xe => "KEY_UPDATE_ERROR",
225 0xf => "AEAD_LIMIT_REACHED",
226 0x10 => "NO_VIABLE_PATH",
227 0x11 => "VERSION_NEGOTIATION_ERROR",
228 0x100..=0x1ff => "CRYPTO_ERROR",
229
230 _ => "QUIC_UNKNOWN",
231 };
232 serializer.serialize_str(v)
233 }
234}
235
236impl From<u64> for QuicError {
237 fn from(code: u64) -> Self {
238 Self(code)
239 }
240}