@@ -47,12 +47,14 @@ impl Address {
4747 }
4848
4949 /// Extracts socket address from an [Address] message.
50- /// This will return [io::Error] [io::ErrorKind::AddrNotAvailable]
51- /// if the message contains a Tor address.
52- pub fn socket_addr ( & self ) -> Result < SocketAddr , io:: Error > {
50+ ///
51+ /// # Errors
52+ ///
53+ /// Returns an error if the message contains a Tor V2 onion address.
54+ pub fn socket_addr ( & self ) -> Result < SocketAddr , UnroutableAddressError > {
5355 let addr = & self . address ;
5456 if addr[ 0 ..3 ] == ONION {
55- return Err ( io :: Error :: from ( io :: ErrorKind :: AddrNotAvailable ) ) ;
57+ return Err ( UnroutableAddressError :: TorV2 ) ;
5658 }
5759 let ipv6 =
5860 Ipv6Addr :: new ( addr[ 0 ] , addr[ 1 ] , addr[ 2 ] , addr[ 3 ] , addr[ 4 ] , addr[ 5 ] , addr[ 6 ] , addr[ 7 ] ) ;
@@ -126,7 +128,9 @@ impl fmt::Debug for Address {
126128impl ToSocketAddrs for Address {
127129 type Iter = iter:: Once < SocketAddr > ;
128130 fn to_socket_addrs ( & self ) -> Result < Self :: Iter , std:: io:: Error > {
129- Ok ( iter:: once ( self . socket_addr ( ) ?) )
131+ self . socket_addr ( )
132+ . map ( iter:: once)
133+ . map_err ( |e| std:: io:: Error :: new ( std:: io:: ErrorKind :: InvalidInput , e) )
130134 }
131135}
132136
@@ -148,16 +152,16 @@ pub enum AddrV2 {
148152}
149153
150154impl TryFrom < AddrV2 > for IpAddr {
151- type Error = AddrV2ToIpAddrError ;
155+ type Error = UnroutableAddressError ;
152156
153157 fn try_from ( addr : AddrV2 ) -> Result < Self , Self :: Error > {
154158 match addr {
155159 AddrV2 :: Ipv4 ( ip) => Ok ( Self :: V4 ( ip) ) ,
156160 AddrV2 :: Ipv6 ( ip) => Ok ( Self :: V6 ( ip) ) ,
157- AddrV2 :: Cjdns ( _) => Err ( AddrV2ToIpAddrError :: Cjdns ) ,
158- AddrV2 :: TorV3 ( _) => Err ( AddrV2ToIpAddrError :: TorV3 ) ,
159- AddrV2 :: I2p ( _) => Err ( AddrV2ToIpAddrError :: I2p ) ,
160- AddrV2 :: Unknown ( _, _) => Err ( AddrV2ToIpAddrError :: Unknown ) ,
161+ AddrV2 :: Cjdns ( _) => Err ( UnroutableAddressError :: Cjdns ) ,
162+ AddrV2 :: TorV3 ( _) => Err ( UnroutableAddressError :: TorV3 ) ,
163+ AddrV2 :: I2p ( _) => Err ( UnroutableAddressError :: I2p ) ,
164+ AddrV2 :: Unknown ( _, _) => Err ( UnroutableAddressError :: Unknown ) ,
161165 }
162166 }
163167}
@@ -202,11 +206,15 @@ impl From<IpAddr> for AddrV2 {
202206}
203207
204208impl From < Ipv4Addr > for AddrV2 {
205- fn from ( addr : Ipv4Addr ) -> Self { Self :: Ipv4 ( addr) }
209+ fn from ( addr : Ipv4Addr ) -> Self {
210+ Self :: Ipv4 ( addr)
211+ }
206212}
207213
208214impl From < Ipv6Addr > for AddrV2 {
209- fn from ( addr : Ipv6Addr ) -> Self { Self :: Ipv6 ( addr) }
215+ fn from ( addr : Ipv6Addr ) -> Self {
216+ Self :: Ipv6 ( addr)
217+ }
210218}
211219
212220impl Encodable for AddrV2 {
@@ -317,13 +325,19 @@ pub struct AddrV2Message {
317325
318326impl AddrV2Message {
319327 /// Extracts socket address from an [AddrV2Message] message.
320- /// This will return [io::Error] [io::ErrorKind::AddrNotAvailable]
321- /// if the address type can't be converted into a [SocketAddr].
322- pub fn socket_addr ( & self ) -> Result < SocketAddr , io:: Error > {
328+ ///
329+ /// # Errors
330+ ///
331+ /// Returns an error if the address type cannot be converted to a socket address
332+ /// (e.g. Tor, I2P, CJDNS addresses).
333+ pub fn socket_addr ( & self ) -> Result < SocketAddr , UnroutableAddressError > {
323334 match self . addr {
324335 AddrV2 :: Ipv4 ( addr) => Ok ( SocketAddr :: V4 ( SocketAddrV4 :: new ( addr, self . port ) ) ) ,
325336 AddrV2 :: Ipv6 ( addr) => Ok ( SocketAddr :: V6 ( SocketAddrV6 :: new ( addr, self . port , 0 , 0 ) ) ) ,
326- _ => Err ( io:: Error :: from ( io:: ErrorKind :: AddrNotAvailable ) ) ,
337+ AddrV2 :: TorV3 ( _) => Err ( UnroutableAddressError :: TorV3 ) ,
338+ AddrV2 :: I2p ( _) => Err ( UnroutableAddressError :: I2p ) ,
339+ AddrV2 :: Cjdns ( _) => Err ( UnroutableAddressError :: Cjdns ) ,
340+ AddrV2 :: Unknown ( _, _) => Err ( UnroutableAddressError :: Unknown ) ,
327341 }
328342 }
329343}
@@ -356,10 +370,46 @@ impl Decodable for AddrV2Message {
356370impl ToSocketAddrs for AddrV2Message {
357371 type Iter = iter:: Once < SocketAddr > ;
358372 fn to_socket_addrs ( & self ) -> Result < Self :: Iter , std:: io:: Error > {
359- Ok ( iter:: once ( self . socket_addr ( ) ?) )
373+ self . socket_addr ( )
374+ . map ( iter:: once)
375+ . map_err ( |e| std:: io:: Error :: new ( std:: io:: ErrorKind :: InvalidInput , e) )
360376 }
361377}
362378
379+ /// Error returned when an address cannot be converted to an IP-based address.
380+ ///
381+ /// Addresses like Tor, I2P, and CJDNS use different routing mechanisms
382+ /// and cannot be represented as standard IP addresses or socket addresses.
383+ #[ derive( Debug , Clone , Copy , PartialEq , Eq , Hash ) ]
384+ #[ non_exhaustive]
385+ pub enum UnroutableAddressError {
386+ /// Tor V2 onion address.
387+ TorV2 ,
388+ /// Tor V3 onion address.
389+ TorV3 ,
390+ /// I2P address.
391+ I2p ,
392+ /// CJDNS address.
393+ Cjdns ,
394+ /// Unknown address type.
395+ Unknown ,
396+ }
397+
398+ impl fmt:: Display for UnroutableAddressError {
399+ fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
400+ match self {
401+ Self :: TorV2 => write ! ( f, "Tor v2 addresses cannot be converted to IP addresses" ) ,
402+ Self :: TorV3 => write ! ( f, "Tor v3 addresses cannot be converted to IP addresses" ) ,
403+ Self :: I2p => write ! ( f, "I2P addresses cannot be converted to IP addresses" ) ,
404+ Self :: Cjdns => write ! ( f, "CJDNS addresses cannot be converted to IP addresses" ) ,
405+ Self :: Unknown => write ! ( f, "unknown address type cannot be converted to IP addresses" ) ,
406+ }
407+ }
408+ }
409+
410+ #[ cfg( feature = "std" ) ]
411+ impl std:: error:: Error for UnroutableAddressError { }
412+
363413/// Error types for [`AddrV2`] to [`IpAddr`] conversion.
364414#[ derive( Debug , PartialEq , Eq ) ]
365415pub enum AddrV2ToIpAddrError {
@@ -794,7 +844,7 @@ mod test {
794844 let result = IpAddr :: try_from ( addr) ;
795845
796846 assert ! ( result. is_err( ) ) ;
797- assert_eq ! ( result. unwrap_err( ) , AddrV2ToIpAddrError :: Cjdns ) ;
847+ assert_eq ! ( result. unwrap_err( ) , UnroutableAddressError :: Cjdns ) ;
798848 }
799849
800850 #[ test]
@@ -803,7 +853,7 @@ mod test {
803853 let result = IpAddr :: try_from ( addr) ;
804854
805855 assert ! ( result. is_err( ) ) ;
806- assert_eq ! ( result. unwrap_err( ) , AddrV2ToIpAddrError :: TorV3 ) ;
856+ assert_eq ! ( result. unwrap_err( ) , UnroutableAddressError :: TorV3 ) ;
807857 }
808858
809859 #[ test]
@@ -812,7 +862,7 @@ mod test {
812862 let result = IpAddr :: try_from ( addr) ;
813863
814864 assert ! ( result. is_err( ) ) ;
815- assert_eq ! ( result. unwrap_err( ) , AddrV2ToIpAddrError :: I2p ) ;
865+ assert_eq ! ( result. unwrap_err( ) , UnroutableAddressError :: I2p ) ;
816866 }
817867
818868 #[ test]
@@ -821,7 +871,7 @@ mod test {
821871 let result = IpAddr :: try_from ( addr) ;
822872
823873 assert ! ( result. is_err( ) ) ;
824- assert_eq ! ( result. unwrap_err( ) , AddrV2ToIpAddrError :: Unknown ) ;
874+ assert_eq ! ( result. unwrap_err( ) , UnroutableAddressError :: Unknown ) ;
825875 }
826876
827877 #[ test]
0 commit comments