1
//! Declare an error type for tor_socksproto
2
use thiserror::Error;
3

            
4
use tor_error::{ErrorKind, HasKind};
5

            
6
/// An error that occurs while negotiating a SOCKS handshake.
7
#[derive(Error, Debug)]
8
#[non_exhaustive]
9
pub enum Error {
10
    /// The SOCKS client didn't implement SOCKS correctly.
11
    ///
12
    /// (Or, more likely, we didn't account for its behavior.)
13
    #[error("SOCKS protocol syntax violation")]
14
    Syntax,
15

            
16
    /// Failed to decode a SOCKS message.
17
    #[error("Error decoding message")]
18
    Decode(#[from] tor_bytes::Error),
19

            
20
    /// The SOCKS client declared a SOCKS version number that isn't
21
    /// one we support.
22
    ///
23
    /// In all likelihood, this is somebody trying to use the port for
24
    /// some protocol other than SOCKS.
25
    #[error("Unrecognized SOCKS protocol version {0}")]
26
    BadProtocol(u8),
27

            
28
    /// The SOCKS client tried to use a SOCKS feature that we don't
29
    /// support at all.
30
    #[error("SOCKS feature not implemented")]
31
    NotImplemented,
32

            
33
    /// Tried to progress the SOCKS handshake when it was already
34
    /// finished.  This is a programming error.
35
    #[error("SOCKS handshake was finished; no need to call this again")]
36
    AlreadyFinished(tor_error::Bug),
37

            
38
    /// The program (perhaps this module, perhaps Arti, perhaps the caller) is buggy
39
    #[error("Bug while handling SOCKS handshake")]
40
    Bug(#[from] tor_error::Bug),
41
}
42

            
43
// Note: at present, tor-socksproto isn't used in any settings where ErrorKind
44
// is used.  This is provided for future-proofing, since someday we'll want to
45
// have SOCKS protocol support internally as well as in the `arti` proxy.
46
impl HasKind for Error {
47
    fn kind(&self) -> ErrorKind {
48
        use Error as E;
49
        use ErrorKind as EK;
50
        match self {
51
            E::Decode(tor_bytes::Error::Truncated) => {
52
                // This variant should always get converted before a user can
53
                // see it.
54
                EK::Internal
55
            }
56
            E::Syntax | E::Decode(_) | E::BadProtocol(_) => EK::LocalProtocolViolation,
57
            E::NotImplemented => EK::NotImplemented,
58
            E::AlreadyFinished(e) => e.kind(),
59
            E::Bug(e) => e.kind(),
60
        }
61
    }
62
}