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