trippy_core/
error.rs

1use std::fmt::{Display, Formatter};
2use std::io;
3use std::net::{IpAddr, SocketAddr};
4use thiserror::Error;
5
6/// A tracer error result.
7pub type Result<T> = std::result::Result<T, Error>;
8
9/// A tracer error.
10#[derive(Error, Debug)]
11pub enum Error {
12    #[error("invalid packet size: {0}")]
13    InvalidPacketSize(usize),
14    #[error("invalid packet: {0}")]
15    PacketError(#[from] trippy_packet::error::Error),
16    #[error("unknown interface: {0}")]
17    UnknownInterface(String),
18    #[error("invalid config: {0}")]
19    BadConfig(String),
20    #[error("IO error: {0}")]
21    IoError(#[from] IoError),
22    #[error("Probe failed to send: {0}")]
23    ProbeFailed(IoError),
24    #[error("insufficient buffer capacity")]
25    InsufficientCapacity,
26    #[error("address {0} in use")]
27    AddressInUse(SocketAddr),
28    #[error("source IP address {0} could not be bound")]
29    InvalidSourceAddr(IpAddr),
30    #[error("missing address from socket call")]
31    MissingAddr,
32    #[error("connect callback error: {0}")]
33    PrivilegeError(#[from] trippy_privilege::Error),
34    #[error("tracer error: {0}")]
35    Other(String),
36}
37
38/// Custom IO error result.
39pub type IoResult<T> = std::result::Result<T, IoError>;
40
41/// Custom IO error.
42#[derive(Error, Debug)]
43pub enum IoError {
44    #[error("Bind error for {1}: {0}")]
45    Bind(io::Error, SocketAddr),
46    #[error("Connect error for {1}: {0}")]
47    Connect(io::Error, SocketAddr),
48    #[error("Sendto error for {1}: {0}")]
49    SendTo(io::Error, SocketAddr),
50    #[error("Failed to {0}: {1}")]
51    Other(io::Error, IoOperation),
52}
53
54impl IoError {
55    /// Get the custom error kind.
56    pub fn kind(&self) -> ErrorKind {
57        match self {
58            Self::Bind(e, _) | Self::Connect(e, _) | Self::SendTo(e, _) | Self::Other(e, _) => {
59                ErrorKind::from(e)
60            }
61        }
62    }
63}
64
65/// Custom error kind.
66///
67/// This includes additional error kinds that are not part of the standard [`io::ErrorKind`].
68#[derive(Debug, Eq, PartialEq)]
69pub enum ErrorKind {
70    InProgress,
71    HostUnreachable,
72    NetUnreachable,
73    Std(io::ErrorKind),
74}
75
76/// Io operation.
77#[derive(Debug)]
78pub enum IoOperation {
79    NewSocket,
80    SetNonBlocking,
81    Select,
82    RecvFrom,
83    Read,
84    Shutdown,
85    LocalAddr,
86    PeerAddr,
87    TakeError,
88    SetTos,
89    SetTclassV6,
90    SetTtl,
91    SetReusePort,
92    SetHeaderIncluded,
93    SetUnicastHopsV6,
94    WSACreateEvent,
95    WSARecvFrom,
96    WSAEventSelect,
97    WSAResetEvent,
98    WSAGetOverlappedResult,
99    WaitForSingleObject,
100    SetTcpFailConnectOnIcmpError,
101    TcpIcmpErrorInfo,
102    ConvertSocketAddress,
103    SioRoutingInterfaceQuery,
104    Startup,
105}
106
107impl Display for IoOperation {
108    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
109        match self {
110            Self::NewSocket => write!(f, "create new socket"),
111            Self::SetNonBlocking => write!(f, "set non-blocking"),
112            Self::Select => write!(f, "select"),
113            Self::RecvFrom => write!(f, "recv from"),
114            Self::Read => write!(f, "read"),
115            Self::Shutdown => write!(f, "shutdown"),
116            Self::LocalAddr => write!(f, "local addr"),
117            Self::PeerAddr => write!(f, "peer addr"),
118            Self::TakeError => write!(f, "take error"),
119            Self::SetTos => write!(f, "set TOS"),
120            Self::SetTclassV6 => write!(f, "set TCLASS v6"),
121            Self::SetTtl => write!(f, "set TTL"),
122            Self::SetReusePort => write!(f, "set reuse port"),
123            Self::SetHeaderIncluded => write!(f, "set header included"),
124            Self::SetUnicastHopsV6 => write!(f, "set unicast hops v6"),
125            Self::WSACreateEvent => write!(f, "WSA create event"),
126            Self::WSARecvFrom => write!(f, "WSA recv from"),
127            Self::WSAEventSelect => write!(f, "WSA event select"),
128            Self::WSAResetEvent => write!(f, "WSA reset event"),
129            Self::WSAGetOverlappedResult => write!(f, "WSA get overlapped result"),
130            Self::WaitForSingleObject => write!(f, "wait for single object"),
131            Self::SetTcpFailConnectOnIcmpError => write!(f, "set TCP failed connect on ICMP error"),
132            Self::TcpIcmpErrorInfo => write!(f, "get TCP ICMP error info"),
133            Self::ConvertSocketAddress => write!(f, "convert socket address"),
134            Self::SioRoutingInterfaceQuery => write!(f, "SIO routing interface query"),
135            Self::Startup => write!(f, "startup"),
136        }
137    }
138}