1 use crate::future;
2 
3 use std::io;
4 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
5 
6 /// Converts or resolves without blocking to one or more `SocketAddr` values.
7 ///
8 /// # DNS
9 ///
10 /// Implementations of `ToSocketAddrs` for string types require a DNS lookup.
11 ///
12 /// # Calling
13 ///
14 /// Currently, this trait is only used as an argument to Tokio functions that
15 /// need to reference a target socket address. To perform a `SocketAddr`
16 /// conversion directly, use [`lookup_host()`](super::lookup_host()).
17 ///
18 /// This trait is sealed and is intended to be opaque. The details of the trait
19 /// will change. Stabilization is pending enhancements to the Rust language.
20 pub trait ToSocketAddrs: sealed::ToSocketAddrsPriv {}
21 
22 type ReadyFuture<T> = future::Ready<io::Result<T>>;
23 
24 cfg_net! {
25     pub(crate) fn to_socket_addrs<T>(arg: T) -> T::Future
26     where
27         T: ToSocketAddrs,
28     {
29         arg.to_socket_addrs(sealed::Internal)
30     }
31 }
32 
33 // ===== impl &impl ToSocketAddrs =====
34 
35 impl<T: ToSocketAddrs + ?Sized> ToSocketAddrs for &T {}
36 
37 impl<T> sealed::ToSocketAddrsPriv for &T
38 where
39     T: sealed::ToSocketAddrsPriv + ?Sized,
40 {
41     type Iter = T::Iter;
42     type Future = T::Future;
43 
to_socket_addrs(&self, _: sealed::Internal) -> Self::Future44     fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
45         (**self).to_socket_addrs(sealed::Internal)
46     }
47 }
48 
49 // ===== impl SocketAddr =====
50 
51 impl ToSocketAddrs for SocketAddr {}
52 
53 impl sealed::ToSocketAddrsPriv for SocketAddr {
54     type Iter = std::option::IntoIter<SocketAddr>;
55     type Future = ReadyFuture<Self::Iter>;
56 
to_socket_addrs(&self, _: sealed::Internal) -> Self::Future57     fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
58         let iter = Some(*self).into_iter();
59         future::ok(iter)
60     }
61 }
62 
63 // ===== impl SocketAddrV4 =====
64 
65 impl ToSocketAddrs for SocketAddrV4 {}
66 
67 impl sealed::ToSocketAddrsPriv for SocketAddrV4 {
68     type Iter = std::option::IntoIter<SocketAddr>;
69     type Future = ReadyFuture<Self::Iter>;
70 
to_socket_addrs(&self, _: sealed::Internal) -> Self::Future71     fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
72         SocketAddr::V4(*self).to_socket_addrs(sealed::Internal)
73     }
74 }
75 
76 // ===== impl SocketAddrV6 =====
77 
78 impl ToSocketAddrs for SocketAddrV6 {}
79 
80 impl sealed::ToSocketAddrsPriv for SocketAddrV6 {
81     type Iter = std::option::IntoIter<SocketAddr>;
82     type Future = ReadyFuture<Self::Iter>;
83 
to_socket_addrs(&self, _: sealed::Internal) -> Self::Future84     fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
85         SocketAddr::V6(*self).to_socket_addrs(sealed::Internal)
86     }
87 }
88 
89 // ===== impl (IpAddr, u16) =====
90 
91 impl ToSocketAddrs for (IpAddr, u16) {}
92 
93 impl sealed::ToSocketAddrsPriv for (IpAddr, u16) {
94     type Iter = std::option::IntoIter<SocketAddr>;
95     type Future = ReadyFuture<Self::Iter>;
96 
to_socket_addrs(&self, _: sealed::Internal) -> Self::Future97     fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
98         let iter = Some(SocketAddr::from(*self)).into_iter();
99         future::ok(iter)
100     }
101 }
102 
103 // ===== impl (Ipv4Addr, u16) =====
104 
105 impl ToSocketAddrs for (Ipv4Addr, u16) {}
106 
107 impl sealed::ToSocketAddrsPriv for (Ipv4Addr, u16) {
108     type Iter = std::option::IntoIter<SocketAddr>;
109     type Future = ReadyFuture<Self::Iter>;
110 
to_socket_addrs(&self, _: sealed::Internal) -> Self::Future111     fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
112         let (ip, port) = *self;
113         SocketAddrV4::new(ip, port).to_socket_addrs(sealed::Internal)
114     }
115 }
116 
117 // ===== impl (Ipv6Addr, u16) =====
118 
119 impl ToSocketAddrs for (Ipv6Addr, u16) {}
120 
121 impl sealed::ToSocketAddrsPriv for (Ipv6Addr, u16) {
122     type Iter = std::option::IntoIter<SocketAddr>;
123     type Future = ReadyFuture<Self::Iter>;
124 
to_socket_addrs(&self, _: sealed::Internal) -> Self::Future125     fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
126         let (ip, port) = *self;
127         SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs(sealed::Internal)
128     }
129 }
130 
131 // ===== impl &[SocketAddr] =====
132 
133 impl ToSocketAddrs for &[SocketAddr] {}
134 
135 impl sealed::ToSocketAddrsPriv for &[SocketAddr] {
136     type Iter = std::vec::IntoIter<SocketAddr>;
137     type Future = ReadyFuture<Self::Iter>;
138 
to_socket_addrs(&self, _: sealed::Internal) -> Self::Future139     fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
140         let iter = self.to_vec().into_iter();
141         future::ok(iter)
142     }
143 }
144 
145 cfg_net! {
146     // ===== impl str =====
147 
148     impl ToSocketAddrs for str {}
149 
150     impl sealed::ToSocketAddrsPriv for str {
151         type Iter = sealed::OneOrMore;
152         type Future = sealed::MaybeReady;
153 
154         fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
155             use crate::blocking::spawn_blocking;
156             use sealed::MaybeReady;
157 
158             // First check if the input parses as a socket address
159             let res: Result<SocketAddr, _> = self.parse();
160 
161             if let Ok(addr) = res {
162                 return MaybeReady(sealed::State::Ready(Some(addr)));
163             }
164 
165             // Run DNS lookup on the blocking pool
166             let s = self.to_owned();
167 
168             MaybeReady(sealed::State::Blocking(spawn_blocking(move || {
169                 std::net::ToSocketAddrs::to_socket_addrs(&s)
170             })))
171         }
172     }
173 
174     // ===== impl (&str, u16) =====
175 
176     impl ToSocketAddrs for (&str, u16) {}
177 
178     impl sealed::ToSocketAddrsPriv for (&str, u16) {
179         type Iter = sealed::OneOrMore;
180         type Future = sealed::MaybeReady;
181 
182         fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
183             use crate::blocking::spawn_blocking;
184             use sealed::MaybeReady;
185 
186             let (host, port) = *self;
187 
188             // try to parse the host as a regular IP address first
189             if let Ok(addr) = host.parse::<Ipv4Addr>() {
190                 let addr = SocketAddrV4::new(addr, port);
191                 let addr = SocketAddr::V4(addr);
192 
193                 return MaybeReady(sealed::State::Ready(Some(addr)));
194             }
195 
196             if let Ok(addr) = host.parse::<Ipv6Addr>() {
197                 let addr = SocketAddrV6::new(addr, port, 0, 0);
198                 let addr = SocketAddr::V6(addr);
199 
200                 return MaybeReady(sealed::State::Ready(Some(addr)));
201             }
202 
203             let host = host.to_owned();
204 
205             MaybeReady(sealed::State::Blocking(spawn_blocking(move || {
206                 std::net::ToSocketAddrs::to_socket_addrs(&(&host[..], port))
207             })))
208         }
209     }
210 
211     // ===== impl (String, u16) =====
212 
213     impl ToSocketAddrs for (String, u16) {}
214 
215     impl sealed::ToSocketAddrsPriv for (String, u16) {
216         type Iter = sealed::OneOrMore;
217         type Future = sealed::MaybeReady;
218 
219         fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
220             (self.0.as_str(), self.1).to_socket_addrs(sealed::Internal)
221         }
222     }
223 
224     // ===== impl String =====
225 
226     impl ToSocketAddrs for String {}
227 
228     impl sealed::ToSocketAddrsPriv for String {
229         type Iter = <str as sealed::ToSocketAddrsPriv>::Iter;
230         type Future = <str as sealed::ToSocketAddrsPriv>::Future;
231 
232         fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future {
233             (&self[..]).to_socket_addrs(sealed::Internal)
234         }
235     }
236 }
237 
238 pub(crate) mod sealed {
239     //! The contents of this trait are intended to remain private and __not__
240     //! part of the `ToSocketAddrs` public API. The details will change over
241     //! time.
242 
243     use std::future::Future;
244     use std::io;
245     use std::net::SocketAddr;
246 
247     #[doc(hidden)]
248     pub trait ToSocketAddrsPriv {
249         type Iter: Iterator<Item = SocketAddr> + Send + 'static;
250         type Future: Future<Output = io::Result<Self::Iter>> + Send + 'static;
251 
to_socket_addrs(&self, internal: Internal) -> Self::Future252         fn to_socket_addrs(&self, internal: Internal) -> Self::Future;
253     }
254 
255     #[allow(missing_debug_implementations)]
256     pub struct Internal;
257 
258     cfg_net! {
259         use crate::blocking::JoinHandle;
260 
261         use std::option;
262         use std::pin::Pin;
263         use std::task::{Context, Poll};
264         use std::vec;
265 
266         #[doc(hidden)]
267         #[derive(Debug)]
268         pub struct MaybeReady(pub(super) State);
269 
270         #[derive(Debug)]
271         pub(super) enum State {
272             Ready(Option<SocketAddr>),
273             Blocking(JoinHandle<io::Result<vec::IntoIter<SocketAddr>>>),
274         }
275 
276         #[doc(hidden)]
277         #[derive(Debug)]
278         pub enum OneOrMore {
279             One(option::IntoIter<SocketAddr>),
280             More(vec::IntoIter<SocketAddr>),
281         }
282 
283         impl Future for MaybeReady {
284             type Output = io::Result<OneOrMore>;
285 
286             fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
287                 match self.0 {
288                     State::Ready(ref mut i) => {
289                         let iter = OneOrMore::One(i.take().into_iter());
290                         Poll::Ready(Ok(iter))
291                     }
292                     State::Blocking(ref mut rx) => {
293                         let res = ready!(Pin::new(rx).poll(cx))?.map(OneOrMore::More);
294 
295                         Poll::Ready(res)
296                     }
297                 }
298             }
299         }
300 
301         impl Iterator for OneOrMore {
302             type Item = SocketAddr;
303 
304             fn next(&mut self) -> Option<Self::Item> {
305                 match self {
306                     OneOrMore::One(i) => i.next(),
307                     OneOrMore::More(i) => i.next(),
308                 }
309             }
310 
311             fn size_hint(&self) -> (usize, Option<usize>) {
312                 match self {
313                     OneOrMore::One(i) => i.size_hint(),
314                     OneOrMore::More(i) => i.size_hint(),
315                 }
316             }
317         }
318     }
319 }
320