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