err.rs
1 //! Declare an error type for tor_socksproto 2 use std::borrow::Cow; 3 4 use thiserror::Error; 5 6 use tor_error::{ErrorKind, HasKind}; 7 8 /// An error that occurs while negotiating a SOCKS handshake. 9 #[derive(Clone, Error, Debug)] 10 #[non_exhaustive] 11 pub enum Error { 12 /// The SOCKS client didn't implement SOCKS correctly. 13 /// 14 /// (Or, more likely, we didn't account for its behavior.) 15 #[error("SOCKS protocol syntax violation")] 16 Syntax, 17 18 /// Failed to decode a SOCKS message. 19 #[error("Error decoding SOCKS message")] 20 Decode(#[from] tor_bytes::Error), 21 22 /// The SOCKS client declared a SOCKS version number that isn't 23 /// one we support. 24 /// 25 /// In all likelihood, this is somebody trying to use the port for 26 /// some protocol other than SOCKS. 27 #[error("Unrecognized SOCKS protocol version {0}")] 28 BadProtocol(u8), 29 30 /// The SOCKS client tried to use a SOCKS feature that we don't 31 /// support at all. 32 #[error("SOCKS feature ({0}) not implemented")] 33 NotImplemented(Cow<'static, str>), 34 35 /// Tried to progress the SOCKS handshake when it was already 36 /// finished. This is a programming error. 37 #[error("SOCKS handshake was finished; no need to call this again")] 38 AlreadyFinished(tor_error::Bug), 39 40 /// The SOCKS proxy refused our authentication. 41 #[error("SOCKS Authentication failed")] 42 AuthRejected, 43 44 /// During the protocol exchange, we needed to handle a handshake bigger than our buffer 45 #[error("SOCKS protocol message size limit {limit} exceeded")] 46 MessageTooLong { 47 /// The limit in bytes 48 limit: usize, 49 }, 50 51 /// Peer closed connection during SOCKS handshake 52 #[error("peer closed connection during SOCKS handshake")] 53 UnexpectedEof, 54 55 /// The peer sent payload data too early 56 /// 57 /// The peer sent data after its part of the protocol exchange, 58 /// without waiting for our side of it to complete, 59 /// in circumstances where we consider that a protocol violation by the peer. 60 /// 61 /// Returned only by 62 /// [`Finished::into_output_forbid_pipelining`](crate::Finished::into_output_forbid_pipelining). 63 #[error("SOCKS peer inappropriately pipelined (optimistically sent) payload data")] 64 ForbiddenPipelining, 65 66 /// The program (perhaps this module, perhaps Arti, perhaps the caller) is buggy 67 #[error("Bug while handling SOCKS handshake")] 68 Bug(#[from] tor_error::Bug), 69 } 70 71 // Note: at present, tor-socksproto isn't used in any settings where ErrorKind 72 // is used. This is provided for future-proofing, since someday we'll want to 73 // have SOCKS protocol support internally as well as in the `arti` proxy. 74 impl HasKind for Error { 75 fn kind(&self) -> ErrorKind { 76 use Error as E; 77 use ErrorKind as EK; 78 match self { 79 E::Decode(tor_bytes::Error::Incomplete { .. }) => { 80 // This variant should always get converted before a user can 81 // see it. 82 EK::Internal 83 } 84 E::Syntax | E::Decode(_) | E::BadProtocol(_) => EK::LocalProtocolViolation, 85 E::NotImplemented(_) => EK::NotImplemented, 86 E::AuthRejected => EK::LocalProtocolViolation, 87 E::UnexpectedEof => EK::LocalProtocolViolation, 88 E::ForbiddenPipelining => EK::LocalProtocolViolation, 89 E::MessageTooLong { .. } => EK::Internal, // We should select a buffer big enough! 90 E::AlreadyFinished(e) => e.kind(), 91 E::Bug(e) => e.kind(), 92 } 93 } 94 }