Impl ToSocketAddrs for SocketAddress
authorslanesuke <slaneian@gmail.com>
Sat, 30 Sep 2023 23:05:00 +0000 (17:05 -0600)
committerslanesuke <slaneian@gmail.com>
Wed, 18 Oct 2023 23:52:31 +0000 (17:52 -0600)
lightning/src/ln/msgs.rs

index a68ac35218594689cd36402b7b4c05df3fa7321c..3bc4483aaa552a618c6df63a126edcad6e8d2705 100644 (file)
@@ -46,6 +46,8 @@ use core::fmt::Debug;
 use core::ops::Deref;
 #[cfg(feature = "std")]
 use core::str::FromStr;
+#[cfg(feature = "std")]
+use std::net::SocketAddr;
 use crate::io::{self, Cursor, Read};
 use crate::io_extras::read_to_end;
 
@@ -958,6 +960,37 @@ impl From<std::net::SocketAddr> for SocketAddress {
                }
 }
 
+#[cfg(feature = "std")]
+impl std::net::ToSocketAddrs for SocketAddress {
+       type Iter = std::vec::IntoIter<std::net::SocketAddr>;
+
+       fn to_socket_addrs(&self) -> std::io::Result<Self::Iter> {
+               match self {
+                       SocketAddress::TcpIpV4 { addr, port } => {
+                               let ip_addr = std::net::Ipv4Addr::from(*addr);
+                               let socket_addr = SocketAddr::new(ip_addr.into(), *port);
+                               Ok(vec![socket_addr].into_iter())
+                       }
+                       SocketAddress::TcpIpV6 { addr, port } => {
+                               let ip_addr = std::net::Ipv6Addr::from(*addr);
+                               let socket_addr = SocketAddr::new(ip_addr.into(), *port);
+                               Ok(vec![socket_addr].into_iter())
+                       }
+                       SocketAddress::Hostname { ref hostname, port } => {
+                               (hostname.as_str(), *port).to_socket_addrs()
+                       }
+                       SocketAddress::OnionV2(..) => {
+                               Err(std::io::Error::new(std::io::ErrorKind::Other, "Resolution of OnionV2 \
+                               addresses is currently unsupported."))
+                       }
+                       SocketAddress::OnionV3 { .. } => {
+                               Err(std::io::Error::new(std::io::ErrorKind::Other, "Resolution of OnionV3 \
+                               addresses is currently unsupported."))
+                       }
+               }
+       }
+}
+
 /// Parses an OnionV3 host and port into a [`SocketAddress::OnionV3`].
 ///
 /// The host part must end with ".onion".
@@ -2676,7 +2709,7 @@ mod tests {
        use crate::chain::transaction::OutPoint;
 
        #[cfg(feature = "std")]
-       use std::net::{Ipv4Addr, Ipv6Addr};
+       use std::net::{Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6, ToSocketAddrs};
        use crate::ln::msgs::SocketAddressParseError;
 
        #[test]
@@ -4105,4 +4138,22 @@ mod tests {
                assert!("invalid-address".parse::<SocketAddress>().is_err());
                assert!(SocketAddress::from_str("pg6mmjiyjmcrsslvykfwnntlaru7p5svn6y2ymmju6nubxndf4pscryd.onion.onion:1234").is_err());
        }
+
+       #[test]
+       #[cfg(feature = "std")]
+       fn test_socket_address_to_socket_addrs() {
+               assert_eq!(SocketAddress::TcpIpV4 {addr:[0u8; 4], port: 1337,}.to_socket_addrs().unwrap().next().unwrap(),
+                                  SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(0,0,0,0), 1337)));
+               assert_eq!(SocketAddress::TcpIpV6 {addr:[0u8; 16], port: 1337,}.to_socket_addrs().unwrap().next().unwrap(),
+                                  SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::from([0u8; 16]), 1337, 0, 0)));
+               assert_eq!(SocketAddress::Hostname { hostname: Hostname::try_from("0.0.0.0".to_string()).unwrap(), port: 0 }
+                                          .to_socket_addrs().unwrap().next().unwrap(), SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::from([0u8; 4]),0)));
+               assert!(SocketAddress::OnionV2([0u8; 12]).to_socket_addrs().is_err());
+               assert!(SocketAddress::OnionV3{ ed25519_pubkey: [37, 24, 75, 5, 25, 73, 117, 194, 139, 102,
+                       182, 107, 4, 105, 247, 246, 85, 111, 177, 172, 49, 137, 167, 155, 64, 221, 163, 47, 31,
+                       33, 71, 3],
+                       checksum: 48326,
+                       version: 121,
+                       port: 1234 }.to_socket_addrs().is_err());
+       }
 }