1extern crate alloc;
2
3use crate::io;
4use alloc::string::String;
5use core::{iter, option, slice};
6
7pub use core::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
8
9pub trait ToSocketAddrs {
32    type Iter: Iterator<Item = SocketAddr>;
34
35    fn to_socket_addrs(&self) -> io::Result<Self::Iter>;
37}
38
39impl ToSocketAddrs for SocketAddr {
40    type Iter = option::IntoIter<SocketAddr>;
41    fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
42        Ok(Some(*self).into_iter())
43    }
44}
45
46impl ToSocketAddrs for SocketAddrV4 {
47    type Iter = option::IntoIter<SocketAddr>;
48    fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
49        SocketAddr::V4(*self).to_socket_addrs()
50    }
51}
52
53impl ToSocketAddrs for (IpAddr, u16) {
54    type Iter = option::IntoIter<SocketAddr>;
55    fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
56        let (ip, port) = *self;
57        SocketAddr::new(ip, port).to_socket_addrs()
58    }
59}
60
61impl ToSocketAddrs for (Ipv4Addr, u16) {
62    type Iter = option::IntoIter<SocketAddr>;
63    fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
64        let (ip, port) = *self;
65        SocketAddrV4::new(ip, port).to_socket_addrs()
66    }
67}
68
69impl<'a> ToSocketAddrs for &'a [SocketAddr] {
70    type Iter = iter::Cloned<slice::Iter<'a, SocketAddr>>;
71
72    fn to_socket_addrs(&self) -> io::Result<Self::Iter> {
73        Ok(self.iter().cloned())
74    }
75}
76
77impl<T: ToSocketAddrs + ?Sized> ToSocketAddrs for &T {
78    type Iter = T::Iter;
79    fn to_socket_addrs(&self) -> io::Result<T::Iter> {
80        (**self).to_socket_addrs()
81    }
82}
83
84#[cfg(not(feature = "dns"))]
85#[doc(cfg(feature = "net"))]
86mod no_dns {
87    use super::*;
88
89    impl ToSocketAddrs for (&str, u16) {
90        type Iter = option::IntoIter<SocketAddr>;
91        fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
92            let (host, port) = *self;
93            Ok(host
94                .parse::<Ipv4Addr>()
95                .ok()
96                .map(|addr| {
97                    let addr = SocketAddrV4::new(addr, port);
98                    SocketAddr::V4(addr)
99                })
100                .into_iter())
101        }
102    }
103
104    impl ToSocketAddrs for str {
105        type Iter = option::IntoIter<SocketAddr>;
106        fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
107            Ok(self.parse().ok().into_iter())
109        }
110    }
111
112    impl ToSocketAddrs for (String, u16) {
113        type Iter = option::IntoIter<SocketAddr>;
114        fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
115            (&*self.0, self.1).to_socket_addrs()
116        }
117    }
118
119    impl ToSocketAddrs for String {
120        type Iter = option::IntoIter<SocketAddr>;
121        fn to_socket_addrs(&self) -> io::Result<option::IntoIter<SocketAddr>> {
122            (**self).to_socket_addrs()
123        }
124    }
125}
126
127#[cfg(feature = "dns")]
128#[doc(cfg(feature = "net"))]
129mod dns {
130    use super::*;
131    use alloc::{vec, vec::Vec};
132
133    impl ToSocketAddrs for (&str, u16) {
134        type Iter = vec::IntoIter<SocketAddr>;
135        fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
136            let (host, port) = *self;
137
138            if let Ok(addr) = host.parse::<Ipv4Addr>() {
140                let addr = SocketAddrV4::new(addr, port);
141                return Ok(vec![SocketAddr::V4(addr)].into_iter());
142            }
143
144            Ok(arceos_api::net::ax_dns_query(host)?
145                .into_iter()
146                .map(|ip| SocketAddr::new(ip, port))
147                .collect::<Vec<_>>()
148                .into_iter())
149        }
150    }
151
152    impl ToSocketAddrs for str {
153        type Iter = vec::IntoIter<SocketAddr>;
154
155        fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
156            if let Ok(addr) = self.parse() {
158                return Ok(vec![addr].into_iter());
159            }
160
161            let (host, port_str) = self
163                .rsplit_once(':')
164                .ok_or_else(|| axerrno::ax_err_type!(InvalidInput, "invalid socket address"))?;
165            let port: u16 = port_str
166                .parse()
167                .map_err(|_| axerrno::ax_err_type!(InvalidInput, "invalid port value"))?;
168
169            Ok(arceos_api::net::ax_dns_query(host)?
170                .into_iter()
171                .map(|ip| SocketAddr::new(ip, port))
172                .collect::<Vec<_>>()
173                .into_iter())
174        }
175    }
176
177    impl ToSocketAddrs for (String, u16) {
178        type Iter = vec::IntoIter<SocketAddr>;
179        fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
180            (&*self.0, self.1).to_socket_addrs()
181        }
182    }
183
184    impl ToSocketAddrs for String {
185        type Iter = vec::IntoIter<SocketAddr>;
186        fn to_socket_addrs(&self) -> io::Result<vec::IntoIter<SocketAddr>> {
187            (**self).to_socket_addrs()
188        }
189    }
190}