gatekeeper/model/
error.rs

1#![allow(non_local_definitions)]
2use std::fmt;
3use std::sync;
4
5use thiserror::Error;
6
7use crate::model::*;
8
9pub type Result<T> = ::std::result::Result<T, Error>;
10
11#[derive(Error, Debug)]
12pub enum Error {
13    #[error("io error: {0}")]
14    Io(#[from] std::io::Error),
15    #[error("poisoned error: {0}")]
16    Poisoned(String),
17    #[error("disconnected channel error: {name}")]
18    Disconnected { name: String },
19    #[error("message format error: {message}")]
20    MessageFormat { message: String },
21    #[error("authentication error: general")]
22    Authentication,
23    #[error("authentication error: no acceptable method")]
24    NoAcceptableMethod,
25    #[error("authentication error: unrecognized username/password")]
26    UnrecognizedUsernamePassword,
27    #[error("command not supported: {cmd:?}")]
28    CommandNotSupported { cmd: Command },
29    #[error("host unreachable: {host}:{port}")]
30    HostUnreachable { host: String, port: u16 },
31    #[error("name not resolved: {domain}:{port}")]
32    DomainNotResolved { domain: String, port: u16 },
33    #[error("packet size limit exceeded: {size} > {limit}")]
34    PacketSizeLimitExceeded { size: usize, limit: usize },
35    #[error("address already in use: {addr}")]
36    AddressAlreadInUse { addr: SocketAddr },
37    #[error("address not available: {addr}")]
38    AddressNotAvailable { addr: SocketAddr },
39    /// rejected by gatekeeper
40    #[error("connection not allowed: {addr}: {protocol}")]
41    ConnectionNotAllowed { addr: Address, protocol: L4Protocol },
42    /// rejected by external server
43    #[error("connection refused: {addr}: {protocol}")]
44    ConnectionRefused { addr: Address, protocol: L4Protocol },
45    #[error(transparent)]
46    Unknown(#[from] anyhow::Error),
47}
48
49impl Error {
50    pub fn disconnected<S: Into<String>>(name: S) -> Self {
51        Error::Disconnected { name: name.into() }
52    }
53
54    pub fn message_fmt(message: fmt::Arguments) -> Self {
55        Error::MessageFormat {
56            message: message.to_string(),
57        }
58    }
59
60    pub fn command_not_supported(cmd: Command) -> Self {
61        Error::CommandNotSupported { cmd }
62    }
63
64    pub fn connection_not_allowed(addr: Address, protocol: L4Protocol) -> Self {
65        Error::ConnectionNotAllowed { addr, protocol }
66    }
67
68    pub fn connection_refused(addr: Address, protocol: L4Protocol) -> Self {
69        Error::ConnectionRefused { addr, protocol }
70    }
71}
72
73impl Error {
74    pub fn cerr(&self) -> ConnectError {
75        use ConnectError as CErr;
76        use Error as E;
77        match self {
78            E::Io(_) => CErr::ServerFailure,
79            E::Poisoned(_) => CErr::ServerFailure,
80            E::Disconnected { .. } => CErr::ServerFailure,
81            E::MessageFormat { .. } => CErr::ServerFailure,
82            E::Authentication => CErr::ConnectionNotAllowed,
83            E::NoAcceptableMethod => CErr::ConnectionNotAllowed,
84            E::UnrecognizedUsernamePassword => CErr::ConnectionNotAllowed,
85            E::CommandNotSupported { .. } => CErr::CommandNotSupported,
86            E::HostUnreachable { .. } => CErr::HostUnreachable,
87            E::DomainNotResolved { .. } => CErr::NetworkUnreachable,
88            E::PacketSizeLimitExceeded { .. } => CErr::ServerFailure,
89            E::AddressAlreadInUse { .. } => CErr::ServerFailure,
90            E::AddressNotAvailable { .. } => CErr::ServerFailure,
91            E::ConnectionNotAllowed { .. } => CErr::ConnectionNotAllowed,
92            E::ConnectionRefused { .. } => CErr::ConnectionRefused,
93            E::Unknown(_) => CErr::ServerFailure,
94        }
95    }
96}
97
98impl<T: fmt::Debug> From<sync::PoisonError<T>> for Error {
99    fn from(error: sync::PoisonError<T>) -> Self {
100        Error::Poisoned(format!("{:?}", error))
101    }
102}