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