1 use std::future; 2 use std::io; 3 use 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. 19 pub trait ToSocketAddrs: sealed::ToSocketAddrsPriv {} 20 21 type ReadyFuture<T> = future::Ready<io::Result<T>>; 22 23 cfg_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 34 impl<T: ToSocketAddrs + ?Sized> ToSocketAddrs for &T {} 35 36 impl<T> sealed::ToSocketAddrsPriv for &T 37 where 38 T: sealed::ToSocketAddrsPriv + ?Sized, 39 { 40 type Iter = T::Iter; 41 type Future = T::Future; 42 to_socket_addrs(&self, _: sealed::Internal) -> Self::Future43 fn to_socket_addrs(&self, _: sealed::Internal) -> Self::Future { 44 (**self).to_socket_addrs(sealed::Internal) 45 } 46 } 47 48 // ===== impl SocketAddr ===== 49 50 impl ToSocketAddrs for SocketAddr {} 51 52 impl sealed::ToSocketAddrsPriv for SocketAddr { 53 type Iter = std::option::IntoIter<SocketAddr>; 54 type Future = ReadyFuture<Self::Iter>; 55 to_socket_addrs(&self, _: sealed::Internal) -> Self::Future56 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 64 impl ToSocketAddrs for SocketAddrV4 {} 65 66 impl sealed::ToSocketAddrsPriv for SocketAddrV4 { 67 type Iter = std::option::IntoIter<SocketAddr>; 68 type Future = ReadyFuture<Self::Iter>; 69 to_socket_addrs(&self, _: sealed::Internal) -> Self::Future70 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 77 impl ToSocketAddrs for SocketAddrV6 {} 78 79 impl sealed::ToSocketAddrsPriv for SocketAddrV6 { 80 type Iter = std::option::IntoIter<SocketAddr>; 81 type Future = ReadyFuture<Self::Iter>; 82 to_socket_addrs(&self, _: sealed::Internal) -> Self::Future83 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 90 impl ToSocketAddrs for (IpAddr, u16) {} 91 92 impl sealed::ToSocketAddrsPriv for (IpAddr, u16) { 93 type Iter = std::option::IntoIter<SocketAddr>; 94 type Future = ReadyFuture<Self::Iter>; 95 to_socket_addrs(&self, _: sealed::Internal) -> Self::Future96 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 104 impl ToSocketAddrs for (Ipv4Addr, u16) {} 105 106 impl sealed::ToSocketAddrsPriv for (Ipv4Addr, u16) { 107 type Iter = std::option::IntoIter<SocketAddr>; 108 type Future = ReadyFuture<Self::Iter>; 109 to_socket_addrs(&self, _: sealed::Internal) -> Self::Future110 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 118 impl ToSocketAddrs for (Ipv6Addr, u16) {} 119 120 impl sealed::ToSocketAddrsPriv for (Ipv6Addr, u16) { 121 type Iter = std::option::IntoIter<SocketAddr>; 122 type Future = ReadyFuture<Self::Iter>; 123 to_socket_addrs(&self, _: sealed::Internal) -> Self::Future124 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 132 impl ToSocketAddrs for &[SocketAddr] {} 133 134 impl sealed::ToSocketAddrsPriv for &[SocketAddr] { 135 type Iter = std::vec::IntoIter<SocketAddr>; 136 type Future = ReadyFuture<Self::Iter>; 137 to_socket_addrs(&self, _: sealed::Internal) -> Self::Future138 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 159 cfg_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 252 pub(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 to_socket_addrs(&self, internal: Internal) -> Self::Future266 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::{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 } 334