1use std::{
2 io::ErrorKind,
3 net::{IpAddr, SocketAddr},
4};
5
6use memberlist_core::transport::TransportError;
7use nodecraft::resolver::AddressResolver;
8
9#[derive(thiserror::Error)]
11pub enum NetTransportError<A: AddressResolver> {
12 #[error("no private IP address found, and explicit IP not provided")]
14 NoPrivateIP,
15 #[error("at least one bind address is required")]
17 EmptyBindAddresses,
18 #[error("the ip {0} is blocked")]
20 BlockedIp(IpAddr),
21 #[error("failed to start packet listener on {0}: {1}")]
23 ListenPacket(SocketAddr, std::io::Error),
24 #[error("failed to start promised listener on {0}: {1}")]
26 ListenPromised(SocketAddr, std::io::Error),
27 #[error("failed to create resolver: {0}")]
29 Resolver(A::Error),
30 #[error("failed to resolve address {addr}: {err}")]
32 Resolve {
33 addr: A::Address,
35 err: A::Error,
37 },
38 #[error("packet too large, the maximum packet can be sent is 65535, got {0}")]
40 PacketTooLarge(usize),
41 #[error(transparent)]
43 Io(#[from] std::io::Error),
44 #[error("{0}")]
46 Custom(std::borrow::Cow<'static, str>),
47}
48
49impl<A: AddressResolver> core::fmt::Debug for NetTransportError<A> {
50 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
51 core::fmt::Display::fmt(&self, f)
52 }
53}
54
55impl<A> TransportError for NetTransportError<A>
56where
57 A: AddressResolver,
58 A::Address: Send + Sync + 'static,
59{
60 fn is_remote_failure(&self) -> bool {
61 match self {
62 Self::Io(err) => matches!(
63 err.kind(),
64 ErrorKind::ConnectionRefused
65 | ErrorKind::ConnectionReset
66 | ErrorKind::ConnectionAborted
67 | ErrorKind::BrokenPipe
68 | ErrorKind::TimedOut
69 | ErrorKind::NotConnected
70 ),
71 _ => false,
72 }
73 }
74
75 fn custom(err: std::borrow::Cow<'static, str>) -> Self {
76 Self::Custom(err)
77 }
78}