1#![cfg_attr(docsrs, feature(doc_cfg, doc_auto_cfg))]
2#![allow(clippy::multiple_bound_locations)]
3#[cfg(feature = "remote")]
4pub mod client;
5pub mod composite;
6#[cfg(feature = "host-net")]
7pub mod host;
8pub mod loopback;
9pub mod meta;
10pub mod ruleset;
11#[cfg(feature = "remote")]
12pub mod rx_tx;
13#[cfg(feature = "remote")]
14pub mod server;
15pub mod tcp_pair;
16#[cfg(feature = "tokio")]
17#[cfg(test)]
18mod tests;
19
20#[cfg(feature = "remote")]
21pub use client::{RemoteNetworkingClient, RemoteNetworkingClientDriver};
22pub use composite::CompositeTcpListener;
23pub use loopback::LoopbackNetworking;
24use pin_project_lite::pin_project;
25#[cfg(feature = "rkyv")]
26use rkyv::{Archive, Deserialize as RkyvDeserialize, Serialize as RkyvSerialize};
27#[cfg(feature = "remote")]
28pub use server::{RemoteNetworkingServer, RemoteNetworkingServerDriver};
29use std::fmt;
30use std::mem::MaybeUninit;
31use std::net::IpAddr;
32use std::net::Ipv4Addr;
33use std::net::Ipv6Addr;
34use std::net::Shutdown;
35use std::net::SocketAddr;
36use std::pin::Pin;
37use std::sync::Arc;
38use std::task::Context;
39use std::task::Poll;
40use std::time::Duration;
41use thiserror::Error;
42#[cfg(feature = "tokio")]
43use tokio::io::AsyncRead;
44#[cfg(feature = "tokio")]
45use tokio::io::AsyncWrite;
46
47pub use bytes::Bytes;
48pub use bytes::BytesMut;
49use serde::{Deserialize, Serialize};
50#[cfg(feature = "host-net")]
51pub use virtual_mio::{InterestGuard, InterestHandlerWaker, InterestType};
52pub use virtual_mio::{InterestHandler, handler_into_waker};
53
54pub type Result<T> = std::result::Result<T, NetworkError>;
55
56#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)]
58#[cfg_attr(feature = "rkyv", derive(RkyvSerialize, RkyvDeserialize, Archive))]
59pub struct IpCidr {
60 pub ip: IpAddr,
61 pub prefix: u8,
62}
63
64#[derive(Clone, Debug, Serialize, Deserialize)]
66#[cfg_attr(feature = "rkyv", derive(RkyvSerialize, RkyvDeserialize, Archive))]
67pub struct IpRoute {
68 pub cidr: IpCidr,
69 pub via_router: IpAddr,
70 pub preferred_until: Option<Duration>,
71 pub expires_at: Option<Duration>,
72}
73
74pub trait VirtualIoSource: fmt::Debug + Send + Sync + 'static {
76 fn remove_handler(&mut self);
78
79 fn poll_read_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<usize>>;
81
82 fn poll_write_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<usize>>;
84}
85
86#[async_trait::async_trait]
88#[allow(unused_variables)]
89pub trait VirtualNetworking: fmt::Debug + Send + Sync + 'static {
90 async fn bridge(
93 &self,
94 network: &str,
95 access_token: &str,
96 security: StreamSecurity,
97 ) -> Result<()> {
98 Err(NetworkError::Unsupported)
99 }
100
101 async fn unbridge(&self) -> Result<()> {
103 Err(NetworkError::Unsupported)
104 }
105
106 async fn dhcp_acquire(&self) -> Result<Vec<IpAddr>> {
108 Err(NetworkError::Unsupported)
109 }
110
111 async fn ip_add(&self, ip: IpAddr, prefix: u8) -> Result<()> {
113 Err(NetworkError::Unsupported)
114 }
115
116 async fn ip_remove(&self, ip: IpAddr) -> Result<()> {
118 Err(NetworkError::Unsupported)
119 }
120
121 async fn ip_clear(&self) -> Result<()> {
123 Err(NetworkError::Unsupported)
124 }
125
126 async fn ip_list(&self) -> Result<Vec<IpCidr>> {
128 Err(NetworkError::Unsupported)
129 }
130
131 async fn mac(&self) -> Result<[u8; 6]> {
133 Err(NetworkError::Unsupported)
134 }
135
136 async fn gateway_set(&self, ip: IpAddr) -> Result<()> {
138 Err(NetworkError::Unsupported)
139 }
140
141 async fn route_add(
143 &self,
144 cidr: IpCidr,
145 via_router: IpAddr,
146 preferred_until: Option<Duration>,
147 expires_at: Option<Duration>,
148 ) -> Result<()> {
149 Err(NetworkError::Unsupported)
150 }
151
152 async fn route_remove(&self, cidr: IpAddr) -> Result<()> {
154 Err(NetworkError::Unsupported)
155 }
156
157 async fn route_clear(&self) -> Result<()> {
159 Err(NetworkError::Unsupported)
160 }
161
162 async fn route_list(&self) -> Result<Vec<IpRoute>> {
164 Err(NetworkError::Unsupported)
165 }
166
167 async fn bind_raw(&self) -> Result<Box<dyn VirtualRawSocket + Sync>> {
170 Err(NetworkError::Unsupported)
171 }
172
173 async fn listen_tcp(
177 &self,
178 addr: SocketAddr,
179 only_v6: bool,
180 reuse_port: bool,
181 reuse_addr: bool,
182 ) -> Result<Box<dyn VirtualTcpListener + Sync>> {
183 Err(NetworkError::Unsupported)
184 }
185
186 async fn bind_udp(
190 &self,
191 addr: SocketAddr,
192 reuse_port: bool,
193 reuse_addr: bool,
194 ) -> Result<Box<dyn VirtualUdpSocket + Sync>> {
195 Err(NetworkError::Unsupported)
196 }
197
198 async fn bind_icmp(&self, addr: IpAddr) -> Result<Box<dyn VirtualIcmpSocket + Sync>> {
201 Err(NetworkError::Unsupported)
202 }
203
204 async fn connect_tcp(
206 &self,
207 addr: SocketAddr,
208 peer: SocketAddr,
209 ) -> Result<Box<dyn VirtualTcpSocket + Sync>> {
210 Err(NetworkError::Unsupported)
211 }
212
213 async fn resolve(
215 &self,
216 host: &str,
217 port: Option<u16>,
218 dns_server: Option<IpAddr>,
219 ) -> Result<Vec<IpAddr>> {
220 Err(NetworkError::Unsupported)
221 }
222}
223
224pub type DynVirtualNetworking = Arc<dyn VirtualNetworking>;
225
226pub trait VirtualTcpListener: VirtualIoSource + fmt::Debug + Send + Sync + 'static {
227 fn try_accept(&mut self) -> Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)>;
229
230 fn set_handler(&mut self, handler: Box<dyn InterestHandler + Send + Sync>) -> Result<()>;
233
234 fn addr_local(&self) -> Result<SocketAddr>;
236
237 fn set_ttl(&mut self, ttl: u8) -> Result<()>;
239
240 fn ttl(&self) -> Result<u8>;
242}
243
244#[async_trait::async_trait]
245pub trait VirtualTcpListenerExt: VirtualTcpListener {
246 async fn accept(&mut self) -> Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)>;
248}
249
250#[async_trait::async_trait]
251impl<R: VirtualTcpListener + ?Sized> VirtualTcpListenerExt for R {
252 async fn accept(&mut self) -> Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)> {
253 struct Poller<'a, R>
254 where
255 R: VirtualTcpListener + ?Sized,
256 {
257 listener: &'a mut R,
258 }
259 impl<R> std::future::Future for Poller<'_, R>
260 where
261 R: VirtualTcpListener + ?Sized,
262 {
263 type Output = Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)>;
264 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
265 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
266 if let Err(err) = self.listener.set_handler(handler) {
267 return Poll::Ready(Err(err));
268 }
269 match self.listener.try_accept() {
270 Ok(ret) => Poll::Ready(Ok(ret)),
271 Err(NetworkError::WouldBlock) => Poll::Pending,
272 Err(err) => Poll::Ready(Err(err)),
273 }
274 }
275 }
276 Poller { listener: self }.await
277 }
278}
279
280pub trait VirtualSocket: VirtualIoSource + fmt::Debug + Send + Sync + 'static {
281 fn set_ttl(&mut self, ttl: u32) -> Result<()>;
283
284 fn ttl(&self) -> Result<u32>;
286
287 fn addr_local(&self) -> Result<SocketAddr>;
289
290 fn status(&self) -> Result<SocketStatus>;
292
293 fn set_handler(&mut self, handler: Box<dyn InterestHandler + Send + Sync>) -> Result<()>;
297}
298
299#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
300pub enum SocketStatus {
301 Opening,
302 Opened,
303 Closed,
304 Failed,
305}
306
307#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
308pub enum StreamSecurity {
309 Unencrypted,
310 AnyEncyption,
311 ClassicEncryption,
312 DoubleEncryption,
313}
314
315pub trait VirtualConnectedSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
317 fn set_linger(&mut self, linger: Option<Duration>) -> Result<()>;
322
323 fn linger(&self) -> Result<Option<Duration>>;
326
327 fn try_send(&mut self, data: &[u8]) -> Result<usize>;
329
330 fn try_flush(&mut self) -> Result<()>;
332
333 fn close(&mut self) -> Result<()>;
335
336 fn try_recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize>;
338}
339
340#[async_trait::async_trait]
341pub trait VirtualConnectedSocketExt: VirtualConnectedSocket {
342 async fn send(&mut self, data: &[u8]) -> Result<usize>;
343
344 async fn recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize>;
345
346 async fn flush(&mut self) -> Result<()>;
347}
348
349#[async_trait::async_trait]
350impl<R: VirtualConnectedSocket + ?Sized> VirtualConnectedSocketExt for R {
351 async fn send(&mut self, data: &[u8]) -> Result<usize> {
352 pin_project! {
353 struct Poller<'a, 'b, R: ?Sized>
354 where
355 R: VirtualConnectedSocket,
356 {
357 socket: &'a mut R,
358 data: &'b [u8],
359 }
360 }
361 impl<R> std::future::Future for Poller<'_, '_, R>
362 where
363 R: VirtualConnectedSocket + ?Sized,
364 {
365 type Output = Result<usize>;
366 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
367 let this = self.project();
368
369 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
370 if let Err(err) = this.socket.set_handler(handler) {
371 return Poll::Ready(Err(err));
372 }
373 match this.socket.try_send(this.data) {
374 Ok(ret) => Poll::Ready(Ok(ret)),
375 Err(NetworkError::WouldBlock) => Poll::Pending,
376 Err(err) => Poll::Ready(Err(err)),
377 }
378 }
379 }
380 Poller { socket: self, data }.await
381 }
382
383 async fn recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize> {
384 pin_project! {
385 struct Poller<'a, 'b, R: ?Sized>
386 where
387 R: VirtualConnectedSocket,
388 {
389 socket: &'a mut R,
390 buf: &'b mut [MaybeUninit<u8>],
391 peek: bool,
392 }
393 }
394 impl<R> std::future::Future for Poller<'_, '_, R>
395 where
396 R: VirtualConnectedSocket + ?Sized,
397 {
398 type Output = Result<usize>;
399 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
400 let this = self.project();
401
402 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
403 if let Err(err) = this.socket.set_handler(handler) {
404 return Poll::Ready(Err(err));
405 }
406 match this.socket.try_recv(this.buf, *this.peek) {
407 Ok(ret) => Poll::Ready(Ok(ret)),
408 Err(NetworkError::WouldBlock) => Poll::Pending,
409 Err(err) => Poll::Ready(Err(err)),
410 }
411 }
412 }
413 Poller {
414 socket: self,
415 buf,
416 peek,
417 }
418 .await
419 }
420
421 async fn flush(&mut self) -> Result<()> {
422 struct Poller<'a, R>
423 where
424 R: VirtualConnectedSocket + ?Sized,
425 {
426 socket: &'a mut R,
427 }
428 impl<R> std::future::Future for Poller<'_, R>
429 where
430 R: VirtualConnectedSocket + ?Sized,
431 {
432 type Output = Result<()>;
433 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
434 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
435 if let Err(err) = self.socket.set_handler(handler) {
436 return Poll::Ready(Err(err));
437 }
438 match self.socket.try_flush() {
439 Ok(ret) => Poll::Ready(Ok(ret)),
440 Err(NetworkError::WouldBlock) => Poll::Pending,
441 Err(err) => Poll::Ready(Err(err)),
442 }
443 }
444 }
445 Poller { socket: self }.await
446 }
447}
448
449pub trait VirtualConnectionlessSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
452 fn try_send_to(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize>;
455
456 fn try_recv_from(
458 &mut self,
459 buf: &mut [MaybeUninit<u8>],
460 peek: bool,
461 ) -> Result<(usize, SocketAddr)>;
462}
463
464#[async_trait::async_trait]
465pub trait VirtualConnectionlessSocketExt: VirtualConnectionlessSocket {
466 async fn send_to(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize>;
467
468 async fn recv_from(
469 &mut self,
470 buf: &mut [MaybeUninit<u8>],
471 peek: bool,
472 ) -> Result<(usize, SocketAddr)>;
473}
474
475#[async_trait::async_trait]
476impl<R: VirtualConnectionlessSocket + ?Sized> VirtualConnectionlessSocketExt for R {
477 async fn send_to(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize> {
478 pin_project! {
479 struct Poller<'a, 'b, R: ?Sized>
480 where
481 R: VirtualConnectionlessSocket,
482 {
483 socket: &'a mut R,
484 data: &'b [u8],
485 addr: SocketAddr,
486 }
487 }
488 impl<R> std::future::Future for Poller<'_, '_, R>
489 where
490 R: VirtualConnectionlessSocket + ?Sized,
491 {
492 type Output = Result<usize>;
493 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
494 let this = self.project();
495
496 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
497 if let Err(err) = this.socket.set_handler(handler) {
498 return Poll::Ready(Err(err));
499 }
500 match this.socket.try_send_to(this.data, *this.addr) {
501 Ok(ret) => Poll::Ready(Ok(ret)),
502 Err(NetworkError::WouldBlock) => Poll::Pending,
503 Err(err) => Poll::Ready(Err(err)),
504 }
505 }
506 }
507 Poller {
508 socket: self,
509 data,
510 addr,
511 }
512 .await
513 }
514
515 async fn recv_from(
516 &mut self,
517 buf: &mut [MaybeUninit<u8>],
518 peek: bool,
519 ) -> Result<(usize, SocketAddr)> {
520 pin_project! {
521 struct Poller<'a, 'b, R: ?Sized>
522 where
523 R: VirtualConnectionlessSocket,
524 {
525 socket: &'a mut R,
526 buf: &'b mut [MaybeUninit<u8>],
527 peek: bool,
528 }
529 }
530 impl<R> std::future::Future for Poller<'_, '_, R>
531 where
532 R: VirtualConnectionlessSocket + ?Sized,
533 {
534 type Output = Result<(usize, SocketAddr)>;
535 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
536 let this = self.project();
537
538 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
539 if let Err(err) = this.socket.set_handler(handler) {
540 return Poll::Ready(Err(err));
541 }
542 match this.socket.try_recv_from(this.buf, *this.peek) {
543 Ok(ret) => Poll::Ready(Ok(ret)),
544 Err(NetworkError::WouldBlock) => Poll::Pending,
545 Err(err) => Poll::Ready(Err(err)),
546 }
547 }
548 }
549 Poller {
550 socket: self,
551 buf,
552 peek,
553 }
554 .await
555 }
556}
557
558pub trait VirtualIcmpSocket:
561 VirtualConnectionlessSocket + fmt::Debug + Send + Sync + 'static
562{
563}
564
565#[async_trait::async_trait]
566pub trait VirtualRawSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
567 fn try_send(&mut self, data: &[u8]) -> Result<usize>;
569
570 fn try_flush(&mut self) -> Result<()>;
573
574 fn try_recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize>;
576
577 fn set_promiscuous(&mut self, promiscuous: bool) -> Result<()>;
581
582 fn promiscuous(&self) -> Result<bool>;
586}
587
588pub trait VirtualTcpSocket: VirtualConnectedSocket + fmt::Debug + Send + Sync + 'static {
589 fn set_recv_buf_size(&mut self, size: usize) -> Result<()>;
592
593 fn recv_buf_size(&self) -> Result<usize>;
596
597 fn set_send_buf_size(&mut self, size: usize) -> Result<()>;
600
601 fn send_buf_size(&self) -> Result<usize>;
604
605 fn set_nodelay(&mut self, reuse: bool) -> Result<()>;
610
611 fn nodelay(&self) -> Result<bool>;
615
616 fn set_keepalive(&mut self, keepalive: bool) -> Result<()>;
620
621 fn keepalive(&self) -> Result<bool>;
625
626 fn set_dontroute(&mut self, keepalive: bool) -> Result<()>;
629
630 fn dontroute(&self) -> Result<bool>;
633
634 fn addr_peer(&self) -> Result<SocketAddr>;
637
638 fn shutdown(&mut self, how: Shutdown) -> Result<()>;
641
642 fn is_closed(&self) -> bool;
644}
645
646#[cfg(feature = "tokio")]
647impl<'a> AsyncRead for Box<dyn VirtualTcpSocket + Sync + 'a> {
648 fn poll_read(
649 self: Pin<&mut Self>,
650 cx: &mut Context<'_>,
651 buf: &mut tokio::io::ReadBuf<'_>,
652 ) -> Poll<std::io::Result<()>> {
653 let this = self.get_mut();
654 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
655 if let Err(err) = this.set_handler(handler) {
656 return Poll::Ready(Err(net_error_into_io_err(err)));
657 }
658 let buf_unsafe = unsafe { buf.unfilled_mut() };
659 match this.try_recv(buf_unsafe) {
660 Ok(ret) => {
661 unsafe { buf.assume_init(ret) };
662 buf.set_filled(ret);
663 Poll::Ready(Ok(()))
664 }
665 Err(NetworkError::WouldBlock) => Poll::Pending,
666 Err(err) => Poll::Ready(Err(net_error_into_io_err(err))),
667 }
668 }
669}
670
671#[cfg(feature = "tokio")]
672impl<'a> AsyncWrite for Box<dyn VirtualTcpSocket + Sync + 'a> {
673 fn poll_write(
674 self: Pin<&mut Self>,
675 cx: &mut Context<'_>,
676 buf: &[u8],
677 ) -> Poll<std::io::Result<usize>> {
678 let this = self.get_mut();
679 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
680 if let Err(err) = this.set_handler(handler) {
681 return Poll::Ready(Err(net_error_into_io_err(err)));
682 }
683 match this.try_send(buf) {
684 Ok(ret) => Poll::Ready(Ok(ret)),
685 Err(NetworkError::WouldBlock) => Poll::Pending,
686 Err(err) => Poll::Ready(Err(net_error_into_io_err(err))),
687 }
688 }
689
690 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
691 let this = self.get_mut();
692 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
693 if let Err(err) = this.set_handler(handler) {
694 return Poll::Ready(Err(net_error_into_io_err(err)));
695 }
696 match this.try_flush() {
697 Ok(()) => Poll::Ready(Ok(())),
698 Err(NetworkError::WouldBlock) => Poll::Pending,
699 Err(err) => Poll::Ready(Err(net_error_into_io_err(err))),
700 }
701 }
702
703 fn poll_shutdown(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
704 Poll::Ready(
705 self.shutdown(Shutdown::Write)
706 .map_err(net_error_into_io_err),
707 )
708 }
709}
710
711pub trait VirtualUdpSocket:
712 VirtualConnectionlessSocket + fmt::Debug + Send + Sync + 'static
713{
714 fn set_broadcast(&mut self, broadcast: bool) -> Result<()>;
717
718 fn broadcast(&self) -> Result<bool>;
722
723 fn set_multicast_loop_v4(&mut self, val: bool) -> Result<()>;
727
728 fn multicast_loop_v4(&self) -> Result<bool>;
732
733 fn set_multicast_loop_v6(&mut self, val: bool) -> Result<()>;
737
738 fn multicast_loop_v6(&self) -> Result<bool>;
742
743 fn set_multicast_ttl_v4(&mut self, ttl: u32) -> Result<()>;
746
747 fn multicast_ttl_v4(&self) -> Result<u32>;
750
751 fn join_multicast_v4(&mut self, multiaddr: Ipv4Addr, iface: Ipv4Addr) -> Result<()>;
754
755 fn leave_multicast_v4(&mut self, multiaddr: Ipv4Addr, iface: Ipv4Addr) -> Result<()>;
758
759 fn join_multicast_v6(&mut self, multiaddr: Ipv6Addr, iface: u32) -> Result<()>;
762
763 fn leave_multicast_v6(&mut self, multiaddr: Ipv6Addr, iface: u32) -> Result<()>;
766
767 fn addr_peer(&self) -> Result<Option<SocketAddr>>;
770}
771
772#[derive(Debug, Default)]
773pub struct UnsupportedVirtualNetworking {}
774
775#[async_trait::async_trait]
776impl VirtualNetworking for UnsupportedVirtualNetworking {}
777
778#[derive(Error, Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
779pub enum NetworkError {
780 #[error("invalid fd")]
782 InvalidFd,
783 #[error("file exists")]
785 AlreadyExists,
786 #[error("lock error")]
788 Lock,
789 #[error("io error")]
792 IOError,
793 #[error("address is in use")]
795 AddressInUse,
796 #[error("address could not be found")]
798 AddressNotAvailable,
799 #[error("broken pipe (was closed)")]
801 BrokenPipe,
802 #[error("Insufficient memory")]
804 InsufficientMemory,
805 #[error("connection aborted")]
807 ConnectionAborted,
808 #[error("connection refused")]
810 ConnectionRefused,
811 #[error("connection reset")]
813 ConnectionReset,
814 #[error("operation interrupted")]
816 Interrupted,
817 #[error("invalid internal data")]
819 InvalidData,
820 #[error("invalid input")]
822 InvalidInput,
823 #[error("connection is not open")]
825 NotConnected,
826 #[error("can't access device")]
828 NoDevice,
829 #[error("permission denied")]
831 PermissionDenied,
832 #[error("time out")]
834 TimedOut,
835 #[error("unexpected eof")]
837 UnexpectedEof,
838 #[error("blocking operation. try again")]
840 WouldBlock,
841 #[error("write returned 0")]
843 WriteZero,
844 #[error("too many open files")]
846 TooManyOpenFiles,
847 #[error("unsupported")]
849 Unsupported,
850 #[error("unknown error found")]
852 UnknownError,
853}
854
855pub fn io_err_into_net_error(net_error: std::io::Error) -> NetworkError {
856 use std::io::ErrorKind;
857 match net_error.kind() {
858 ErrorKind::BrokenPipe => NetworkError::BrokenPipe,
859 ErrorKind::AlreadyExists => NetworkError::AlreadyExists,
860 ErrorKind::AddrInUse => NetworkError::AddressInUse,
861 ErrorKind::AddrNotAvailable => NetworkError::AddressNotAvailable,
862 ErrorKind::ConnectionAborted => NetworkError::ConnectionAborted,
863 ErrorKind::ConnectionRefused => NetworkError::ConnectionRefused,
864 ErrorKind::ConnectionReset => NetworkError::ConnectionReset,
865 ErrorKind::Interrupted => NetworkError::Interrupted,
866 ErrorKind::InvalidData => NetworkError::InvalidData,
867 ErrorKind::InvalidInput => NetworkError::InvalidInput,
868 ErrorKind::NotConnected => NetworkError::NotConnected,
869 ErrorKind::PermissionDenied => NetworkError::PermissionDenied,
870 ErrorKind::TimedOut => NetworkError::TimedOut,
871 ErrorKind::UnexpectedEof => NetworkError::UnexpectedEof,
872 ErrorKind::WouldBlock => NetworkError::WouldBlock,
873 ErrorKind::WriteZero => NetworkError::WriteZero,
874 ErrorKind::Unsupported => NetworkError::Unsupported,
875
876 #[cfg(all(target_family = "unix", feature = "libc"))]
877 _ => {
878 if let Some(code) = net_error.raw_os_error() {
879 match code {
880 libc::EPERM => NetworkError::PermissionDenied,
881 libc::EBADF => NetworkError::InvalidFd,
882 libc::ECHILD => NetworkError::InvalidFd,
883 libc::EMFILE => NetworkError::TooManyOpenFiles,
884 libc::EINTR => NetworkError::Interrupted,
885 libc::EIO => NetworkError::IOError,
886 libc::ENXIO => NetworkError::IOError,
887 libc::EAGAIN => NetworkError::WouldBlock,
888 libc::ENOMEM => NetworkError::InsufficientMemory,
889 libc::EACCES => NetworkError::PermissionDenied,
890 libc::ENODEV => NetworkError::NoDevice,
891 libc::EINVAL => NetworkError::InvalidInput,
892 libc::EPIPE => NetworkError::BrokenPipe,
893 err => {
894 tracing::trace!("unknown os error {}", err);
895 NetworkError::UnknownError
896 }
897 }
898 } else {
899 NetworkError::UnknownError
900 }
901 }
902 #[cfg(not(all(target_family = "unix", feature = "libc")))]
903 _ => NetworkError::UnknownError,
904 }
905}
906
907pub fn net_error_into_io_err(net_error: NetworkError) -> std::io::Error {
908 use std::io::ErrorKind;
909 match net_error {
910 NetworkError::InvalidFd => ErrorKind::BrokenPipe.into(),
911 NetworkError::AlreadyExists => ErrorKind::AlreadyExists.into(),
912 NetworkError::Lock => ErrorKind::BrokenPipe.into(),
913 NetworkError::IOError => ErrorKind::BrokenPipe.into(),
914 NetworkError::AddressInUse => ErrorKind::AddrInUse.into(),
915 NetworkError::AddressNotAvailable => ErrorKind::AddrNotAvailable.into(),
916 NetworkError::BrokenPipe => ErrorKind::BrokenPipe.into(),
917 NetworkError::ConnectionAborted => ErrorKind::ConnectionAborted.into(),
918 NetworkError::ConnectionRefused => ErrorKind::ConnectionRefused.into(),
919 NetworkError::ConnectionReset => ErrorKind::ConnectionReset.into(),
920 NetworkError::Interrupted => ErrorKind::Interrupted.into(),
921 NetworkError::InvalidData => ErrorKind::InvalidData.into(),
922 NetworkError::InvalidInput => ErrorKind::InvalidInput.into(),
923 NetworkError::NotConnected => ErrorKind::NotConnected.into(),
924 NetworkError::NoDevice => ErrorKind::BrokenPipe.into(),
925 NetworkError::PermissionDenied => ErrorKind::PermissionDenied.into(),
926 NetworkError::TimedOut => ErrorKind::TimedOut.into(),
927 NetworkError::UnexpectedEof => ErrorKind::UnexpectedEof.into(),
928 NetworkError::WouldBlock => ErrorKind::WouldBlock.into(),
929 NetworkError::WriteZero => ErrorKind::WriteZero.into(),
930 NetworkError::Unsupported => ErrorKind::Unsupported.into(),
931 NetworkError::UnknownError => ErrorKind::BrokenPipe.into(),
932 NetworkError::InsufficientMemory => ErrorKind::OutOfMemory.into(),
933 NetworkError::TooManyOpenFiles => {
934 #[cfg(all(target_family = "unix", feature = "libc"))]
935 {
936 std::io::Error::from_raw_os_error(libc::EMFILE)
937 }
938 #[cfg(not(all(target_family = "unix", feature = "libc")))]
939 {
940 ErrorKind::Other.into()
941 }
942 }
943 }
944}