1use std::{sync::Arc, time::Duration};
3use thiserror::Error;
4use tor_cell::relaycell::{msg::EndReason, StreamId};
5use tor_error::{Bug, ErrorKind, HasKind};
6use tor_linkspec::RelayIdType;
7
8#[derive(Error, Debug, Clone)]
14#[non_exhaustive]
15pub enum Error {
16 #[error("Unable to parse {object}")]
19 BytesErr {
20 object: &'static str,
22 #[source]
24 err: tor_bytes::Error,
25 },
26 #[error("IO error on channel with peer")]
29 ChanIoErr(#[source] Arc<std::io::Error>),
30 #[error("IO error while handshaking with peer")]
32 HandshakeIoErr(#[source] Arc<std::io::Error>),
33 #[error("Unable to generate or encode {object}")]
35 CellEncodeErr {
36 object: &'static str,
38 #[source]
40 err: tor_cell::Error,
41 },
42 #[error("Error while parsing {object}")]
44 CellDecodeErr {
45 object: &'static str,
47 #[source]
49 err: tor_cell::Error,
50 },
51 #[error("Problem while encoding {object}")]
57 EncodeErr {
58 object: &'static str,
60 #[source]
62 err: tor_bytes::EncodeError,
63 },
64 #[error("Problem with certificate on handshake")]
67 HandshakeCertErr(#[source] tor_cert::CertError),
68 #[error("Tried to extract too many bytes from a KDF")]
70 InvalidKDFOutputLength,
71 #[error("Tried to encrypt a cell for a nonexistent hop")]
73 NoSuchHop,
74 #[error("Bad relay cell authentication")]
77 BadCellAuth,
78 #[error("Circuit-extension handshake authentication failed")]
81 BadCircHandshakeAuth,
82 #[error("Handshake protocol violation: {0}")]
84 HandshakeProto(String),
85 #[error("Handshake failed due to expired certificates (possible clock skew)")]
90 HandshakeCertsExpired {
91 expired_by: Duration,
93 },
94 #[error("Channel protocol violation: {0}")]
97 ChanProto(String),
98 #[error("Circuit protocol violation: {0}")]
100 CircProto(String),
101 #[error("Channel closed")]
104 ChannelClosed(#[from] ChannelClosed),
105 #[error("Circuit closed")]
108 CircuitClosed,
109 #[error("Too many entries in map: can't allocate ID")]
111 IdRangeFull,
112 #[error("Stream ID {0} is already in use")]
114 IdUnavailable(StreamId),
115 #[error("Received a cell with a stream ID of zero")]
117 StreamIdZero,
118 #[error("Circuit extension refused: {0}")]
121 CircRefused(&'static str),
122 #[error("Invalid stream target address")]
124 BadStreamAddress,
125 #[error("Received an END cell with reason {0}")]
127 EndReceived(EndReason),
128 #[error("Stream not connected")]
130 NotConnected,
131 #[error("Stream protocol violation: {0}")]
133 StreamProto(String),
134
135 #[error("Received too many inbound cells")]
137 ExcessInboundCells,
138 #[error("Tried to send too many outbound cells")]
140 ExcessOutboundCells,
141
142 #[error("Peer identity mismatch: {0}")]
144 ChanMismatch(String),
145 #[error("Programming error")]
147 Bug(#[from] tor_error::Bug),
148 #[error("Remote resolve failed")]
150 ResolveError(#[source] ResolveError),
151 #[error("Relay has no {0} identity")]
154 MissingId(RelayIdType),
155 #[error("memory quota error")]
157 Memquota(#[from] tor_memquota::Error),
158}
159
160#[derive(Error, Debug, Clone)]
162#[error("Channel closed")]
163pub struct ChannelClosed;
164
165impl HasKind for ChannelClosed {
166 fn kind(&self) -> ErrorKind {
167 ErrorKind::CircuitCollapse
168 }
169}
170
171#[derive(Error, Debug, Clone)]
173#[non_exhaustive]
174pub enum ResolveError {
175 #[error("Received retriable transient error")]
177 Transient,
178 #[error("Received non-retriable error")]
180 Nontransient,
181 #[error("Received unrecognized result")]
183 Unrecognized,
184}
185
186impl Error {
187 pub(crate) fn from_cell_enc(err: tor_cell::Error, object: &'static str) -> Error {
190 Error::CellEncodeErr { object, err }
191 }
192
193 pub(crate) fn from_cell_dec(err: tor_cell::Error, object: &'static str) -> Error {
196 match err {
197 tor_cell::Error::ChanProto(msg) => Error::ChanProto(msg),
198 _ => Error::CellDecodeErr { err, object },
199 }
200 }
201
202 pub(crate) fn from_bytes_err(err: tor_bytes::Error, object: &'static str) -> Error {
205 Error::BytesErr { err, object }
206 }
207
208 pub(crate) fn from_bytes_enc(err: tor_bytes::EncodeError, object: &'static str) -> Error {
211 Error::EncodeErr { err, object }
212 }
213}
214
215impl From<Error> for std::io::Error {
216 fn from(err: Error) -> std::io::Error {
217 use std::io::ErrorKind;
218 use Error::*;
219 let kind = match err {
220 ChanIoErr(e) | HandshakeIoErr(e) => match Arc::try_unwrap(e) {
221 Ok(e) => return e,
222 Err(arc) => return std::io::Error::new(arc.kind(), arc),
223 },
224
225 InvalidKDFOutputLength | NoSuchHop | BadStreamAddress => ErrorKind::InvalidInput,
226
227 NotConnected => ErrorKind::NotConnected,
228
229 EndReceived(end_reason) => end_reason.into(),
230
231 CircuitClosed => ErrorKind::ConnectionReset,
232
233 Memquota { .. } => ErrorKind::OutOfMemory,
234
235 BytesErr { .. }
236 | BadCellAuth
237 | BadCircHandshakeAuth
238 | HandshakeProto(_)
239 | HandshakeCertErr(_)
240 | ChanProto(_)
241 | HandshakeCertsExpired { .. }
242 | ChannelClosed(_)
243 | CircProto(_)
244 | CellDecodeErr { .. }
245 | CellEncodeErr { .. }
246 | EncodeErr { .. }
247 | ChanMismatch(_)
248 | StreamProto(_)
249 | MissingId(_)
250 | IdUnavailable(_)
251 | StreamIdZero
252 | ExcessInboundCells
253 | ExcessOutboundCells => ErrorKind::InvalidData,
254
255 Bug(ref e) if e.kind() == tor_error::ErrorKind::BadApiUsage => ErrorKind::InvalidData,
256
257 IdRangeFull | CircRefused(_) | ResolveError(_) | Bug(_) => ErrorKind::Other,
258 };
259 std::io::Error::new(kind, err)
260 }
261}
262
263impl HasKind for Error {
264 fn kind(&self) -> ErrorKind {
265 use tor_bytes::Error as BytesError;
266 use Error as E;
267 use ErrorKind as EK;
268 match self {
269 E::BytesErr {
270 err: BytesError::Bug(e),
271 ..
272 } => e.kind(),
273 E::BytesErr { .. } => EK::TorProtocolViolation,
274 E::ChanIoErr(_) => EK::LocalNetworkError,
275 E::HandshakeIoErr(_) => EK::TorAccessFailed,
276 E::HandshakeCertErr(_) => EK::TorProtocolViolation,
277 E::CellEncodeErr { err, .. } => err.kind(),
278 E::CellDecodeErr { err, .. } => err.kind(),
279 E::EncodeErr { .. } => EK::BadApiUsage,
280 E::InvalidKDFOutputLength => EK::Internal,
281 E::NoSuchHop => EK::BadApiUsage,
282 E::BadCellAuth => EK::TorProtocolViolation,
283 E::BadCircHandshakeAuth => EK::TorProtocolViolation,
284 E::HandshakeProto(_) => EK::TorAccessFailed,
285 E::HandshakeCertsExpired { .. } => EK::ClockSkew,
286 E::ChanProto(_) => EK::TorProtocolViolation,
287 E::CircProto(_) => EK::TorProtocolViolation,
288 E::ChannelClosed(e) => e.kind(),
289 E::CircuitClosed => EK::CircuitCollapse,
290 E::IdRangeFull => EK::BadApiUsage,
291 E::CircRefused(_) => EK::CircuitRefused,
292 E::BadStreamAddress => EK::BadApiUsage,
293 E::EndReceived(reason) => reason.kind(),
294 E::NotConnected => EK::BadApiUsage,
295 E::StreamProto(_) => EK::TorProtocolViolation,
296 E::ChanMismatch(_) => EK::RelayIdMismatch,
297 E::ResolveError(ResolveError::Nontransient) => EK::RemoteHostNotFound,
298 E::ResolveError(ResolveError::Transient) => EK::RemoteHostResolutionFailed,
299 E::ResolveError(ResolveError::Unrecognized) => EK::RemoteHostResolutionFailed,
300 E::MissingId(_) => EK::BadApiUsage,
301 E::IdUnavailable(_) => EK::BadApiUsage,
302 E::StreamIdZero => EK::BadApiUsage,
303 E::ExcessInboundCells => EK::TorProtocolViolation,
304 E::ExcessOutboundCells => EK::Internal,
305 E::Memquota(err) => err.kind(),
306 E::Bug(e) => e.kind(),
307 }
308 }
309}
310
311#[derive(Debug)]
314pub(crate) enum ReactorError {
315 Err(Error),
317 Shutdown,
319}
320
321impl From<Error> for ReactorError {
322 fn from(e: Error) -> ReactorError {
323 ReactorError::Err(e)
324 }
325}
326
327impl From<ChannelClosed> for ReactorError {
328 fn from(e: ChannelClosed) -> ReactorError {
329 ReactorError::Err(e.into())
330 }
331}
332
333impl From<Bug> for ReactorError {
334 fn from(e: Bug) -> ReactorError {
335 ReactorError::Err(e.into())
336 }
337}
338
339#[cfg(test)]
340impl ReactorError {
341 pub(crate) fn unwrap_err(self) -> Error {
343 match self {
344 ReactorError::Shutdown => panic!(),
345 ReactorError::Err(e) => e,
346 }
347 }
348}
349
350#[derive(Debug)]
352#[cfg(feature = "conflux")]
353#[allow(unused)] pub(crate) enum ConfluxHandshakeError {
355 Timeout,
357 Link(Error),
359 ChannelClosed,
361}