• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2023 Huawei Device Co., Ltd.
2 // Licensed under the Apache License, Version 2.0 (the "License");
3 // you may not use this file except in compliance with the License.
4 // You may obtain a copy of the License at
5 //
6 //     http://www.apache.org/licenses/LICENSE-2.0
7 //
8 // Unless required by applicable law or agreed to in writing, software
9 // distributed under the License is distributed on an "AS IS" BASIS,
10 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11 // See the License for the specific language governing permissions and
12 // limitations under the License.
13 
14 use std::future::Future;
15 use std::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr, SocketAddrV4, SocketAddrV6};
16 use std::pin::Pin;
17 use std::task::{Context, Poll};
18 use std::{io, mem, option, vec};
19 
20 use crate::spawn_blocking;
21 use crate::task::JoinHandle;
22 
each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T> where F: FnMut(SocketAddr) -> io::Result<T>,23 pub(crate) async fn each_addr<A: ToSocketAddrs, F, T>(addr: A, mut f: F) -> io::Result<T>
24 where
25     F: FnMut(SocketAddr) -> io::Result<T>,
26 {
27     let addrs = addr.to_socket_addrs().await?;
28 
29     let mut last_e = None;
30 
31     for addr in addrs {
32         match f(addr) {
33             Ok(res) => return Ok(res),
34             Err(e) => last_e = Some(e),
35         }
36     }
37 
38     Err(last_e.unwrap_or(io::Error::new(
39         io::ErrorKind::InvalidInput,
40         "addr could not resolve to any address",
41     )))
42 }
43 
44 /// Convert the type that implements the trait to [`SocketAddr`]
45 pub trait ToSocketAddrs {
46     /// Returned iterator of SocketAddr.
47     type Iter: Iterator<Item = SocketAddr>;
48 
49     /// Converts this object to an iterator of resolved `SocketAddr`s.
to_socket_addrs(&self) -> State<Self::Iter>50     fn to_socket_addrs(&self) -> State<Self::Iter>;
51 }
52 
53 /// Parsing process status, str and (&str, u16) types may be Block
54 pub enum State<I> {
55     Block(JoinHandle<io::Result<I>>),
56     Ready(io::Result<I>),
57     Done,
58 }
59 
60 impl<I: Iterator<Item = SocketAddr>> Future for State<I> {
61     type Output = io::Result<I>;
62 
poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output>63     fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
64         let this = self.get_mut();
65 
66         match mem::replace(this, State::Done) {
67             State::Block(mut task) => {
68                 let poll = Pin::new(&mut task).poll(cx)?;
69                 if poll.is_pending() {
70                     *this = State::Block(task);
71                 }
72                 poll
73             }
74             State::Ready(res) => Poll::Ready(res),
75             State::Done => unreachable!("cannot poll a completed future"),
76         }
77     }
78 }
79 
80 impl<I> Unpin for State<I> {}
81 
82 impl ToSocketAddrs for SocketAddr {
83     type Iter = option::IntoIter<SocketAddr>;
84 
to_socket_addrs(&self) -> State<Self::Iter>85     fn to_socket_addrs(&self) -> State<Self::Iter> {
86         State::Ready(Ok(Some(*self).into_iter()))
87     }
88 }
89 
90 impl ToSocketAddrs for SocketAddrV4 {
91     type Iter = option::IntoIter<SocketAddr>;
92 
to_socket_addrs(&self) -> State<Self::Iter>93     fn to_socket_addrs(&self) -> State<Self::Iter> {
94         SocketAddr::V4(*self).to_socket_addrs()
95     }
96 }
97 
98 impl ToSocketAddrs for SocketAddrV6 {
99     type Iter = option::IntoIter<SocketAddr>;
100 
to_socket_addrs(&self) -> State<Self::Iter>101     fn to_socket_addrs(&self) -> State<Self::Iter> {
102         SocketAddr::V6(*self).to_socket_addrs()
103     }
104 }
105 
106 impl ToSocketAddrs for (IpAddr, u16) {
107     type Iter = option::IntoIter<SocketAddr>;
108 
to_socket_addrs(&self) -> State<Self::Iter>109     fn to_socket_addrs(&self) -> State<Self::Iter> {
110         let (ip, port) = *self;
111         match ip {
112             IpAddr::V4(ip_type) => (ip_type, port).to_socket_addrs(),
113             IpAddr::V6(ip_type) => (ip_type, port).to_socket_addrs(),
114         }
115     }
116 }
117 
118 impl ToSocketAddrs for (Ipv4Addr, u16) {
119     type Iter = option::IntoIter<SocketAddr>;
120 
to_socket_addrs(&self) -> State<Self::Iter>121     fn to_socket_addrs(&self) -> State<Self::Iter> {
122         let (ip, port) = *self;
123         SocketAddrV4::new(ip, port).to_socket_addrs()
124     }
125 }
126 
127 impl ToSocketAddrs for (Ipv6Addr, u16) {
128     type Iter = option::IntoIter<SocketAddr>;
129 
to_socket_addrs(&self) -> State<Self::Iter>130     fn to_socket_addrs(&self) -> State<Self::Iter> {
131         let (ip, port) = *self;
132         SocketAddrV6::new(ip, port, 0, 0).to_socket_addrs()
133     }
134 }
135 
136 impl ToSocketAddrs for (&str, u16) {
137     type Iter = vec::IntoIter<SocketAddr>;
138 
to_socket_addrs(&self) -> State<Self::Iter>139     fn to_socket_addrs(&self) -> State<Self::Iter> {
140         let (host, port) = *self;
141 
142         if let Ok(addr) = host.parse::<Ipv4Addr>() {
143             let addr = SocketAddrV4::new(addr, port);
144             return State::Ready(Ok(vec![SocketAddr::V4(addr)].into_iter()));
145         }
146 
147         if let Ok(addr) = host.parse::<Ipv6Addr>() {
148             let addr = SocketAddrV6::new(addr, port, 0, 0);
149             return State::Ready(Ok(vec![SocketAddr::V6(addr)].into_iter()));
150         }
151 
152         let host = host.to_string();
153         let task = spawn_blocking(move || {
154             let addr = (host.as_str(), port);
155             std::net::ToSocketAddrs::to_socket_addrs(&addr)
156         });
157         State::Block(task)
158     }
159 }
160 
161 impl ToSocketAddrs for str {
162     type Iter = vec::IntoIter<SocketAddr>;
163 
to_socket_addrs(&self) -> State<Self::Iter>164     fn to_socket_addrs(&self) -> State<Self::Iter> {
165         if let Ok(addr) = self.parse() {
166             return State::Ready(Ok(vec![addr].into_iter()));
167         }
168 
169         let addr = self.to_string();
170         let task = spawn_blocking(move || {
171             let addr = addr.as_str();
172             std::net::ToSocketAddrs::to_socket_addrs(addr)
173         });
174         State::Block(task)
175     }
176 }
177 
178 impl<'a> ToSocketAddrs for &'a [SocketAddr] {
179     type Iter = std::iter::Cloned<std::slice::Iter<'a, SocketAddr>>;
180 
to_socket_addrs(&self) -> State<Self::Iter>181     fn to_socket_addrs(&self) -> State<Self::Iter> {
182         State::Ready(Ok(self.iter().cloned()))
183     }
184 }
185 
186 impl ToSocketAddrs for String {
187     type Iter = vec::IntoIter<SocketAddr>;
188 
to_socket_addrs(&self) -> State<Self::Iter>189     fn to_socket_addrs(&self) -> State<Self::Iter> {
190         (**self).to_socket_addrs()
191     }
192 }
193 
194 impl<T: ToSocketAddrs + ?Sized> ToSocketAddrs for &T {
195     type Iter = T::Iter;
196 
to_socket_addrs(&self) -> State<Self::Iter>197     fn to_socket_addrs(&self) -> State<Self::Iter> {
198         (**self).to_socket_addrs()
199     }
200 }
201