1 #![allow(dead_code)] 2 3 use std::io; 4 use std::net; 5 use std::num::ParseIntError; 6 use std::string::FromUtf8Error; 7 use thiserror::Error; 8 9 pub type Result<T> = std::result::Result<T, Error>; 10 11 #[derive(Error, Debug, PartialEq)] 12 #[non_exhaustive] 13 pub enum Error { 14 #[error("buffer: full")] 15 ErrBufferFull, 16 #[error("buffer: closed")] 17 ErrBufferClosed, 18 #[error("buffer: short")] 19 ErrBufferShort, 20 #[error("packet too big")] 21 ErrPacketTooBig, 22 #[error("i/o timeout")] 23 ErrTimeout, 24 #[error("udp: listener closed")] 25 ErrClosedListener, 26 #[error("udp: listen queue exceeded")] 27 ErrListenQueueExceeded, 28 #[error("udp: listener accept ch closed")] 29 ErrClosedListenerAcceptCh, 30 #[error("obs cannot be nil")] 31 ErrObsCannotBeNil, 32 #[error("se of closed network connection")] 33 ErrUseClosedNetworkConn, 34 #[error("addr is not a net.UDPAddr")] 35 ErrAddrNotUdpAddr, 36 #[error("something went wrong with locAddr")] 37 ErrLocAddr, 38 #[error("already closed")] 39 ErrAlreadyClosed, 40 #[error("no remAddr defined")] 41 ErrNoRemAddr, 42 #[error("address already in use")] 43 ErrAddressAlreadyInUse, 44 #[error("no such UDPConn")] 45 ErrNoSuchUdpConn, 46 #[error("cannot remove unspecified IP by the specified IP")] 47 ErrCannotRemoveUnspecifiedIp, 48 #[error("no address assigned")] 49 ErrNoAddressAssigned, 50 #[error("1:1 NAT requires more than one mapping")] 51 ErrNatRequriesMapping, 52 #[error("length mismtach between mappedIPs and localIPs")] 53 ErrMismatchLengthIp, 54 #[error("non-udp translation is not supported yet")] 55 ErrNonUdpTranslationNotSupported, 56 #[error("no associated local address")] 57 ErrNoAssociatedLocalAddress, 58 #[error("no NAT binding found")] 59 ErrNoNatBindingFound, 60 #[error("has no permission")] 61 ErrHasNoPermission, 62 #[error("host name must not be empty")] 63 ErrHostnameEmpty, 64 #[error("failed to parse IP address")] 65 ErrFailedToParseIpaddr, 66 #[error("no interface is available")] 67 ErrNoInterface, 68 #[error("not found")] 69 ErrNotFound, 70 #[error("unexpected network")] 71 ErrUnexpectedNetwork, 72 #[error("can't assign requested address")] 73 ErrCantAssignRequestedAddr, 74 #[error("unknown network")] 75 ErrUnknownNetwork, 76 #[error("no router linked")] 77 ErrNoRouterLinked, 78 #[error("invalid port number")] 79 ErrInvalidPortNumber, 80 #[error("unexpected type-switch failure")] 81 ErrUnexpectedTypeSwitchFailure, 82 #[error("bind failed")] 83 ErrBindFailed, 84 #[error("end port is less than the start")] 85 ErrEndPortLessThanStart, 86 #[error("port space exhausted")] 87 ErrPortSpaceExhausted, 88 #[error("vnet is not enabled")] 89 ErrVnetDisabled, 90 #[error("invalid local IP in static_ips")] 91 ErrInvalidLocalIpInStaticIps, 92 #[error("mapped in static_ips is beyond subnet")] 93 ErrLocalIpBeyondStaticIpsSubset, 94 #[error("all static_ips must have associated local IPs")] 95 ErrLocalIpNoStaticsIpsAssociated, 96 #[error("router already started")] 97 ErrRouterAlreadyStarted, 98 #[error("router already stopped")] 99 ErrRouterAlreadyStopped, 100 #[error("static IP is beyond subnet")] 101 ErrStaticIpIsBeyondSubnet, 102 #[error("address space exhausted")] 103 ErrAddressSpaceExhausted, 104 #[error("no IP address is assigned for eth0")] 105 ErrNoIpaddrEth0, 106 #[error("Invalid mask")] 107 ErrInvalidMask, 108 #[error("parse ipnet: {0}")] 109 ParseIpnet(#[from] ipnet::AddrParseError), 110 #[error("parse ip: {0}")] 111 ParseIp(#[from] net::AddrParseError), 112 #[error("parse int: {0}")] 113 ParseInt(#[from] ParseIntError), 114 #[error("{0}")] 115 Io(#[source] IoError), 116 #[error("utf8: {0}")] 117 Utf8(#[from] FromUtf8Error), 118 #[error("{0}")] 119 Std(#[source] StdError), 120 #[error("{0}")] 121 Other(String), 122 } 123 124 impl Error { from_std<T>(error: T) -> Self where T: std::error::Error + Send + Sync + 'static,125 pub fn from_std<T>(error: T) -> Self 126 where 127 T: std::error::Error + Send + Sync + 'static, 128 { 129 Error::Std(StdError(Box::new(error))) 130 } 131 downcast_ref<T: std::error::Error + 'static>(&self) -> Option<&T>132 pub fn downcast_ref<T: std::error::Error + 'static>(&self) -> Option<&T> { 133 if let Error::Std(s) = self { 134 return s.0.downcast_ref(); 135 } 136 137 None 138 } 139 } 140 141 #[derive(Debug, Error)] 142 #[error("io error: {0}")] 143 pub struct IoError(#[from] pub io::Error); 144 145 // Workaround for wanting PartialEq for io::Error. 146 impl PartialEq for IoError { eq(&self, other: &Self) -> bool147 fn eq(&self, other: &Self) -> bool { 148 self.0.kind() == other.0.kind() 149 } 150 } 151 152 impl From<io::Error> for Error { from(e: io::Error) -> Self153 fn from(e: io::Error) -> Self { 154 Error::Io(IoError(e)) 155 } 156 } 157 158 /// An escape hatch to preserve stack traces when we don't know the error. 159 /// 160 /// This crate exports some traits such as `Conn` and `Listener`. The trait functions 161 /// produce the local error `util::Error`. However when used in crates higher up the stack, 162 /// we are forced to handle errors that are local to that crate. For example we use 163 /// `Listener` the `dtls` crate and it needs to handle `dtls::Error`. 164 /// 165 /// By using `util::Error::from_std` we can preserve the underlying error (and stack trace!). 166 #[derive(Debug, Error)] 167 #[error("{0}")] 168 pub struct StdError(pub Box<dyn std::error::Error + Send + Sync>); 169 170 impl PartialEq for StdError { eq(&self, _: &Self) -> bool171 fn eq(&self, _: &Self) -> bool { 172 false 173 } 174 } 175