1use core::future::{Future, poll_fn};
4use core::pin::Pin;
5use core::task::{Context, Poll};
6use std::io;
7use std::net::{SocketAddr, TcpListener, TcpStream};
8
9use futures_core::Stream;
10
11use super::addr::{ToSocketAddrs, resolve};
12use super::none_worked;
13use std::time::Duration;
14
15use crate::io::IoObject;
16use crate::io::raw::Owned;
17use crate::io::source::write::Peer;
18use crate::io::source::{Addr, Kind};
19use crate::io::{Handle, sys};
20use crate::rt::counters::out_of_descriptors;
21use crate::time::{Sleep, sleep};
22
23impl Handle<TcpListener> {
24 pub async fn bind<A: ToSocketAddrs>(addr: A) -> io::Result<Handle<TcpListener>> {
31 let mut last = None;
32 for addr in resolve(&addr).await? {
33 match TcpListener::bind(addr) {
34 Ok(listener) => return Handle::adopt(listener, Kind::TcpListener),
35 Err(err) => last = Some(err),
36 }
37 }
38 Err(none_worked(last))
39 }
40
41 pub async fn accept(&self) -> io::Result<(Handle<TcpStream>, SocketAddr)> {
53 poll_fn(|cx| self.poll_accept(cx)).await
54 }
55
56 pub fn poll_accept(
63 &self,
64 cx: &mut Context<'_>,
65 ) -> Poll<io::Result<(Handle<TcpStream>, SocketAddr)>> {
66 let source = self.source();
67 source.poll_accept(cx).map(|accepted| {
68 let (fd, addr) = accepted?;
69 Ok((stream(fd, source), inet(addr)?))
70 })
71 }
72
73 fn poll_accept_stream(&self, cx: &mut Context<'_>) -> Poll<io::Result<Handle<TcpStream>>> {
77 let source = self.source();
78 source
79 .poll_accept_stream(cx)
80 .map(|accepted| accepted.map(|fd| stream(fd, source)))
81 }
82
83 pub fn incoming(
86 &self,
87 ) -> impl Stream<Item = io::Result<Handle<TcpStream>>> + Send + Unpin + '_ {
88 Incoming { listener: self }
89 }
90
91 pub async fn accept_multi(&self) -> io::Result<TcpStreamGenerator> {
110 let listener = self.get_ref().try_clone()?;
111 Ok(TcpStreamGenerator {
112 listener: Handle::adopt(listener, Kind::TcpListener)?,
113 error: None,
114 done: false,
115 backoff: None,
116 delay: OUT_OF_DESCRIPTORS_DELAY,
117 })
118 }
119}
120
121fn stream(fd: crate::io::raw::Owned, listener: &crate::io::Source) -> Handle<TcpStream> {
123 #[cfg(any(target_os = "linux", target_os = "android"))]
124 if listener.passes_inq() {
125 return Handle::from_nonblocking_counting(TcpStream::from(fd), Kind::Tcp);
126 }
127 #[cfg(not(any(target_os = "linux", target_os = "android")))]
128 let _ = listener;
129 Handle::from_nonblocking(TcpStream::from(fd), Kind::Tcp)
130}
131
132fn inet(addr: Addr) -> io::Result<SocketAddr> {
133 match addr {
134 Addr::Inet(addr) => Ok(addr),
135 #[cfg(unix)]
136 Addr::Unix(_) => Err(io::Error::new(
137 io::ErrorKind::InvalidData,
138 "a TCP listener's peer has no internet address",
139 )),
140 }
141}
142
143struct Incoming<'a> {
144 listener: &'a Handle<TcpListener>,
145}
146
147impl Stream for Incoming<'_> {
148 type Item = io::Result<Handle<TcpStream>>;
149
150 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
151 self.listener
152 .poll_accept(cx)
153 .map(|accepted| Some(accepted.map(|(stream, _)| stream)))
154 }
155}
156
157#[derive(Debug)]
159pub struct TcpStreamGenerator {
160 listener: Handle<TcpListener>,
161 error: Option<io::Error>,
162 done: bool,
163 backoff: Option<Sleep>,
164 delay: Duration,
165}
166
167const OUT_OF_DESCRIPTORS_DELAY: Duration = Duration::from_millis(10);
170const OUT_OF_DESCRIPTORS_DELAY_MAX: Duration = Duration::from_secs(1);
171
172impl TcpStreamGenerator {
173 pub fn take_error(&mut self) -> Option<io::Error> {
175 self.error.take()
176 }
177}
178
179impl Stream for TcpStreamGenerator {
180 type Item = Handle<TcpStream>;
181
182 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
183 let this = &mut *self;
184 while !this.done {
185 if let Some(backoff) = this.backoff.as_mut() {
186 if Pin::new(backoff).poll(cx).is_pending() {
187 return Poll::Pending;
188 }
189 this.backoff = None;
190 }
191 match this.listener.poll_accept_stream(cx) {
192 Poll::Pending => return Poll::Pending,
193 Poll::Ready(Ok(stream)) => {
194 this.delay = OUT_OF_DESCRIPTORS_DELAY;
195 return Poll::Ready(Some(stream));
196 }
197 Poll::Ready(Err(err)) if err.kind() == io::ErrorKind::ConnectionAborted => {}
198 Poll::Ready(Err(err)) if out_of_descriptors(&err) => {
199 this.backoff = Some(sleep(this.delay));
200 this.delay = (this.delay * 2).min(OUT_OF_DESCRIPTORS_DELAY_MAX);
201 }
202 Poll::Ready(Err(err)) => {
203 this.error = Some(err);
204 this.done = true;
205 }
206 }
207 }
208 Poll::Ready(None)
209 }
210}
211
212impl Handle<TcpStream> {
213 pub async fn connect<A: ToSocketAddrs>(sock_addrs: A) -> io::Result<Handle<TcpStream>> {
220 let mut last = None;
221 for addr in resolve(&sock_addrs).await? {
222 match connect(addr).await {
223 Ok(stream) => return Ok(stream),
224 Err(err) => last = Some(err),
225 }
226 }
227 Err(none_worked(last))
228 }
229
230 pub async fn send(&self, buf: &[u8]) -> io::Result<usize> {
239 poll_fn(|cx| self.source().poll_write(cx, buf)).await
240 }
241
242 pub async fn recv(&self, buf: &mut [u8]) -> io::Result<usize> {
248 poll_fn(|cx| self.source().poll_read(cx, buf, false)).await
249 }
250
251 pub async fn peek(&self, buf: &mut [u8]) -> io::Result<usize> {
257 poll_fn(|cx| self.source().poll_read(cx, buf, true)).await
258 }
259
260 pub fn poll_peek(
267 &self,
268 cx: &mut Context<'_>,
269 buf: &mut crate::io::ReadBuf<'_>,
270 ) -> Poll<io::Result<usize>> {
271 let n = core::task::ready!(self.source().poll_read(cx, buf.initialize_unfilled(), true))?;
272 buf.advance(n);
273 Poll::Ready(Ok(n))
274 }
275
276 pub fn linger(&self) -> io::Result<Option<Duration>> {
279 super::opt::linger_time(self.raw_io())
280 }
281
282 pub fn set_linger(&self, linger: Option<Duration>) -> io::Result<()> {
286 super::opt::set_linger_time(self.raw_io(), linger)
287 }
288
289 pub fn set_zero_linger(&self) -> io::Result<()> {
292 super::opt::set_linger_time(self.raw_io(), Some(Duration::ZERO))
293 }
294}
295
296pub(super) fn new_socket(v6: bool) -> io::Result<Owned> {
298 #[cfg(unix)]
299 return sys::socket(
300 if v6 { libc::AF_INET6 } else { libc::AF_INET },
301 libc::SOCK_STREAM,
302 );
303 #[cfg(windows)]
304 return sys::tcp_socket(if v6 {
305 crate::syscore::windows::AF_INET6
306 } else {
307 crate::syscore::windows::AF_INET
308 });
309}
310
311async fn connect(addr: SocketAddr) -> io::Result<Handle<TcpStream>> {
314 connect_socket(new_socket(addr.is_ipv6())?, true, addr).await
315}
316
317pub(super) async fn connect_socket(
319 socket: Owned,
320 nonblocking: bool,
321 addr: SocketAddr,
322) -> io::Result<Handle<TcpStream>> {
323 let stream = if nonblocking {
324 Handle::from_nonblocking(TcpStream::from(socket), Kind::Tcp)
325 } else {
326 Handle::adopt(TcpStream::from(socket), Kind::Tcp)?
327 };
328 poll_fn(|cx| stream.source().poll_connect(cx, Peer::Inet(addr))).await?;
329 Ok(stream)
330}