tokio/net/
addr.rs

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