1use std::fmt;
2use std::net::IpAddr;
3use std::net::Ipv4Addr;
4use std::net::Ipv6Addr;
5use std::net::Shutdown;
6use std::net::SocketAddr;
7use std::sync::mpsc;
8use std::sync::Arc;
9use std::sync::Mutex;
10use std::time::Duration;
11use thiserror::Error;
12
13pub use bytes::Bytes;
14pub use bytes::BytesMut;
15
16pub type Result<T> = std::result::Result<T, NetworkError>;
17
18pub type SocketDescriptor = wasmer_vfs::FileDescriptor;
21
22#[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
24pub struct IpCidr {
25 pub ip: IpAddr,
26 pub prefix: u8,
27}
28
29#[derive(Clone, Debug)]
31pub struct IpRoute {
32 pub cidr: IpCidr,
33 pub via_router: IpAddr,
34 pub preferred_until: Option<Duration>,
35 pub expires_at: Option<Duration>,
36}
37
38pub trait VirtualNetworking: fmt::Debug + Send + Sync + 'static {
40 fn ws_connect(&self, url: &str) -> Result<Box<dyn VirtualWebSocket + Sync>>;
44
45 fn http_request(
50 &self,
51 url: &str,
52 method: &str,
53 headers: &str,
54 gzip: bool,
55 ) -> Result<SocketHttpRequest>;
56
57 fn bridge(&self, network: &str, access_token: &str, security: StreamSecurity) -> Result<()>;
60
61 fn unbridge(&self) -> Result<()>;
63
64 fn dhcp_acquire(&self) -> Result<Vec<IpAddr>>;
66
67 fn ip_add(&self, ip: IpAddr, prefix: u8) -> Result<()>;
69
70 fn ip_remove(&self, ip: IpAddr) -> Result<()>;
72
73 fn ip_clear(&self) -> Result<()>;
75
76 fn ip_list(&self) -> Result<Vec<IpCidr>>;
78
79 fn mac(&self) -> Result<[u8; 6]>;
81
82 fn gateway_set(&self, ip: IpAddr) -> Result<()>;
84
85 fn route_add(
87 &self,
88 cidr: IpCidr,
89 via_router: IpAddr,
90 preferred_until: Option<Duration>,
91 expires_at: Option<Duration>,
92 ) -> Result<()>;
93
94 fn route_remove(&self, cidr: IpAddr) -> Result<()>;
96
97 fn route_clear(&self) -> Result<()>;
99
100 fn route_list(&self) -> Result<Vec<IpRoute>>;
102
103 fn bind_raw(&self) -> Result<Box<dyn VirtualRawSocket + Sync>>;
106
107 fn listen_tcp(
111 &self,
112 addr: SocketAddr,
113 only_v6: bool,
114 reuse_port: bool,
115 reuse_addr: bool,
116 ) -> Result<Box<dyn VirtualTcpListener + Sync>>;
117
118 fn bind_udp(
122 &self,
123 addr: SocketAddr,
124 reuse_port: bool,
125 reuse_addr: bool,
126 ) -> Result<Box<dyn VirtualUdpSocket + Sync>>;
127
128 fn bind_icmp(&self, addr: IpAddr) -> Result<Box<dyn VirtualIcmpSocket + Sync>>;
131
132 fn connect_tcp(
134 &self,
135 addr: SocketAddr,
136 peer: SocketAddr,
137 timeout: Option<Duration>,
138 ) -> Result<Box<dyn VirtualTcpSocket + Sync>>;
139
140 fn resolve(
142 &self,
143 host: &str,
144 port: Option<u16>,
145 dns_server: Option<IpAddr>,
146 ) -> Result<Vec<IpAddr>>;
147}
148
149#[derive(Debug)]
151pub struct SocketHttpRequest {
152 pub request: Option<mpsc::Sender<Vec<u8>>>,
155 pub response: Option<mpsc::Receiver<Vec<u8>>>,
158 pub headers: Option<mpsc::Receiver<(String, String)>>,
161 pub status: Arc<Mutex<mpsc::Receiver<Result<HttpStatus>>>>,
163}
164
165#[derive(Debug)]
167pub struct HttpStatus {
168 pub redirected: bool,
170 pub size: usize,
172 pub status: u16,
174 pub status_text: String,
176}
177
178#[derive(Debug)]
179pub struct SocketReceive {
180 pub data: Bytes,
182 pub truncated: bool,
184}
185
186#[derive(Debug)]
187pub struct SocketReceiveFrom {
188 pub data: Bytes,
190 pub truncated: bool,
192 pub addr: SocketAddr,
194}
195
196pub trait VirtualTcpListener: fmt::Debug + Send + Sync + 'static {
197 fn accept(&self) -> Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)>;
199
200 fn accept_timeout(
202 &self,
203 timeout: Duration,
204 ) -> Result<(Box<dyn VirtualTcpSocket + Sync>, SocketAddr)>;
205
206 fn set_timeout(&mut self, timeout: Option<Duration>) -> Result<()>;
208
209 fn timeout(&self) -> Result<Option<Duration>>;
211
212 fn addr_local(&self) -> Result<SocketAddr>;
214
215 fn set_ttl(&mut self, ttl: u8) -> Result<()>;
217
218 fn ttl(&self) -> Result<u8>;
220}
221
222pub trait VirtualSocket: fmt::Debug + Send + Sync + 'static {
223 fn set_ttl(&mut self, ttl: u32) -> Result<()>;
225
226 fn ttl(&self) -> Result<u32>;
228
229 fn addr_local(&self) -> Result<SocketAddr>;
231
232 fn status(&self) -> Result<SocketStatus>;
234}
235
236#[derive(Debug, Copy, Clone, PartialEq, Eq)]
237pub enum SocketStatus {
238 Opening,
239 Opened,
240 Closed,
241 Failed,
242}
243
244#[derive(Debug, Copy, Clone, PartialEq, Eq)]
245pub enum StreamSecurity {
246 Unencrypted,
247 AnyEncyption,
248 ClassicEncryption,
249 DoubleEncryption,
250}
251
252pub trait VirtualWebSocket: fmt::Debug + Send + Sync + 'static {
254 fn send(&mut self, data: Bytes) -> Result<usize>;
256
257 fn flush(&mut self) -> Result<()>;
259
260 fn recv(&mut self) -> Result<SocketReceive>;
262}
263
264pub trait VirtualConnectedSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
266 fn set_linger(&mut self, linger: Option<Duration>) -> Result<()>;
271
272 fn linger(&self) -> Result<Option<Duration>>;
275
276 fn send(&mut self, data: Bytes) -> Result<usize>;
278
279 fn flush(&mut self) -> Result<()>;
281
282 fn recv(&mut self) -> Result<SocketReceive>;
284
285 fn peek(&mut self) -> Result<SocketReceive>;
287}
288
289pub trait VirtualConnectionlessSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
292 fn send_to(&mut self, data: Bytes, addr: SocketAddr) -> Result<usize>;
295
296 fn recv_from(&mut self) -> Result<SocketReceiveFrom>;
298
299 fn peek_from(&mut self) -> Result<SocketReceiveFrom>;
301}
302
303pub trait VirtualIcmpSocket:
306 VirtualConnectionlessSocket + fmt::Debug + Send + Sync + 'static
307{
308}
309
310pub trait VirtualRawSocket: VirtualSocket + fmt::Debug + Send + Sync + 'static {
311 fn send(&mut self, data: Bytes) -> Result<usize>;
313
314 fn flush(&mut self) -> Result<()>;
316
317 fn recv(&mut self) -> Result<SocketReceive>;
319
320 fn set_promiscuous(&mut self, promiscuous: bool) -> Result<()>;
324
325 fn promiscuous(&self) -> Result<bool>;
329}
330
331#[derive(Debug, Copy, Clone, PartialEq, Eq)]
332pub enum TimeType {
333 ReadTimeout,
334 WriteTimeout,
335 AcceptTimeout,
336 ConnectTimeout,
337 Linger,
338}
339
340pub trait VirtualTcpSocket: VirtualConnectedSocket + fmt::Debug + Send + Sync + 'static {
341 fn set_opt_time(&mut self, ty: TimeType, timeout: Option<Duration>) -> Result<()>;
343
344 fn opt_time(&self, ty: TimeType) -> Result<Option<Duration>>;
346
347 fn set_recv_buf_size(&mut self, size: usize) -> Result<()>;
350
351 fn recv_buf_size(&self) -> Result<usize>;
354
355 fn set_send_buf_size(&mut self, size: usize) -> Result<()>;
358
359 fn send_buf_size(&self) -> Result<usize>;
362
363 fn set_nodelay(&mut self, reuse: bool) -> Result<()>;
368
369 fn nodelay(&self) -> Result<bool>;
373
374 fn addr_peer(&self) -> Result<SocketAddr>;
377
378 fn flush(&mut self) -> Result<()>;
381
382 fn shutdown(&mut self, how: Shutdown) -> Result<()>;
385}
386
387pub trait VirtualUdpSocket:
388 VirtualConnectedSocket + VirtualConnectionlessSocket + fmt::Debug + Send + Sync + 'static
389{
390 fn connect(&mut self, addr: SocketAddr) -> Result<()>;
393
394 fn set_broadcast(&mut self, broadcast: bool) -> Result<()>;
397
398 fn broadcast(&self) -> Result<bool>;
402
403 fn set_multicast_loop_v4(&mut self, val: bool) -> Result<()>;
407
408 fn multicast_loop_v4(&self) -> Result<bool>;
412
413 fn set_multicast_loop_v6(&mut self, val: bool) -> Result<()>;
417
418 fn multicast_loop_v6(&self) -> Result<bool>;
422
423 fn set_multicast_ttl_v4(&mut self, ttl: u32) -> Result<()>;
426
427 fn multicast_ttl_v4(&self) -> Result<u32>;
430
431 fn join_multicast_v4(&mut self, multiaddr: Ipv4Addr, iface: Ipv4Addr) -> Result<()>;
434
435 fn leave_multicast_v4(&mut self, multiaddr: Ipv4Addr, iface: Ipv4Addr) -> Result<()>;
438
439 fn join_multicast_v6(&mut self, multiaddr: Ipv6Addr, iface: u32) -> Result<()>;
442
443 fn leave_multicast_v6(&mut self, multiaddr: Ipv6Addr, iface: u32) -> Result<()>;
446
447 fn addr_peer(&self) -> Result<Option<SocketAddr>>;
450}
451
452#[derive(Debug, Default)]
453pub struct UnsupportedVirtualNetworking {}
454
455impl VirtualNetworking for UnsupportedVirtualNetworking {
456 fn ws_connect(&self, _url: &str) -> Result<Box<dyn VirtualWebSocket + Sync>> {
457 Err(NetworkError::Unsupported)
458 }
459
460 fn http_request(
461 &self,
462 _url: &str,
463 _method: &str,
464 _headers: &str,
465 _gzip: bool,
466 ) -> Result<SocketHttpRequest> {
467 Err(NetworkError::Unsupported)
468 }
469
470 fn bridge(&self, _network: &str, _access_token: &str, _security: StreamSecurity) -> Result<()> {
471 Err(NetworkError::Unsupported)
472 }
473
474 fn unbridge(&self) -> Result<()> {
475 Err(NetworkError::Unsupported)
476 }
477
478 fn dhcp_acquire(&self) -> Result<Vec<IpAddr>> {
479 Err(NetworkError::Unsupported)
480 }
481
482 fn ip_add(&self, _ip: IpAddr, _prefix: u8) -> Result<()> {
483 Err(NetworkError::Unsupported)
484 }
485
486 fn ip_remove(&self, _ip: IpAddr) -> Result<()> {
487 Err(NetworkError::Unsupported)
488 }
489
490 fn ip_clear(&self) -> Result<()> {
491 Err(NetworkError::Unsupported)
492 }
493
494 fn ip_list(&self) -> Result<Vec<IpCidr>> {
495 Err(NetworkError::Unsupported)
496 }
497
498 fn mac(&self) -> Result<[u8; 6]> {
499 Err(NetworkError::Unsupported)
500 }
501
502 fn gateway_set(&self, _ip: IpAddr) -> Result<()> {
503 Err(NetworkError::Unsupported)
504 }
505
506 fn route_add(
507 &self,
508 _cidr: IpCidr,
509 _via_router: IpAddr,
510 _preferred_until: Option<Duration>,
511 _expires_at: Option<Duration>,
512 ) -> Result<()> {
513 Err(NetworkError::Unsupported)
514 }
515
516 fn route_remove(&self, _cidr: IpAddr) -> Result<()> {
517 Err(NetworkError::Unsupported)
518 }
519
520 fn route_clear(&self) -> Result<()> {
521 Err(NetworkError::Unsupported)
522 }
523
524 fn route_list(&self) -> Result<Vec<IpRoute>> {
525 Err(NetworkError::Unsupported)
526 }
527
528 fn bind_raw(&self) -> Result<Box<dyn VirtualRawSocket + Sync>> {
529 Err(NetworkError::Unsupported)
530 }
531
532 fn bind_icmp(&self, _addr: IpAddr) -> Result<Box<dyn VirtualIcmpSocket + Sync>> {
533 Err(NetworkError::Unsupported)
534 }
535
536 fn listen_tcp(
537 &self,
538 _addr: SocketAddr,
539 _only_v6: bool,
540 _reuse_port: bool,
541 _reuse_addr: bool,
542 ) -> Result<Box<dyn VirtualTcpListener + Sync>> {
543 Err(NetworkError::Unsupported)
544 }
545
546 fn connect_tcp(
547 &self,
548 _addr: SocketAddr,
549 _peer: SocketAddr,
550 _timeout: Option<Duration>,
551 ) -> Result<Box<dyn VirtualTcpSocket + Sync>> {
552 Err(NetworkError::Unsupported)
553 }
554
555 fn bind_udp(
556 &self,
557 _addr: SocketAddr,
558 _reuse_port: bool,
559 _reuse_addr: bool,
560 ) -> Result<Box<dyn VirtualUdpSocket + Sync>> {
561 Err(NetworkError::Unsupported)
562 }
563
564 fn resolve(
565 &self,
566 _host: &str,
567 _port: Option<u16>,
568 _dns_server: Option<IpAddr>,
569 ) -> Result<Vec<IpAddr>> {
570 Err(NetworkError::Unsupported)
571 }
572}
573
574#[derive(Error, Copy, Clone, Debug, PartialEq, Eq)]
575pub enum NetworkError {
576 #[error("invalid fd")]
578 InvalidFd,
579 #[error("file exists")]
581 AlreadyExists,
582 #[error("lock error")]
584 Lock,
585 #[error("io error")]
588 IOError,
589 #[error("address is in use")]
591 AddressInUse,
592 #[error("address could not be found")]
594 AddressNotAvailable,
595 #[error("broken pipe (was closed)")]
597 BrokenPipe,
598 #[error("connection aborted")]
600 ConnectionAborted,
601 #[error("connection refused")]
603 ConnectionRefused,
604 #[error("connection reset")]
606 ConnectionReset,
607 #[error("operation interrupted")]
609 Interrupted,
610 #[error("invalid internal data")]
612 InvalidData,
613 #[error("invalid input")]
615 InvalidInput,
616 #[error("connection is not open")]
618 NotConnected,
619 #[error("can't access device")]
621 NoDevice,
622 #[error("permission denied")]
624 PermissionDenied,
625 #[error("time out")]
627 TimedOut,
628 #[error("unexpected eof")]
630 UnexpectedEof,
631 #[error("blocking operation. try again")]
633 WouldBlock,
634 #[error("write returned 0")]
636 WriteZero,
637 #[error("unsupported")]
639 Unsupported,
640 #[error("unknown error found")]
642 UnknownError,
643}
644
645pub fn net_error_into_io_err(net_error: NetworkError) -> std::io::Error {
646 use std::io::ErrorKind;
647 match net_error {
648 NetworkError::InvalidFd => ErrorKind::BrokenPipe.into(),
649 NetworkError::AlreadyExists => ErrorKind::AlreadyExists.into(),
650 NetworkError::Lock => ErrorKind::BrokenPipe.into(),
651 NetworkError::IOError => ErrorKind::BrokenPipe.into(),
652 NetworkError::AddressInUse => ErrorKind::AddrInUse.into(),
653 NetworkError::AddressNotAvailable => ErrorKind::AddrNotAvailable.into(),
654 NetworkError::BrokenPipe => ErrorKind::BrokenPipe.into(),
655 NetworkError::ConnectionAborted => ErrorKind::ConnectionAborted.into(),
656 NetworkError::ConnectionRefused => ErrorKind::ConnectionRefused.into(),
657 NetworkError::ConnectionReset => ErrorKind::ConnectionReset.into(),
658 NetworkError::Interrupted => ErrorKind::Interrupted.into(),
659 NetworkError::InvalidData => ErrorKind::InvalidData.into(),
660 NetworkError::InvalidInput => ErrorKind::InvalidInput.into(),
661 NetworkError::NotConnected => ErrorKind::NotConnected.into(),
662 NetworkError::NoDevice => ErrorKind::BrokenPipe.into(),
663 NetworkError::PermissionDenied => ErrorKind::PermissionDenied.into(),
664 NetworkError::TimedOut => ErrorKind::TimedOut.into(),
665 NetworkError::UnexpectedEof => ErrorKind::UnexpectedEof.into(),
666 NetworkError::WouldBlock => ErrorKind::WouldBlock.into(),
667 NetworkError::WriteZero => ErrorKind::WriteZero.into(),
668 NetworkError::Unsupported => ErrorKind::Unsupported.into(),
669 NetworkError::UnknownError => ErrorKind::BrokenPipe.into(),
670 }
671}
672
673pub fn io_err_into_net_error(net_error: std::io::Error) -> NetworkError {
674 use std::io::ErrorKind;
675 match net_error.kind() {
676 ErrorKind::BrokenPipe => NetworkError::BrokenPipe,
677 ErrorKind::AlreadyExists => NetworkError::AlreadyExists,
678 ErrorKind::AddrInUse => NetworkError::AddressInUse,
679 ErrorKind::AddrNotAvailable => NetworkError::AddressNotAvailable,
680 ErrorKind::ConnectionAborted => NetworkError::ConnectionAborted,
681 ErrorKind::ConnectionRefused => NetworkError::ConnectionRefused,
682 ErrorKind::ConnectionReset => NetworkError::ConnectionReset,
683 ErrorKind::Interrupted => NetworkError::Interrupted,
684 ErrorKind::InvalidData => NetworkError::InvalidData,
685 ErrorKind::InvalidInput => NetworkError::InvalidInput,
686 ErrorKind::NotConnected => NetworkError::NotConnected,
687 ErrorKind::PermissionDenied => NetworkError::PermissionDenied,
688 ErrorKind::TimedOut => NetworkError::TimedOut,
689 ErrorKind::UnexpectedEof => NetworkError::UnexpectedEof,
690 ErrorKind::WouldBlock => NetworkError::WouldBlock,
691 ErrorKind::WriteZero => NetworkError::WriteZero,
692 ErrorKind::Unsupported => NetworkError::Unsupported,
693 _ => NetworkError::UnknownError,
694 }
695}