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
56pub const MAX_SOCKET_PAYLOAD: usize = 65535 - 8;
59
60#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, Serialize, Deserialize)]
62#[cfg_attr(feature = "rkyv", derive(RkyvSerialize, RkyvDeserialize, Archive))]
63pub struct IpCidr {
64 pub ip: IpAddr,
65 pub prefix: u8,
66}
67
68#[derive(Clone, Debug, Serialize, Deserialize)]
70#[cfg_attr(feature = "rkyv", derive(RkyvSerialize, RkyvDeserialize, Archive))]
71pub struct IpRoute {
72 pub cidr: IpCidr,
73 pub via_router: IpAddr,
74 pub preferred_until: Option<Duration>,
75 pub expires_at: Option<Duration>,
76}
77
78pub trait VirtualIoSource: fmt::Debug + Send + Sync + 'static {
80 fn remove_handler(&mut self);
82
83 fn poll_read_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<usize>>;
85
86 fn poll_write_ready(&mut self, cx: &mut Context<'_>) -> Poll<Result<usize>>;
88}
89
90#[async_trait::async_trait]
92#[allow(unused_variables)]
93pub trait VirtualNetworking: fmt::Debug + Send + Sync + 'static {
94 async fn bridge(
97 &self,
98 network: &str,
99 access_token: &str,
100 security: StreamSecurity,
101 ) -> Result<()> {
102 Err(NetworkError::Unsupported)
103 }
104
105 async fn unbridge(&self) -> Result<()> {
107 Err(NetworkError::Unsupported)
108 }
109
110 async fn dhcp_acquire(&self) -> Result<Vec<IpAddr>> {
112 Err(NetworkError::Unsupported)
113 }
114
115 async fn ip_add(&self, ip: IpAddr, prefix: u8) -> Result<()> {
117 Err(NetworkError::Unsupported)
118 }
119
120 async fn ip_remove(&self, ip: IpAddr) -> Result<()> {
122 Err(NetworkError::Unsupported)
123 }
124
125 async fn ip_clear(&self) -> Result<()> {
127 Err(NetworkError::Unsupported)
128 }
129
130 async fn ip_list(&self) -> Result<Vec<IpCidr>> {
132 Err(NetworkError::Unsupported)
133 }
134
135 async fn mac(&self) -> Result<[u8; 6]> {
137 Err(NetworkError::Unsupported)
138 }
139
140 async fn gateway_set(&self, ip: IpAddr) -> Result<()> {
142 Err(NetworkError::Unsupported)
143 }
144
145 async fn route_add(
147 &self,
148 cidr: IpCidr,
149 via_router: IpAddr,
150 preferred_until: Option<Duration>,
151 expires_at: Option<Duration>,
152 ) -> Result<()> {
153 Err(NetworkError::Unsupported)
154 }
155
156 async fn route_remove(&self, cidr: IpAddr) -> Result<()> {
158 Err(NetworkError::Unsupported)
159 }
160
161 async fn route_clear(&self) -> Result<()> {
163 Err(NetworkError::Unsupported)
164 }
165
166 async fn route_list(&self) -> Result<Vec<IpRoute>> {
168 Err(NetworkError::Unsupported)
169 }
170
171 async fn bind_raw(&self) -> Result<Box<dyn VirtualRawSocket + Sync>> {
174 Err(NetworkError::Unsupported)
175 }
176
177 async fn listen_tcp(
181 &self,
182 addr: SocketAddr,
183 only_v6: bool,
184 reuse_port: bool,
185 reuse_addr: bool,
186 ) -> Result<Box<dyn VirtualTcpListener + Sync>> {
187 Err(NetworkError::Unsupported)
188 }
189
190 async fn bind_tcp(
193 &self,
194 addr: SocketAddr,
195 only_v6: bool,
196 reuse_port: bool,
197 reuse_addr: bool,
198 ) -> Result<Box<dyn VirtualTcpBoundSocket + Sync>> {
199 Err(NetworkError::Unsupported)
200 }
201
202 async fn bind_udp(
206 &self,
207 addr: SocketAddr,
208 reuse_port: bool,
209 reuse_addr: bool,
210 ) -> Result<Box<dyn VirtualUdpSocket + Sync>> {
211 Err(NetworkError::Unsupported)
212 }
213
214 async fn bind_icmp(&self, addr: IpAddr) -> Result<Box<dyn VirtualIcmpSocket + Sync>> {
217 Err(NetworkError::Unsupported)
218 }
219
220 async fn connect_tcp(
222 &self,
223 addr: SocketAddr,
224 peer: SocketAddr,
225 ) -> Result<Box<dyn VirtualTcpSocket + Sync>> {
226 Err(NetworkError::Unsupported)
227 }
228
229 async fn resolve(
231 &self,
232 host: &str,
233 port: Option<u16>,
234 dns_server: Option<IpAddr>,
235 ) -> Result<Vec<IpAddr>> {
236 Err(NetworkError::Unsupported)
237 }
238}
239
240pub type DynVirtualNetworking = Arc<dyn VirtualNetworking>;
241
242pub trait VirtualTcpListener: VirtualIoSource + fmt::Debug + Send + Sync + 'static {
243 fn try_accept(&mut self) -> Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)>;
245
246 fn set_handler(&mut self, handler: Box<dyn InterestHandler + Send + Sync>) -> Result<()>;
249
250 fn addr_local(&self) -> Result<SocketAddr>;
252
253 fn set_ttl(&mut self, ttl: u8) -> Result<()>;
255
256 fn ttl(&self) -> Result<u8>;
258}
259
260pub trait VirtualTcpBoundSocket: fmt::Debug + Send + Sync + 'static {
261 fn addr_local(&self) -> Result<SocketAddr>;
263
264 fn listen(&mut self) -> Result<Box<dyn VirtualTcpListener + Sync>>;
266
267 fn connect(&mut self, peer: SocketAddr) -> Result<Box<dyn VirtualTcpSocket + Sync>>;
269
270 fn set_ttl(&mut self, ttl: u32) -> Result<()>;
272
273 fn ttl(&self) -> Result<u32>;
275}
276
277#[async_trait::async_trait]
278pub trait VirtualTcpListenerExt: VirtualTcpListener {
279 async fn accept(&mut self) -> Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)>;
281}
282
283#[async_trait::async_trait]
284impl<R: VirtualTcpListener + ?Sized> VirtualTcpListenerExt for R {
285 async fn accept(&mut self) -> Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)> {
286 struct Poller<'a, R>
287 where
288 R: VirtualTcpListener + ?Sized,
289 {
290 listener: &'a mut R,
291 }
292 impl<R> std::future::Future for Poller<'_, R>
293 where
294 R: VirtualTcpListener + ?Sized,
295 {
296 type Output = Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)>;
297 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
298 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
299 if let Err(err) = self.listener.set_handler(handler) {
300 return Poll::Ready(Err(err));
301 }
302 match self.listener.try_accept() {
303 Ok(ret) => Poll::Ready(Ok(ret)),
304 Err(NetworkError::WouldBlock) => Poll::Pending,
305 Err(err) => Poll::Ready(Err(err)),
306 }
307 }
308 }
309 Poller { listener: self }.await
310 }
311}
312
313pub trait VirtualSocket: VirtualIoSource + fmt::Debug + Send + Sync + 'static {
314 fn set_ttl(&mut self, ttl: u32) -> Result<()>;
316
317 fn ttl(&self) -> Result<u32>;
319
320 fn addr_local(&self) -> Result<SocketAddr>;
322
323 fn status(&self) -> Result<SocketStatus>;
325
326 fn last_error(&self) -> Result<Option<NetworkError>> {
328 Ok(None)
329 }
330
331 fn set_handler(&mut self, handler: Box<dyn InterestHandler + Send + Sync>) -> Result<()>;
335}
336
337#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
338pub enum SocketStatus {
339 Opening,
340 Opened,
341 Closed,
342 Failed,
343}
344
345#[derive(Debug, Copy, Clone, PartialEq, Eq, Serialize, Deserialize)]
346pub enum StreamSecurity {
347 Unencrypted,
348 AnyEncryption,
349 ClassicEncryption,
350 DoubleEncryption,
351}
352
353pub trait VirtualConnectedSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
355 fn set_linger(&mut self, linger: Option<Duration>) -> Result<()>;
360
361 fn linger(&self) -> Result<Option<Duration>>;
364
365 fn try_send(&mut self, data: &[u8]) -> Result<usize>;
367
368 fn try_flush(&mut self) -> Result<()>;
370
371 fn close(&mut self) -> Result<()>;
373
374 fn try_recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize>;
376}
377
378#[async_trait::async_trait]
379pub trait VirtualConnectedSocketExt: VirtualConnectedSocket {
380 async fn send(&mut self, data: &[u8]) -> Result<usize>;
381
382 async fn recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize>;
383
384 async fn flush(&mut self) -> Result<()>;
385}
386
387#[async_trait::async_trait]
388impl<R: VirtualConnectedSocket + ?Sized> VirtualConnectedSocketExt for R {
389 async fn send(&mut self, data: &[u8]) -> Result<usize> {
390 pin_project! {
391 struct Poller<'a, 'b, R: ?Sized>
392 where
393 R: VirtualConnectedSocket,
394 {
395 socket: &'a mut R,
396 data: &'b [u8],
397 }
398 }
399 impl<R> std::future::Future for Poller<'_, '_, R>
400 where
401 R: VirtualConnectedSocket + ?Sized,
402 {
403 type Output = Result<usize>;
404 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
405 let this = self.project();
406
407 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
408 if let Err(err) = this.socket.set_handler(handler) {
409 return Poll::Ready(Err(err));
410 }
411 match this.socket.try_send(this.data) {
412 Ok(ret) => Poll::Ready(Ok(ret)),
413 Err(NetworkError::WouldBlock) => Poll::Pending,
414 Err(err) => Poll::Ready(Err(err)),
415 }
416 }
417 }
418 Poller { socket: self, data }.await
419 }
420
421 async fn recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize> {
422 pin_project! {
423 struct Poller<'a, 'b, R: ?Sized>
424 where
425 R: VirtualConnectedSocket,
426 {
427 socket: &'a mut R,
428 buf: &'b mut [MaybeUninit<u8>],
429 peek: bool,
430 }
431 }
432 impl<R> std::future::Future for Poller<'_, '_, R>
433 where
434 R: VirtualConnectedSocket + ?Sized,
435 {
436 type Output = Result<usize>;
437 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
438 let this = self.project();
439
440 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
441 if let Err(err) = this.socket.set_handler(handler) {
442 return Poll::Ready(Err(err));
443 }
444 match this.socket.try_recv(this.buf, *this.peek) {
445 Ok(ret) => Poll::Ready(Ok(ret)),
446 Err(NetworkError::WouldBlock) => Poll::Pending,
447 Err(err) => Poll::Ready(Err(err)),
448 }
449 }
450 }
451 Poller {
452 socket: self,
453 buf,
454 peek,
455 }
456 .await
457 }
458
459 async fn flush(&mut self) -> Result<()> {
460 struct Poller<'a, R>
461 where
462 R: VirtualConnectedSocket + ?Sized,
463 {
464 socket: &'a mut R,
465 }
466 impl<R> std::future::Future for Poller<'_, R>
467 where
468 R: VirtualConnectedSocket + ?Sized,
469 {
470 type Output = Result<()>;
471 fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
472 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
473 if let Err(err) = self.socket.set_handler(handler) {
474 return Poll::Ready(Err(err));
475 }
476 match self.socket.try_flush() {
477 Ok(ret) => Poll::Ready(Ok(ret)),
478 Err(NetworkError::WouldBlock) => Poll::Pending,
479 Err(err) => Poll::Ready(Err(err)),
480 }
481 }
482 }
483 Poller { socket: self }.await
484 }
485}
486
487pub trait VirtualConnectionlessSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
490 fn try_send_to(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize>;
493
494 fn try_recv_from(
496 &mut self,
497 buf: &mut [MaybeUninit<u8>],
498 peek: bool,
499 ) -> Result<(usize, SocketAddr)>;
500}
501
502#[async_trait::async_trait]
503pub trait VirtualConnectionlessSocketExt: VirtualConnectionlessSocket {
504 async fn send_to(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize>;
505
506 async fn recv_from(
507 &mut self,
508 buf: &mut [MaybeUninit<u8>],
509 peek: bool,
510 ) -> Result<(usize, SocketAddr)>;
511}
512
513#[async_trait::async_trait]
514impl<R: VirtualConnectionlessSocket + ?Sized> VirtualConnectionlessSocketExt for R {
515 async fn send_to(&mut self, data: &[u8], addr: SocketAddr) -> Result<usize> {
516 pin_project! {
517 struct Poller<'a, 'b, R: ?Sized>
518 where
519 R: VirtualConnectionlessSocket,
520 {
521 socket: &'a mut R,
522 data: &'b [u8],
523 addr: SocketAddr,
524 }
525 }
526 impl<R> std::future::Future for Poller<'_, '_, R>
527 where
528 R: VirtualConnectionlessSocket + ?Sized,
529 {
530 type Output = Result<usize>;
531 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
532 let this = self.project();
533
534 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
535 if let Err(err) = this.socket.set_handler(handler) {
536 return Poll::Ready(Err(err));
537 }
538 match this.socket.try_send_to(this.data, *this.addr) {
539 Ok(ret) => Poll::Ready(Ok(ret)),
540 Err(NetworkError::WouldBlock) => Poll::Pending,
541 Err(err) => Poll::Ready(Err(err)),
542 }
543 }
544 }
545 Poller {
546 socket: self,
547 data,
548 addr,
549 }
550 .await
551 }
552
553 async fn recv_from(
554 &mut self,
555 buf: &mut [MaybeUninit<u8>],
556 peek: bool,
557 ) -> Result<(usize, SocketAddr)> {
558 pin_project! {
559 struct Poller<'a, 'b, R: ?Sized>
560 where
561 R: VirtualConnectionlessSocket,
562 {
563 socket: &'a mut R,
564 buf: &'b mut [MaybeUninit<u8>],
565 peek: bool,
566 }
567 }
568 impl<R> std::future::Future for Poller<'_, '_, R>
569 where
570 R: VirtualConnectionlessSocket + ?Sized,
571 {
572 type Output = Result<(usize, SocketAddr)>;
573 fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
574 let this = self.project();
575
576 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
577 if let Err(err) = this.socket.set_handler(handler) {
578 return Poll::Ready(Err(err));
579 }
580 match this.socket.try_recv_from(this.buf, *this.peek) {
581 Ok(ret) => Poll::Ready(Ok(ret)),
582 Err(NetworkError::WouldBlock) => Poll::Pending,
583 Err(err) => Poll::Ready(Err(err)),
584 }
585 }
586 }
587 Poller {
588 socket: self,
589 buf,
590 peek,
591 }
592 .await
593 }
594}
595
596pub trait VirtualIcmpSocket:
599 VirtualConnectionlessSocket + fmt::Debug + Send + Sync + 'static
600{
601}
602
603#[async_trait::async_trait]
604pub trait VirtualRawSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
605 fn try_send(&mut self, data: &[u8]) -> Result<usize>;
607
608 fn try_flush(&mut self) -> Result<()>;
611
612 fn try_recv(&mut self, buf: &mut [MaybeUninit<u8>], peek: bool) -> Result<usize>;
614
615 fn set_promiscuous(&mut self, promiscuous: bool) -> Result<()>;
619
620 fn promiscuous(&self) -> Result<bool>;
624}
625
626pub trait VirtualTcpSocket: VirtualConnectedSocket + fmt::Debug + Send + Sync + 'static {
627 fn set_recv_buf_size(&mut self, size: usize) -> Result<()>;
630
631 fn recv_buf_size(&self) -> Result<usize>;
634
635 fn set_send_buf_size(&mut self, size: usize) -> Result<()>;
638
639 fn send_buf_size(&self) -> Result<usize>;
642
643 fn set_nodelay(&mut self, reuse: bool) -> Result<()>;
648
649 fn nodelay(&self) -> Result<bool>;
653
654 fn set_keepalive(&mut self, keepalive: bool) -> Result<()>;
658
659 fn keepalive(&self) -> Result<bool>;
663
664 fn set_dontroute(&mut self, keepalive: bool) -> Result<()>;
667
668 fn dontroute(&self) -> Result<bool>;
671
672 fn addr_peer(&self) -> Result<SocketAddr>;
675
676 fn shutdown(&mut self, how: Shutdown) -> Result<()>;
679
680 fn is_closed(&self) -> bool;
682}
683
684#[cfg(feature = "tokio")]
685impl<'a> AsyncRead for Box<dyn VirtualTcpSocket + Sync + 'a> {
686 fn poll_read(
687 self: Pin<&mut Self>,
688 cx: &mut Context<'_>,
689 buf: &mut tokio::io::ReadBuf<'_>,
690 ) -> 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 let buf_unsafe = unsafe { buf.unfilled_mut() };
697 match this.try_recv(buf_unsafe, false) {
698 Ok(ret) => {
699 unsafe { buf.assume_init(ret) };
700 buf.set_filled(ret);
701 Poll::Ready(Ok(()))
702 }
703 Err(NetworkError::WouldBlock) => Poll::Pending,
704 Err(err) => Poll::Ready(Err(net_error_into_io_err(err))),
705 }
706 }
707}
708
709#[cfg(feature = "tokio")]
710impl<'a> AsyncWrite for Box<dyn VirtualTcpSocket + Sync + 'a> {
711 fn poll_write(
712 self: Pin<&mut Self>,
713 cx: &mut Context<'_>,
714 buf: &[u8],
715 ) -> Poll<std::io::Result<usize>> {
716 let this = self.get_mut();
717 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
718 if let Err(err) = this.set_handler(handler) {
719 return Poll::Ready(Err(net_error_into_io_err(err)));
720 }
721 match this.try_send(buf) {
722 Ok(ret) => Poll::Ready(Ok(ret)),
723 Err(NetworkError::WouldBlock) => Poll::Pending,
724 Err(err) => Poll::Ready(Err(net_error_into_io_err(err))),
725 }
726 }
727
728 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
729 let this = self.get_mut();
730 let handler: Box<dyn InterestHandler + Send + Sync> = cx.waker().into();
731 if let Err(err) = this.set_handler(handler) {
732 return Poll::Ready(Err(net_error_into_io_err(err)));
733 }
734 match this.try_flush() {
735 Ok(()) => Poll::Ready(Ok(())),
736 Err(NetworkError::WouldBlock) => Poll::Pending,
737 Err(err) => Poll::Ready(Err(net_error_into_io_err(err))),
738 }
739 }
740
741 fn poll_shutdown(mut self: Pin<&mut Self>, _cx: &mut Context<'_>) -> Poll<std::io::Result<()>> {
742 Poll::Ready(
743 self.shutdown(Shutdown::Write)
744 .map_err(net_error_into_io_err),
745 )
746 }
747}
748
749pub trait VirtualUdpSocket:
750 VirtualConnectionlessSocket + fmt::Debug + Send + Sync + 'static
751{
752 fn set_broadcast(&mut self, broadcast: bool) -> Result<()>;
755
756 fn broadcast(&self) -> Result<bool>;
760
761 fn set_multicast_loop_v4(&mut self, val: bool) -> Result<()>;
765
766 fn multicast_loop_v4(&self) -> Result<bool>;
770
771 fn set_multicast_loop_v6(&mut self, val: bool) -> Result<()>;
775
776 fn multicast_loop_v6(&self) -> Result<bool>;
780
781 fn set_multicast_ttl_v4(&mut self, ttl: u32) -> Result<()>;
784
785 fn multicast_ttl_v4(&self) -> Result<u32>;
788
789 fn join_multicast_v4(&mut self, multiaddr: Ipv4Addr, iface: Ipv4Addr) -> Result<()>;
792
793 fn leave_multicast_v4(&mut self, multiaddr: Ipv4Addr, iface: Ipv4Addr) -> Result<()>;
796
797 fn join_multicast_v6(&mut self, multiaddr: Ipv6Addr, iface: u32) -> Result<()>;
800
801 fn leave_multicast_v6(&mut self, multiaddr: Ipv6Addr, iface: u32) -> Result<()>;
804
805 fn addr_peer(&self) -> Result<Option<SocketAddr>>;
808}
809
810#[derive(Debug, Default)]
811pub struct UnsupportedVirtualNetworking {}
812
813#[async_trait::async_trait]
814impl VirtualNetworking for UnsupportedVirtualNetworking {}
815
816#[derive(Error, Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
817pub enum NetworkError {
818 #[error("invalid fd")]
820 InvalidFd,
821 #[error("file exists")]
823 AlreadyExists,
824 #[error("lock error")]
826 Lock,
827 #[error("io error")]
830 IOError,
831 #[error("address is in use")]
833 AddressInUse,
834 #[error("address could not be found")]
836 AddressNotAvailable,
837 #[error("broken pipe (was closed)")]
839 BrokenPipe,
840 #[error("Insufficient memory")]
842 InsufficientMemory,
843 #[error("connection aborted")]
845 ConnectionAborted,
846 #[error("connection refused")]
848 ConnectionRefused,
849 #[error("connection reset")]
851 ConnectionReset,
852 #[error("operation interrupted")]
854 Interrupted,
855 #[error("invalid internal data")]
857 InvalidData,
858 #[error("invalid input")]
860 InvalidInput,
861 #[error("message too large")]
863 MessageSize,
864 #[error("connection is not open")]
866 NotConnected,
867 #[error("can't access device")]
869 NoDevice,
870 #[error("permission denied")]
872 PermissionDenied,
873 #[error("time out")]
875 TimedOut,
876 #[error("unexpected eof")]
878 UnexpectedEof,
879 #[error("blocking operation. try again")]
881 WouldBlock,
882 #[error("write returned 0")]
884 WriteZero,
885 #[error("too many open files")]
887 TooManyOpenFiles,
888 #[error("unsupported")]
890 Unsupported,
891 #[error("unknown error found")]
893 UnknownError,
894}
895
896pub fn io_err_into_net_error(net_error: std::io::Error) -> NetworkError {
897 use std::io::ErrorKind;
898 match net_error.kind() {
899 ErrorKind::BrokenPipe => NetworkError::BrokenPipe,
900 ErrorKind::AlreadyExists => NetworkError::AlreadyExists,
901 ErrorKind::AddrInUse => NetworkError::AddressInUse,
902 ErrorKind::AddrNotAvailable => NetworkError::AddressNotAvailable,
903 ErrorKind::ConnectionAborted => NetworkError::ConnectionAborted,
904 ErrorKind::ConnectionRefused => NetworkError::ConnectionRefused,
905 ErrorKind::ConnectionReset => NetworkError::ConnectionReset,
906 ErrorKind::Interrupted => NetworkError::Interrupted,
907 ErrorKind::InvalidData => NetworkError::InvalidData,
908 ErrorKind::InvalidInput => {
909 #[cfg(all(target_family = "unix", feature = "libc"))]
910 if net_error.raw_os_error() == Some(libc::EMSGSIZE) {
911 return NetworkError::MessageSize;
912 }
913 NetworkError::InvalidInput
914 }
915 ErrorKind::NotConnected => NetworkError::NotConnected,
916 ErrorKind::PermissionDenied => NetworkError::PermissionDenied,
917 ErrorKind::TimedOut => NetworkError::TimedOut,
918 ErrorKind::UnexpectedEof => NetworkError::UnexpectedEof,
919 ErrorKind::WouldBlock => NetworkError::WouldBlock,
920 ErrorKind::WriteZero => NetworkError::WriteZero,
921 ErrorKind::Unsupported => NetworkError::Unsupported,
922
923 #[cfg(all(target_family = "unix", feature = "libc"))]
924 _ => {
925 if let Some(code) = net_error.raw_os_error() {
926 match code {
927 libc::EPERM => NetworkError::PermissionDenied,
928 libc::EBADF => NetworkError::InvalidFd,
929 libc::ECHILD => NetworkError::InvalidFd,
930 libc::EMFILE => NetworkError::TooManyOpenFiles,
931 libc::EINTR => NetworkError::Interrupted,
932 libc::EIO => NetworkError::IOError,
933 libc::ENXIO => NetworkError::IOError,
934 libc::EAGAIN => NetworkError::WouldBlock,
935 libc::ENOMEM => NetworkError::InsufficientMemory,
936 libc::EACCES => NetworkError::PermissionDenied,
937 libc::ENODEV => NetworkError::NoDevice,
938 libc::EINVAL => NetworkError::InvalidInput,
939 libc::EMSGSIZE => NetworkError::MessageSize,
940 libc::EPIPE => NetworkError::BrokenPipe,
941 err => {
942 tracing::trace!("unknown os error {}", err);
943 NetworkError::UnknownError
944 }
945 }
946 } else {
947 NetworkError::UnknownError
948 }
949 }
950 #[cfg(not(all(target_family = "unix", feature = "libc")))]
951 _ => NetworkError::UnknownError,
952 }
953}
954
955pub fn net_error_into_io_err(net_error: NetworkError) -> std::io::Error {
956 use std::io::ErrorKind;
957 match net_error {
958 NetworkError::InvalidFd => ErrorKind::BrokenPipe.into(),
959 NetworkError::AlreadyExists => ErrorKind::AlreadyExists.into(),
960 NetworkError::Lock => ErrorKind::BrokenPipe.into(),
961 NetworkError::IOError => ErrorKind::BrokenPipe.into(),
962 NetworkError::AddressInUse => ErrorKind::AddrInUse.into(),
963 NetworkError::AddressNotAvailable => ErrorKind::AddrNotAvailable.into(),
964 NetworkError::BrokenPipe => ErrorKind::BrokenPipe.into(),
965 NetworkError::ConnectionAborted => ErrorKind::ConnectionAborted.into(),
966 NetworkError::ConnectionRefused => ErrorKind::ConnectionRefused.into(),
967 NetworkError::ConnectionReset => ErrorKind::ConnectionReset.into(),
968 NetworkError::Interrupted => ErrorKind::Interrupted.into(),
969 NetworkError::InvalidData => ErrorKind::InvalidData.into(),
970 NetworkError::InvalidInput => ErrorKind::InvalidInput.into(),
971 NetworkError::NotConnected => ErrorKind::NotConnected.into(),
972 NetworkError::NoDevice => ErrorKind::BrokenPipe.into(),
973 NetworkError::PermissionDenied => ErrorKind::PermissionDenied.into(),
974 NetworkError::TimedOut => ErrorKind::TimedOut.into(),
975 NetworkError::UnexpectedEof => ErrorKind::UnexpectedEof.into(),
976 NetworkError::WouldBlock => ErrorKind::WouldBlock.into(),
977 NetworkError::WriteZero => ErrorKind::WriteZero.into(),
978 NetworkError::Unsupported => ErrorKind::Unsupported.into(),
979 NetworkError::UnknownError => ErrorKind::BrokenPipe.into(),
980 NetworkError::InsufficientMemory => ErrorKind::OutOfMemory.into(),
981 NetworkError::MessageSize => {
982 #[cfg(all(target_family = "unix", feature = "libc"))]
983 {
984 std::io::Error::from_raw_os_error(libc::EMSGSIZE)
985 }
986 #[cfg(not(all(target_family = "unix", feature = "libc")))]
987 {
988 ErrorKind::Other.into()
989 }
990 }
991 NetworkError::TooManyOpenFiles => {
992 #[cfg(all(target_family = "unix", feature = "libc"))]
993 {
994 std::io::Error::from_raw_os_error(libc::EMFILE)
995 }
996 #[cfg(not(all(target_family = "unix", feature = "libc")))]
997 {
998 ErrorKind::Other.into()
999 }
1000 }
1001 }
1002}