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