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#[non_exhaustive]
817#[derive(Error, Copy, Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
818pub enum NetworkError {
819 #[error("invalid fd")]
821 InvalidFd,
822 #[error("file exists")]
824 AlreadyExists,
825 #[error("lock error")]
827 Lock,
828 #[error("io error")]
831 IOError,
832 #[error("address is in use")]
834 AddressInUse,
835 #[error("address could not be found")]
837 AddressNotAvailable,
838 #[error("broken pipe (was closed)")]
840 BrokenPipe,
841 #[error("Insufficient memory")]
843 InsufficientMemory,
844 #[error("connection aborted")]
846 ConnectionAborted,
847 #[error("connection refused")]
849 ConnectionRefused,
850 #[error("connection reset")]
852 ConnectionReset,
853 #[error("operation interrupted")]
855 Interrupted,
856 #[error("invalid internal data")]
858 InvalidData,
859 #[error("invalid input")]
861 InvalidInput,
862 #[error("message too large")]
864 MessageSize,
865 #[error("connection is not open")]
867 NotConnected,
868 #[error("can't access device")]
870 NoDevice,
871 #[error("permission denied")]
873 PermissionDenied,
874 #[error("time out")]
876 TimedOut,
877 #[error("unexpected eof")]
879 UnexpectedEof,
880 #[error("blocking operation. try again")]
882 WouldBlock,
883 #[error("write returned 0")]
885 WriteZero,
886 #[error("too many open files")]
888 TooManyOpenFiles,
889 #[error("unsupported")]
891 Unsupported,
892 #[error("network unreachable")]
894 NetworkUnreachable,
895 #[error("host unreachable")]
897 HostUnreachable,
898 #[error("unknown error found")]
900 UnknownError,
901}
902
903pub fn io_err_into_net_error(net_error: std::io::Error) -> NetworkError {
904 use std::io::ErrorKind;
905 match net_error.kind() {
906 ErrorKind::BrokenPipe => NetworkError::BrokenPipe,
907 ErrorKind::AlreadyExists => NetworkError::AlreadyExists,
908 ErrorKind::AddrInUse => NetworkError::AddressInUse,
909 ErrorKind::AddrNotAvailable => NetworkError::AddressNotAvailable,
910 ErrorKind::ConnectionAborted => NetworkError::ConnectionAborted,
911 ErrorKind::ConnectionRefused => NetworkError::ConnectionRefused,
912 ErrorKind::ConnectionReset => NetworkError::ConnectionReset,
913 ErrorKind::Interrupted => NetworkError::Interrupted,
914 ErrorKind::InvalidData => NetworkError::InvalidData,
915 ErrorKind::InvalidInput => {
916 #[cfg(all(target_family = "unix", feature = "libc"))]
917 if net_error.raw_os_error() == Some(libc::EMSGSIZE) {
918 return NetworkError::MessageSize;
919 }
920 NetworkError::InvalidInput
921 }
922 ErrorKind::NotConnected => NetworkError::NotConnected,
923 ErrorKind::PermissionDenied => NetworkError::PermissionDenied,
924 ErrorKind::TimedOut => NetworkError::TimedOut,
925 ErrorKind::UnexpectedEof => NetworkError::UnexpectedEof,
926 ErrorKind::WouldBlock => NetworkError::WouldBlock,
927 ErrorKind::NetworkUnreachable => NetworkError::NetworkUnreachable,
928 ErrorKind::HostUnreachable => NetworkError::HostUnreachable,
929 ErrorKind::WriteZero => NetworkError::WriteZero,
930 ErrorKind::Unsupported => NetworkError::Unsupported,
931
932 #[cfg(all(target_family = "unix", feature = "libc"))]
933 _ => {
934 if let Some(code) = net_error.raw_os_error() {
935 match code {
936 libc::EPERM => NetworkError::PermissionDenied,
937 libc::EBADF => NetworkError::InvalidFd,
938 libc::ECHILD => NetworkError::InvalidFd,
939 libc::EMFILE => NetworkError::TooManyOpenFiles,
940 libc::EINTR => NetworkError::Interrupted,
941 libc::EIO => NetworkError::IOError,
942 libc::ENXIO => NetworkError::IOError,
943 libc::EAGAIN => NetworkError::WouldBlock,
944 libc::ENOMEM => NetworkError::InsufficientMemory,
945 libc::EACCES => NetworkError::PermissionDenied,
946 libc::ENODEV => NetworkError::NoDevice,
947 libc::EINVAL => NetworkError::InvalidInput,
948 libc::EMSGSIZE => NetworkError::MessageSize,
949 libc::EPIPE => NetworkError::BrokenPipe,
950 libc::ENETUNREACH => NetworkError::NetworkUnreachable,
951 libc::EHOSTUNREACH => NetworkError::HostUnreachable,
952 err => {
953 tracing::trace!("unknown os error {}", err);
954 NetworkError::UnknownError
955 }
956 }
957 } else {
958 NetworkError::UnknownError
959 }
960 }
961 #[cfg(not(all(target_family = "unix", feature = "libc")))]
962 _ => NetworkError::UnknownError,
963 }
964}
965
966pub fn net_error_into_io_err(net_error: NetworkError) -> std::io::Error {
967 use std::io::ErrorKind;
968 match net_error {
969 NetworkError::InvalidFd => ErrorKind::BrokenPipe.into(),
970 NetworkError::AlreadyExists => ErrorKind::AlreadyExists.into(),
971 NetworkError::Lock => ErrorKind::BrokenPipe.into(),
972 NetworkError::IOError => ErrorKind::BrokenPipe.into(),
973 NetworkError::AddressInUse => ErrorKind::AddrInUse.into(),
974 NetworkError::AddressNotAvailable => ErrorKind::AddrNotAvailable.into(),
975 NetworkError::BrokenPipe => ErrorKind::BrokenPipe.into(),
976 NetworkError::ConnectionAborted => ErrorKind::ConnectionAborted.into(),
977 NetworkError::ConnectionRefused => ErrorKind::ConnectionRefused.into(),
978 NetworkError::ConnectionReset => ErrorKind::ConnectionReset.into(),
979 NetworkError::Interrupted => ErrorKind::Interrupted.into(),
980 NetworkError::InvalidData => ErrorKind::InvalidData.into(),
981 NetworkError::InvalidInput => ErrorKind::InvalidInput.into(),
982 NetworkError::NotConnected => ErrorKind::NotConnected.into(),
983 NetworkError::NoDevice => ErrorKind::BrokenPipe.into(),
984 NetworkError::PermissionDenied => ErrorKind::PermissionDenied.into(),
985 NetworkError::TimedOut => ErrorKind::TimedOut.into(),
986 NetworkError::UnexpectedEof => ErrorKind::UnexpectedEof.into(),
987 NetworkError::WouldBlock => ErrorKind::WouldBlock.into(),
988 NetworkError::NetworkUnreachable => ErrorKind::NetworkUnreachable.into(),
989 NetworkError::HostUnreachable => ErrorKind::HostUnreachable.into(),
990 NetworkError::WriteZero => ErrorKind::WriteZero.into(),
991 NetworkError::Unsupported => ErrorKind::Unsupported.into(),
992 NetworkError::UnknownError => ErrorKind::BrokenPipe.into(),
993 NetworkError::InsufficientMemory => ErrorKind::OutOfMemory.into(),
994 NetworkError::MessageSize => {
995 #[cfg(all(target_family = "unix", feature = "libc"))]
996 {
997 std::io::Error::from_raw_os_error(libc::EMSGSIZE)
998 }
999 #[cfg(not(all(target_family = "unix", feature = "libc")))]
1000 {
1001 ErrorKind::Other.into()
1002 }
1003 }
1004 NetworkError::TooManyOpenFiles => {
1005 #[cfg(all(target_family = "unix", feature = "libc"))]
1006 {
1007 std::io::Error::from_raw_os_error(libc::EMFILE)
1008 }
1009 #[cfg(not(all(target_family = "unix", feature = "libc")))]
1010 {
1011 ErrorKind::Other.into()
1012 }
1013 }
1014 }
1015}