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