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}