1pub(crate) mod net {
8 use crate::{impls, traits};
9 use async_trait::async_trait;
10 #[cfg(unix)]
11 use tor_general_addr::unix;
12
13 pub(crate) use tokio_crate::net::{
14 TcpListener as TokioTcpListener, TcpStream as TokioTcpStream, UdpSocket as TokioUdpSocket,
15 };
16 #[cfg(unix)]
17 pub(crate) use tokio_crate::net::{
18 UnixListener as TokioUnixListener, UnixStream as TokioUnixStream,
19 };
20
21 use futures::io::{AsyncRead, AsyncWrite};
22 use paste::paste;
23 use tokio_util::compat::{Compat, TokioAsyncReadCompatExt as _};
24
25 use std::io::Result as IoResult;
26 use std::net::SocketAddr;
27 use std::pin::Pin;
28 use std::task::{Context, Poll};
29
30 macro_rules! stream_impl {
32 {
33 $kind:ident,
34 $addr:ty,
35 $cvt_addr:ident
36 } => {paste!{
37 #[doc = stringify!($kind)]
39 pub struct [<$kind Stream>] {
43 s: Compat<[<Tokio $kind Stream>]>,
45 }
46 impl From<[<Tokio $kind Stream>]> for [<$kind Stream>] {
47 fn from(s: [<Tokio $kind Stream>]) -> [<$kind Stream>] {
48 let s = s.compat();
49 [<$kind Stream>] { s }
50 }
51 }
52 impl AsyncRead for [<$kind Stream>] {
53 fn poll_read(
54 mut self: Pin<&mut Self>,
55 cx: &mut Context<'_>,
56 buf: &mut [u8],
57 ) -> Poll<IoResult<usize>> {
58 Pin::new(&mut self.s).poll_read(cx, buf)
59 }
60 }
61 impl AsyncWrite for [<$kind Stream>] {
62 fn poll_write(
63 mut self: Pin<&mut Self>,
64 cx: &mut Context<'_>,
65 buf: &[u8],
66 ) -> Poll<IoResult<usize>> {
67 Pin::new(&mut self.s).poll_write(cx, buf)
68 }
69 fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<IoResult<()>> {
70 Pin::new(&mut self.s).poll_flush(cx)
71 }
72 fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<IoResult<()>> {
73 Pin::new(&mut self.s).poll_close(cx)
74 }
75 }
76
77 #[doc = stringify!($kind)]
79 pub struct [<$kind Listener>] {
81 pub(super) lis: [<Tokio $kind Listener>],
83 }
84
85 #[doc = stringify!($kind)]
87 pub struct [<Incoming $kind Streams>] {
91 pub(super) lis: [<Tokio $kind Listener>],
93 }
94
95 impl futures::stream::Stream for [<Incoming $kind Streams>] {
96 type Item = IoResult<([<$kind Stream>], $addr)>;
97
98 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
99 match self.lis.poll_accept(cx) {
100 Poll::Ready(Ok((s, a))) => Poll::Ready(Some(Ok((s.into(), $cvt_addr(a)? )))),
101 Poll::Ready(Err(e)) => Poll::Ready(Some(Err(e))),
102 Poll::Pending => Poll::Pending,
103 }
104 }
105 }
106 impl traits::NetStreamListener<$addr> for [<$kind Listener>] {
107 type Stream = [<$kind Stream>];
108 type Incoming = [<Incoming $kind Streams>];
109 fn incoming(self) -> Self::Incoming {
110 [<Incoming $kind Streams>] { lis: self.lis }
111 }
112 fn local_addr(&self) -> IoResult<$addr> {
113 $cvt_addr(self.lis.local_addr()?)
114 }
115 }
116 }}
117 }
118
119 #[cfg(unix)]
124 #[allow(clippy::needless_pass_by_value)]
125 fn try_cvt_tokio_unix_addr(
126 addr: tokio_crate::net::unix::SocketAddr,
127 ) -> IoResult<unix::SocketAddr> {
128 if addr.is_unnamed() {
129 crate::unix::new_unnamed_socketaddr()
130 } else if let Some(p) = addr.as_pathname() {
131 unix::SocketAddr::from_pathname(p)
132 } else {
133 Err(crate::unix::UnsupportedAfUnixAddressType.into())
134 }
135 }
136
137 #[allow(clippy::unnecessary_wraps)]
139 fn identity_fn_socketaddr(addr: std::net::SocketAddr) -> IoResult<std::net::SocketAddr> {
140 Ok(addr)
141 }
142
143 stream_impl! { Tcp, std::net::SocketAddr, identity_fn_socketaddr }
144 #[cfg(unix)]
145 stream_impl! { Unix, unix::SocketAddr, try_cvt_tokio_unix_addr }
146
147 pub struct UdpSocket {
149 socket: TokioUdpSocket,
151 }
152
153 impl UdpSocket {
154 pub async fn bind(addr: SocketAddr) -> IoResult<Self> {
156 TokioUdpSocket::bind(addr)
157 .await
158 .map(|socket| UdpSocket { socket })
159 }
160 }
161
162 #[async_trait]
163 impl traits::UdpSocket for UdpSocket {
164 async fn recv(&self, buf: &mut [u8]) -> IoResult<(usize, SocketAddr)> {
165 self.socket.recv_from(buf).await
166 }
167
168 async fn send(&self, buf: &[u8], target: &SocketAddr) -> IoResult<usize> {
169 self.socket.send_to(buf, target).await
170 }
171
172 fn local_addr(&self) -> IoResult<SocketAddr> {
173 self.socket.local_addr()
174 }
175 }
176
177 impl traits::StreamOps for TcpStream {
178 fn set_tcp_notsent_lowat(&self, notsent_lowat: u32) -> IoResult<()> {
179 impls::streamops::set_tcp_notsent_lowat(&self.s, notsent_lowat)
180 }
181
182 #[cfg(target_os = "linux")]
183 fn new_handle(&self) -> Box<dyn traits::StreamOps + Send + Unpin> {
184 Box::new(impls::streamops::TcpSockFd::from_fd(&self.s))
185 }
186 }
187
188 #[cfg(unix)]
189 impl traits::StreamOps for UnixStream {
190 fn set_tcp_notsent_lowat(&self, _notsent_lowat: u32) -> IoResult<()> {
191 Err(traits::UnsupportedStreamOp::new(
192 "set_tcp_notsent_lowat",
193 "unsupported on Unix streams",
194 )
195 .into())
196 }
197 }
198}
199
200use crate::network::{TcpConnectOptions, TcpListenOptions};
203#[cfg(unix)]
204use crate::network::{UnixConnectOptions, UnixListenOptions};
205use crate::traits::*;
206use async_trait::async_trait;
207use futures::Future;
208use std::io::Result as IoResult;
209use std::time::Duration;
210#[cfg(unix)]
211use tor_general_addr::unix;
212use tracing::instrument;
213
214impl SleepProvider for TokioRuntimeHandle {
215 type SleepFuture = tokio_crate::time::Sleep;
216 fn sleep(&self, duration: Duration) -> Self::SleepFuture {
217 tokio_crate::time::sleep(duration)
218 }
219}
220
221#[async_trait]
222impl crate::traits::NetStreamProvider for TokioRuntimeHandle {
223 type Stream = net::TcpStream;
224 type Listener = net::TcpListener;
225 type ConnectOptions = TcpConnectOptions;
226 type ListenOptions = TcpListenOptions;
227
228 #[instrument(skip_all, level = "trace")]
229 async fn connect(
230 &self,
231 addr: &std::net::SocketAddr,
232 options: &Self::ConnectOptions,
233 ) -> IoResult<Self::Stream> {
234 let socket = super::tcp_pre_connect(addr, options)?;
236
237 let socket = std::net::TcpStream::from(socket);
249 let socket = tokio_crate::net::TcpSocket::from_std_stream(socket);
250
251 let socket = socket.connect(*addr).await?;
253
254 Ok(socket.into())
255 }
256 async fn listen(
257 &self,
258 addr: &std::net::SocketAddr,
259 options: &Self::ListenOptions,
260 ) -> IoResult<Self::Listener> {
261 let lis = net::TokioTcpListener::from_std(super::tcp_listen(addr, options)?)?;
263
264 Ok(net::TcpListener { lis })
265 }
266}
267
268#[cfg(unix)]
269#[async_trait]
270impl crate::traits::NetStreamProvider<unix::SocketAddr> for TokioRuntimeHandle {
271 type Stream = net::UnixStream;
272 type Listener = net::UnixListener;
273 type ConnectOptions = UnixConnectOptions;
274 type ListenOptions = UnixListenOptions;
275
276 #[instrument(skip_all, level = "trace")]
277 async fn connect(
278 &self,
279 addr: &unix::SocketAddr,
280 options: &Self::ConnectOptions,
281 ) -> IoResult<Self::Stream> {
282 let UnixConnectOptions {} = options;
284
285 let path = addr
286 .as_pathname()
287 .ok_or(crate::unix::UnsupportedAfUnixAddressType)?;
288 let s = net::TokioUnixStream::connect(path).await?;
289 Ok(s.into())
290 }
291 async fn listen(
292 &self,
293 addr: &unix::SocketAddr,
294 options: &Self::ListenOptions,
295 ) -> IoResult<Self::Listener> {
296 let UnixListenOptions {} = options;
298
299 let path = addr
300 .as_pathname()
301 .ok_or(crate::unix::UnsupportedAfUnixAddressType)?;
302 let lis = net::TokioUnixListener::bind(path)?;
303 Ok(net::UnixListener { lis })
304 }
305}
306
307#[cfg(not(unix))]
308crate::impls::impl_unix_non_provider! { TokioRuntimeHandle }
309
310#[async_trait]
311impl crate::traits::UdpProvider for TokioRuntimeHandle {
312 type UdpSocket = net::UdpSocket;
313
314 async fn bind(&self, addr: &std::net::SocketAddr) -> IoResult<Self::UdpSocket> {
315 net::UdpSocket::bind(*addr).await
316 }
317}
318
319pub(crate) fn create_runtime() -> IoResult<TokioRuntimeHandle> {
321 let runtime = async_executors::exec::TokioTp::new().map_err(std::io::Error::other)?;
322 Ok(runtime.into())
323}
324
325#[derive(Clone, Debug)]
338pub struct TokioRuntimeHandle {
339 owned: Option<async_executors::TokioTp>,
345 handle: tokio_crate::runtime::Handle,
347}
348
349impl TokioRuntimeHandle {
350 pub(crate) fn new(handle: tokio_crate::runtime::Handle) -> Self {
358 handle.into()
359 }
360
361 pub fn is_owned(&self) -> bool {
363 self.owned.is_some()
364 }
365}
366
367impl From<tokio_crate::runtime::Handle> for TokioRuntimeHandle {
368 fn from(handle: tokio_crate::runtime::Handle) -> Self {
369 Self {
370 owned: None,
371 handle,
372 }
373 }
374}
375
376impl From<async_executors::TokioTp> for TokioRuntimeHandle {
377 fn from(owner: async_executors::TokioTp) -> TokioRuntimeHandle {
378 let handle = owner.block_on(async { tokio_crate::runtime::Handle::current() });
379 Self {
380 owned: Some(owner),
381 handle,
382 }
383 }
384}
385
386impl ToplevelBlockOn for TokioRuntimeHandle {
387 #[track_caller]
388 fn block_on<F: Future>(&self, f: F) -> F::Output {
389 self.handle.block_on(f)
390 }
391}
392
393impl Blocking for TokioRuntimeHandle {
394 type ThreadHandle<T: Send + 'static> = async_executors::BlockingHandle<T>;
395
396 #[track_caller]
397 fn spawn_blocking<F, T>(&self, f: F) -> async_executors::BlockingHandle<T>
398 where
399 F: FnOnce() -> T + Send + 'static,
400 T: Send + 'static,
401 {
402 async_executors::BlockingHandle::tokio(self.handle.spawn_blocking(f))
403 }
404
405 #[track_caller]
406 fn reenter_block_on<F: Future>(&self, future: F) -> F::Output {
407 self.handle.block_on(future)
408 }
409
410 #[track_caller]
411 fn blocking_io<F, T>(&self, f: F) -> impl Future<Output = T>
412 where
413 F: FnOnce() -> T + Send + 'static,
414 T: Send + 'static,
415 {
416 let r = tokio_crate::task::block_in_place(f);
417 std::future::ready(r)
418 }
419}
420
421impl futures::task::Spawn for TokioRuntimeHandle {
422 #[track_caller]
423 fn spawn_obj(
424 &self,
425 future: futures::task::FutureObj<'static, ()>,
426 ) -> Result<(), futures::task::SpawnError> {
427 let join_handle = self.handle.spawn(future);
428 drop(join_handle); Ok(())
430 }
431}