@@ -46,6 +46,8 @@ use core::fmt::Debug;
4646use core:: ops:: Deref ;
4747#[ cfg( feature = "std" ) ]
4848use core:: str:: FromStr ;
49+ #[ cfg( feature = "std" ) ]
50+ use std:: net:: SocketAddr ;
4951use crate :: io:: { self , Cursor , Read } ;
5052use crate :: io_extras:: read_to_end;
5153
@@ -958,6 +960,37 @@ impl From<std::net::SocketAddr> for SocketAddress {
958960 }
959961}
960962
963+ #[ cfg( feature = "std" ) ]
964+ impl std:: net:: ToSocketAddrs for SocketAddress {
965+ type Iter = std:: vec:: IntoIter < std:: net:: SocketAddr > ;
966+
967+ fn to_socket_addrs ( & self ) -> std:: io:: Result < Self :: Iter > {
968+ match self {
969+ SocketAddress :: TcpIpV4 { addr, port } => {
970+ let ip_addr = std:: net:: Ipv4Addr :: from ( * addr) ;
971+ let socket_addr = SocketAddr :: new ( ip_addr. into ( ) , * port) ;
972+ Ok ( vec ! [ socket_addr] . into_iter ( ) )
973+ }
974+ SocketAddress :: TcpIpV6 { addr, port } => {
975+ let ip_addr = std:: net:: Ipv6Addr :: from ( * addr) ;
976+ let socket_addr = SocketAddr :: new ( ip_addr. into ( ) , * port) ;
977+ Ok ( vec ! [ socket_addr] . into_iter ( ) )
978+ }
979+ SocketAddress :: Hostname { ref hostname, port } => {
980+ ( hostname. as_str ( ) , * port) . to_socket_addrs ( )
981+ }
982+ SocketAddress :: OnionV2 ( ..) => {
983+ Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "Resolution of OnionV2 \
984+ addresses is currently unsupported.") )
985+ }
986+ SocketAddress :: OnionV3 { .. } => {
987+ Err ( std:: io:: Error :: new ( std:: io:: ErrorKind :: Other , "Resolution of OnionV3 \
988+ addresses is currently unsupported.") )
989+ }
990+ }
991+ }
992+ }
993+
961994/// Parses an OnionV3 host and port into a [`SocketAddress::OnionV3`].
962995///
963996/// The host part must end with ".onion".
@@ -2681,7 +2714,7 @@ mod tests {
26812714 use crate :: chain:: transaction:: OutPoint ;
26822715
26832716 #[ cfg( feature = "std" ) ]
2684- use std:: net:: { Ipv4Addr , Ipv6Addr } ;
2717+ use std:: net:: { Ipv4Addr , Ipv6Addr , SocketAddr , SocketAddrV4 , SocketAddrV6 , ToSocketAddrs } ;
26852718 use crate :: ln:: msgs:: SocketAddressParseError ;
26862719
26872720 #[ test]
@@ -4110,4 +4143,22 @@ mod tests {
41104143 assert ! ( "invalid-address" . parse:: <SocketAddress >( ) . is_err( ) ) ;
41114144 assert ! ( SocketAddress :: from_str( "pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion.onion:1234" ) . is_err( ) ) ;
41124145 }
4146+
4147+ #[ test]
4148+ #[ cfg( feature = "std" ) ]
4149+ fn test_socket_address_to_socket_addrs ( ) {
4150+ assert_eq ! ( SocketAddress :: TcpIpV4 { addr: [ 0u8 ; 4 ] , port: 1337 , } . to_socket_addrs( ) . unwrap( ) . next( ) . unwrap( ) ,
4151+ SocketAddr :: V4 ( SocketAddrV4 :: new( Ipv4Addr :: new( 0 , 0 , 0 , 0 ) , 1337 ) ) ) ;
4152+ assert_eq ! ( SocketAddress :: TcpIpV6 { addr: [ 0u8 ; 16 ] , port: 1337 , } . to_socket_addrs( ) . unwrap( ) . next( ) . unwrap( ) ,
4153+ SocketAddr :: V6 ( SocketAddrV6 :: new( Ipv6Addr :: from( [ 0u8 ; 16 ] ) , 1337 , 0 , 0 ) ) ) ;
4154+ assert_eq ! ( SocketAddress :: Hostname { hostname: Hostname :: try_from( "0.0.0.0" . to_string( ) ) . unwrap( ) , port: 0 }
4155+ . to_socket_addrs( ) . unwrap( ) . next( ) . unwrap( ) , SocketAddr :: V4 ( SocketAddrV4 :: new( Ipv4Addr :: from( [ 0u8 ; 4 ] ) , 0 ) ) ) ;
4156+ assert ! ( SocketAddress :: OnionV2 ( [ 0u8 ; 12 ] ) . to_socket_addrs( ) . is_err( ) ) ;
4157+ assert ! ( SocketAddress :: OnionV3 { ed25519_pubkey: [ 37 , 24 , 75 , 5 , 25 , 73 , 117 , 194 , 139 , 102 ,
4158+ 182 , 107 , 4 , 105 , 247 , 246 , 85 , 111 , 177 , 172 , 49 , 137 , 167 , 155 , 64 , 221 , 163 , 47 , 31 ,
4159+ 33 , 71 , 3 ] ,
4160+ checksum: 48326 ,
4161+ version: 121 ,
4162+ port: 1234 } . to_socket_addrs( ) . is_err( ) ) ;
4163+ }
41134164}
0 commit comments