1use std::fmt::{Display, Formatter};
2use std::io;
3use std::net::{IpAddr, SocketAddr};
4use thiserror::Error;
5
6pub type Result<T> = std::result::Result<T, Error>;
8
9#[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
38pub type IoResult<T> = std::result::Result<T, IoError>;
40
41#[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 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#[derive(Debug, Eq, PartialEq)]
69pub enum ErrorKind {
70 InProgress,
71 HostUnreachable,
72 NetUnreachable,
73 Std(io::ErrorKind),
74}
75
76#[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}