1#![cfg_attr(docsrs, feature(doc_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_tcp(
189 &self,
190 addr: SocketAddr,
191 only_v6: bool,
192 reuse_port: bool,
193 reuse_addr: bool,
194 ) -> Result<Box<dyn VirtualTcpBoundSocket + Sync>> {
195 Err(NetworkError::Unsupported)
196 }
197
198 async fn bind_udp(
202 &self,
203 addr: SocketAddr,
204 reuse_port: bool,
205 reuse_addr: bool,
206 ) -> Result<Box<dyn VirtualUdpSocket + Sync>> {
207 Err(NetworkError::Unsupported)
208 }
209
210 async fn bind_icmp(&self, addr: IpAddr) -> Result<Box<dyn VirtualIcmpSocket + Sync>> {
213 Err(NetworkError::Unsupported)
214 }
215
216 async fn connect_tcp(
218 &self,
219 addr: SocketAddr,
220 peer: SocketAddr,
221 ) -> Result<Box<dyn VirtualTcpSocket + Sync>> {
222 Err(NetworkError::Unsupported)
223 }
224
225 async fn resolve(
227 &self,
228 host: &str,
229 port: Option<u16>,
230 dns_server: Option<IpAddr>,
231 ) -> Result<Vec<IpAddr>> {
232 Err(NetworkError::Unsupported)
233 }
234}
235
236pub type DynVirtualNetworking = Arc<dyn VirtualNetworking>;
237
238pub trait VirtualTcpListener: VirtualIoSource + fmt::Debug + Send + Sync + 'static {
239 fn try_accept(&mut self) -> Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)>;
241
242 fn set_handler(&mut self, handler: Box<dyn InterestHandler + Send + Sync>) -> Result<()>;
245
246 fn addr_local(&self) -> Result<SocketAddr>;
248
249 fn set_ttl(&mut self, ttl: u8) -> Result<()>;
251
252 fn ttl(&self) -> Result<u8>;
254}
255
256pub trait VirtualTcpBoundSocket: fmt::Debug + Send + Sync + 'static {
257 fn addr_local(&self) -> Result<SocketAddr>;
259
260 fn listen(&mut self) -> Result<Box<dyn VirtualTcpListener + Sync>>;
262
263 fn connect(&mut self, peer: SocketAddr) -> Result<Box<dyn VirtualTcpSocket + Sync>>;
265
266 fn set_ttl(&mut self, ttl: u32) -> Result<()>;
268
269 fn ttl(&self) -> Result<u32>;
271}
272
273#[async_trait::async_trait]
274pub trait VirtualTcpListenerExt: VirtualTcpListener {
275 async fn accept(&mut self) -> Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)>;
277}
278
279#[async_trait::async_trait]
280impl<R: VirtualTcpListener + ?Sized> VirtualTcpListenerExt for R {
281 async fn accept(&mut self) -> Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)> {
282 struct Poller<'a, R>
283 where
284 R: VirtualTcpListener + ?Sized,
285 {
286 listener: &'a mut R,
287 }
288 impl<R> std::future::Future for Poller<'_, R>
289 where
290 R: VirtualTcpListener + ?Sized,
291 {
292 type Output = Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)>;
293 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
294 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
295 if let Err(err) = self.listener.set_handler(handler) {
296 return Poll::Ready(Err(err));
297 }
298 match self.listener.try_accept() {
299 Ok(ret) => Poll::Ready(Ok(ret)),
300 Err(NetworkError::WouldBlock) => Poll::Pending,
301 Err(err) => Poll::Ready(Err(err)),
302 }
303 }
304 }
305 Poller { listener: self }.await
306 }
307}
308
309pub trait VirtualSocket: VirtualIoSource + fmt::Debug + Send + Sync + 'static {
310 fn set_ttl(&mut self, ttl: u32) -> Result<()>;
312
313 fn ttl(&self) -> Result<u32>;
315
316 fn addr_local(&self) -> Result<SocketAddr>;
318
319 fn status(&self) -> Result<SocketStatus>;
321
322 fn set_handler(&mut self, handler: Box<dyn InterestHandler + Send + Sync>) -> Result<()>;
326}
327
328#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
329pub enum SocketStatus {
330 Opening,
331 Opened,
332 Closed,
333 Failed,
334}
335
336#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
337pub enum StreamSecurity {
338 Unencrypted,
339 AnyEncryption,
340 ClassicEncryption,
341 DoubleEncryption,
342}
343
344pub trait VirtualConnectedSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
346 fn set_linger(&mut self, linger: Option<Duration>) -> Result<()>;
351
352 fn linger(&self) -> Result<Option<Duration>>;
355
356 fn try_send(&mut self, data: &[u8]) -> Result<usize>;
358
359 fn try_flush(&mut self) -> Result<()>;
361
362 fn close(&mut self) -> Result<()>;
364
365 fn try_recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize>;
367}
368
369#[async_trait::async_trait]
370pub trait VirtualConnectedSocketExt: VirtualConnectedSocket {
371 async fn send(&mut self, data: &[u8]) -> Result<usize>;
372
373 async fn recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize>;
374
375 async fn flush(&mut self) -> Result<()>;
376}
377
378#[async_trait::async_trait]
379impl<R: VirtualConnectedSocket + ?Sized> VirtualConnectedSocketExt for R {
380 async fn send(&mut self, data: &[u8]) -> Result<usize> {
381 pin_project! {
382 struct Poller<'a, 'b, R: ?Sized>
383 where
384 R: VirtualConnectedSocket,
385 {
386 socket: &'a mut R,
387 data: &'b [u8],
388 }
389 }
390 impl<R> std::future::Future for Poller<'_, '_, R>
391 where
392 R: VirtualConnectedSocket + ?Sized,
393 {
394 type Output = Result<usize>;
395 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
396 let this = self.project();
397
398 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
399 if let Err(err) = this.socket.set_handler(handler) {
400 return Poll::Ready(Err(err));
401 }
402 match this.socket.try_send(this.data) {
403 Ok(ret) => Poll::Ready(Ok(ret)),
404 Err(NetworkError::WouldBlock) => Poll::Pending,
405 Err(err) => Poll::Ready(Err(err)),
406 }
407 }
408 }
409 Poller { socket: self, data }.await
410 }
411
412 async fn recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize> {
413 pin_project! {
414 struct Poller<'a, 'b, R: ?Sized>
415 where
416 R: VirtualConnectedSocket,
417 {
418 socket: &'a mut R,
419 buf: &'b mut [MaybeUninit<u8>],
420 peek: bool,
421 }
422 }
423 impl<R> std::future::Future for Poller<'_, '_, R>
424 where
425 R: VirtualConnectedSocket + ?Sized,
426 {
427 type Output = Result<usize>;
428 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
429 let this = self.project();
430
431 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
432 if let Err(err) = this.socket.set_handler(handler) {
433 return Poll::Ready(Err(err));
434 }
435 match this.socket.try_recv(this.buf, *this.peek) {
436 Ok(ret) => Poll::Ready(Ok(ret)),
437 Err(NetworkError::WouldBlock) => Poll::Pending,
438 Err(err) => Poll::Ready(Err(err)),
439 }
440 }
441 }
442 Poller {
443 socket: self,
444 buf,
445 peek,
446 }
447 .await
448 }
449
450 async fn flush(&mut self) -> Result<()> {
451 struct Poller<'a, R>
452 where
453 R: VirtualConnectedSocket + ?Sized,
454 {
455 socket: &'a mut R,
456 }
457 impl<R> std::future::Future for Poller<'_, R>
458 where
459 R: VirtualConnectedSocket + ?Sized,
460 {
461 type Output = Result<()>;
462 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
463 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
464 if let Err(err) = self.socket.set_handler(handler) {
465 return Poll::Ready(Err(err));
466 }
467 match self.socket.try_flush() {
468 Ok(ret) => Poll::Ready(Ok(ret)),
469 Err(NetworkError::WouldBlock) => Poll::Pending,
470 Err(err) => Poll::Ready(Err(err)),
471 }
472 }
473 }
474 Poller { socket: self }.await
475 }
476}
477
478pub trait VirtualConnectionlessSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
481 fn try_send_to(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize>;
484
485 fn try_recv_from(
487 &mut self,
488 buf: &mut [MaybeUninit<u8>],
489 peek: bool,
490 ) -> Result<(usize, SocketAddr)>;
491}
492
493#[async_trait::async_trait]
494pub trait VirtualConnectionlessSocketExt: VirtualConnectionlessSocket {
495 async fn send_to(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize>;
496
497 async fn recv_from(
498 &mut self,
499 buf: &mut [MaybeUninit<u8>],
500 peek: bool,
501 ) -> Result<(usize, SocketAddr)>;
502}
503
504#[async_trait::async_trait]
505impl<R: VirtualConnectionlessSocket + ?Sized> VirtualConnectionlessSocketExt for R {
506 async fn send_to(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize> {
507 pin_project! {
508 struct Poller<'a, 'b, R: ?Sized>
509 where
510 R: VirtualConnectionlessSocket,
511 {
512 socket: &'a mut R,
513 data: &'b [u8],
514 addr: SocketAddr,
515 }
516 }
517 impl<R> std::future::Future for Poller<'_, '_, R>
518 where
519 R: VirtualConnectionlessSocket + ?Sized,
520 {
521 type Output = Result<usize>;
522 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
523 let this = self.project();
524
525 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
526 if let Err(err) = this.socket.set_handler(handler) {
527 return Poll::Ready(Err(err));
528 }
529 match this.socket.try_send_to(this.data, *this.addr) {
530 Ok(ret) => Poll::Ready(Ok(ret)),
531 Err(NetworkError::WouldBlock) => Poll::Pending,
532 Err(err) => Poll::Ready(Err(err)),
533 }
534 }
535 }
536 Poller {
537 socket: self,
538 data,
539 addr,
540 }
541 .await
542 }
543
544 async fn recv_from(
545 &mut self,
546 buf: &mut [MaybeUninit<u8>],
547 peek: bool,
548 ) -> Result<(usize, SocketAddr)> {
549 pin_project! {
550 struct Poller<'a, 'b, R: ?Sized>
551 where
552 R: VirtualConnectionlessSocket,
553 {
554 socket: &'a mut R,
555 buf: &'b mut [MaybeUninit<u8>],
556 peek: bool,
557 }
558 }
559 impl<R> std::future::Future for Poller<'_, '_, R>
560 where
561 R: VirtualConnectionlessSocket + ?Sized,
562 {
563 type Output = Result<(usize, SocketAddr)>;
564 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
565 let this = self.project();
566
567 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
568 if let Err(err) = this.socket.set_handler(handler) {
569 return Poll::Ready(Err(err));
570 }
571 match this.socket.try_recv_from(this.buf, *this.peek) {
572 Ok(ret) => Poll::Ready(Ok(ret)),
573 Err(NetworkError::WouldBlock) => Poll::Pending,
574 Err(err) => Poll::Ready(Err(err)),
575 }
576 }
577 }
578 Poller {
579 socket: self,
580 buf,
581 peek,
582 }
583 .await
584 }
585}
586
587pub trait VirtualIcmpSocket:
590 VirtualConnectionlessSocket + fmt::Debug + Send + Sync + 'static
591{
592}
593
594#[async_trait::async_trait]
595pub trait VirtualRawSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
596 fn try_send(&mut self, data: &[u8]) -> Result<usize>;
598
599 fn try_flush(&mut self) -> Result<()>;
602
603 fn try_recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize>;
605
606 fn set_promiscuous(&mut self, promiscuous: bool) -> Result<()>;
610
611 fn promiscuous(&self) -> Result<bool>;
615}
616
617pub trait VirtualTcpSocket: VirtualConnectedSocket + fmt::Debug + Send + Sync + 'static {
618 fn set_recv_buf_size(&mut self, size: usize) -> Result<()>;
621
622 fn recv_buf_size(&self) -> Result<usize>;
625
626 fn set_send_buf_size(&mut self, size: usize) -> Result<()>;
629
630 fn send_buf_size(&self) -> Result<usize>;
633
634 fn set_nodelay(&mut self, reuse: bool) -> Result<()>;
639
640 fn nodelay(&self) -> Result<bool>;
644
645 fn set_keepalive(&mut self, keepalive: bool) -> Result<()>;
649
650 fn keepalive(&self) -> Result<bool>;
654
655 fn set_dontroute(&mut self, keepalive: bool) -> Result<()>;
658
659 fn dontroute(&self) -> Result<bool>;
662
663 fn addr_peer(&self) -> Result<SocketAddr>;
666
667 fn shutdown(&mut self, how: Shutdown) -> Result<()>;
670
671 fn is_closed(&self) -> bool;
673}
674
675#[cfg(feature = "tokio")]
676impl<'a> AsyncRead for Box<dyn VirtualTcpSocket + Sync + 'a> {
677 fn poll_read(
678 self: Pin<&mut Self>,
679 cx: &mut Context<'_>,
680 buf: &mut tokio::io::ReadBuf<'_>,
681 ) -> Poll<std::io::Result<()>> {
682 let this = self.get_mut();
683 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
684 if let Err(err) = this.set_handler(handler) {
685 return Poll::Ready(Err(net_error_into_io_err(err)));
686 }
687 let buf_unsafe = unsafe { buf.unfilled_mut() };
688 match this.try_recv(buf_unsafe, false) {
689 Ok(ret) => {
690 unsafe { buf.assume_init(ret) };
691 buf.set_filled(ret);
692 Poll::Ready(Ok(()))
693 }
694 Err(NetworkError::WouldBlock) => Poll::Pending,
695 Err(err) => Poll::Ready(Err(net_error_into_io_err(err))),
696 }
697 }
698}
699
700#[cfg(feature = "tokio")]
701impl<'a> AsyncWrite for Box<dyn VirtualTcpSocket + Sync + 'a> {
702 fn poll_write(
703 self: Pin<&mut Self>,
704 cx: &mut Context<'_>,
705 buf: &[u8],
706 ) -> Poll<std::io::Result<usize>> {
707 let this = self.get_mut();
708 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
709 if let Err(err) = this.set_handler(handler) {
710 return Poll::Ready(Err(net_error_into_io_err(err)));
711 }
712 match this.try_send(buf) {
713 Ok(ret) => Poll::Ready(Ok(ret)),
714 Err(NetworkError::WouldBlock) => Poll::Pending,
715 Err(err) => Poll::Ready(Err(net_error_into_io_err(err))),
716 }
717 }
718
719 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
720 let this = self.get_mut();
721 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
722 if let Err(err) = this.set_handler(handler) {
723 return Poll::Ready(Err(net_error_into_io_err(err)));
724 }
725 match this.try_flush() {
726 Ok(()) => Poll::Ready(Ok(())),
727 Err(NetworkError::WouldBlock) => Poll::Pending,
728 Err(err) => Poll::Ready(Err(net_error_into_io_err(err))),
729 }
730 }
731
732 fn poll_shutdown(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
733 Poll::Ready(
734 self.shutdown(Shutdown::Write)
735 .map_err(net_error_into_io_err),
736 )
737 }
738}
739
740pub trait VirtualUdpSocket:
741 VirtualConnectionlessSocket + fmt::Debug + Send + Sync + 'static
742{
743 fn set_broadcast(&mut self, broadcast: bool) -> Result<()>;
746
747 fn broadcast(&self) -> Result<bool>;
751
752 fn set_multicast_loop_v4(&mut self, val: bool) -> Result<()>;
756
757 fn multicast_loop_v4(&self) -> Result<bool>;
761
762 fn set_multicast_loop_v6(&mut self, val: bool) -> Result<()>;
766
767 fn multicast_loop_v6(&self) -> Result<bool>;
771
772 fn set_multicast_ttl_v4(&mut self, ttl: u32) -> Result<()>;
775
776 fn multicast_ttl_v4(&self) -> Result<u32>;
779
780 fn join_multicast_v4(&mut self, multiaddr: Ipv4Addr, iface: Ipv4Addr) -> Result<()>;
783
784 fn leave_multicast_v4(&mut self, multiaddr: Ipv4Addr, iface: Ipv4Addr) -> Result<()>;
787
788 fn join_multicast_v6(&mut self, multiaddr: Ipv6Addr, iface: u32) -> Result<()>;
791
792 fn leave_multicast_v6(&mut self, multiaddr: Ipv6Addr, iface: u32) -> Result<()>;
795
796 fn addr_peer(&self) -> Result<Option<SocketAddr>>;
799}
800
801#[derive(Debug, Default)]
802pub struct UnsupportedVirtualNetworking {}
803
804#[async_trait::async_trait]
805impl VirtualNetworking for UnsupportedVirtualNetworking {}
806
807#[derive(Error, Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
808pub enum NetworkError {
809 #[error("invalid fd")]
811 InvalidFd,
812 #[error("file exists")]
814 AlreadyExists,
815 #[error("lock error")]
817 Lock,
818 #[error("io error")]
821 IOError,
822 #[error("address is in use")]
824 AddressInUse,
825 #[error("address could not be found")]
827 AddressNotAvailable,
828 #[error("broken pipe (was closed)")]
830 BrokenPipe,
831 #[error("Insufficient memory")]
833 InsufficientMemory,
834 #[error("connection aborted")]
836 ConnectionAborted,
837 #[error("connection refused")]
839 ConnectionRefused,
840 #[error("connection reset")]
842 ConnectionReset,
843 #[error("operation interrupted")]
845 Interrupted,
846 #[error("invalid internal data")]
848 InvalidData,
849 #[error("invalid input")]
851 InvalidInput,
852 #[error("connection is not open")]
854 NotConnected,
855 #[error("can't access device")]
857 NoDevice,
858 #[error("permission denied")]
860 PermissionDenied,
861 #[error("time out")]
863 TimedOut,
864 #[error("unexpected eof")]
866 UnexpectedEof,
867 #[error("blocking operation. try again")]
869 WouldBlock,
870 #[error("write returned 0")]
872 WriteZero,
873 #[error("too many open files")]
875 TooManyOpenFiles,
876 #[error("unsupported")]
878 Unsupported,
879 #[error("unknown error found")]
881 UnknownError,
882}
883
884pub fn io_err_into_net_error(net_error: std::io::Error) -> NetworkError {
885 use std::io::ErrorKind;
886 match net_error.kind() {
887 ErrorKind::BrokenPipe => NetworkError::BrokenPipe,
888 ErrorKind::AlreadyExists => NetworkError::AlreadyExists,
889 ErrorKind::AddrInUse => NetworkError::AddressInUse,
890 ErrorKind::AddrNotAvailable => NetworkError::AddressNotAvailable,
891 ErrorKind::ConnectionAborted => NetworkError::ConnectionAborted,
892 ErrorKind::ConnectionRefused => NetworkError::ConnectionRefused,
893 ErrorKind::ConnectionReset => NetworkError::ConnectionReset,
894 ErrorKind::Interrupted => NetworkError::Interrupted,
895 ErrorKind::InvalidData => NetworkError::InvalidData,
896 ErrorKind::InvalidInput => NetworkError::InvalidInput,
897 ErrorKind::NotConnected => NetworkError::NotConnected,
898 ErrorKind::PermissionDenied => NetworkError::PermissionDenied,
899 ErrorKind::TimedOut => NetworkError::TimedOut,
900 ErrorKind::UnexpectedEof => NetworkError::UnexpectedEof,
901 ErrorKind::WouldBlock => NetworkError::WouldBlock,
902 ErrorKind::WriteZero => NetworkError::WriteZero,
903 ErrorKind::Unsupported => NetworkError::Unsupported,
904
905 #[cfg(all(target_family = "unix", feature = "libc"))]
906 _ => {
907 if let Some(code) = net_error.raw_os_error() {
908 match code {
909 libc::EPERM => NetworkError::PermissionDenied,
910 libc::EBADF => NetworkError::InvalidFd,
911 libc::ECHILD => NetworkError::InvalidFd,
912 libc::EMFILE => NetworkError::TooManyOpenFiles,
913 libc::EINTR => NetworkError::Interrupted,
914 libc::EIO => NetworkError::IOError,
915 libc::ENXIO => NetworkError::IOError,
916 libc::EAGAIN => NetworkError::WouldBlock,
917 libc::ENOMEM => NetworkError::InsufficientMemory,
918 libc::EACCES => NetworkError::PermissionDenied,
919 libc::ENODEV => NetworkError::NoDevice,
920 libc::EINVAL => NetworkError::InvalidInput,
921 libc::EPIPE => NetworkError::BrokenPipe,
922 err => {
923 tracing::trace!("unknown os error {}", err);
924 NetworkError::UnknownError
925 }
926 }
927 } else {
928 NetworkError::UnknownError
929 }
930 }
931 #[cfg(not(all(target_family = "unix", feature = "libc")))]
932 _ => NetworkError::UnknownError,
933 }
934}
935
936pub fn net_error_into_io_err(net_error: NetworkError) -> std::io::Error {
937 use std::io::ErrorKind;
938 match net_error {
939 NetworkError::InvalidFd => ErrorKind::BrokenPipe.into(),
940 NetworkError::AlreadyExists => ErrorKind::AlreadyExists.into(),
941 NetworkError::Lock => ErrorKind::BrokenPipe.into(),
942 NetworkError::IOError => ErrorKind::BrokenPipe.into(),
943 NetworkError::AddressInUse => ErrorKind::AddrInUse.into(),
944 NetworkError::AddressNotAvailable => ErrorKind::AddrNotAvailable.into(),
945 NetworkError::BrokenPipe => ErrorKind::BrokenPipe.into(),
946 NetworkError::ConnectionAborted => ErrorKind::ConnectionAborted.into(),
947 NetworkError::ConnectionRefused => ErrorKind::ConnectionRefused.into(),
948 NetworkError::ConnectionReset => ErrorKind::ConnectionReset.into(),
949 NetworkError::Interrupted => ErrorKind::Interrupted.into(),
950 NetworkError::InvalidData => ErrorKind::InvalidData.into(),
951 NetworkError::InvalidInput => ErrorKind::InvalidInput.into(),
952 NetworkError::NotConnected => ErrorKind::NotConnected.into(),
953 NetworkError::NoDevice => ErrorKind::BrokenPipe.into(),
954 NetworkError::PermissionDenied => ErrorKind::PermissionDenied.into(),
955 NetworkError::TimedOut => ErrorKind::TimedOut.into(),
956 NetworkError::UnexpectedEof => ErrorKind::UnexpectedEof.into(),
957 NetworkError::WouldBlock => ErrorKind::WouldBlock.into(),
958 NetworkError::WriteZero => ErrorKind::WriteZero.into(),
959 NetworkError::Unsupported => ErrorKind::Unsupported.into(),
960 NetworkError::UnknownError => ErrorKind::BrokenPipe.into(),
961 NetworkError::InsufficientMemory => ErrorKind::OutOfMemory.into(),
962 NetworkError::TooManyOpenFiles => {
963 #[cfg(all(target_family = "unix", feature = "libc"))]
964 {
965 std::io::Error::from_raw_os_error(libc::EMFILE)
966 }
967 #[cfg(not(all(target_family = "unix", feature = "libc")))]
968 {
969 ErrorKind::Other.into()
970 }
971 }
972 }
973}