1#![allow(async_fn_in_trait)]
2#![warn(clippy::large_futures)]
3#![allow(clippy::uninlined_format_args)]
4#![allow(unknown_lints)]
5
6use core::net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr};
7use core::ops::Deref;
8use core::pin::pin;
9
10use std::io;
11use std::net::{self, Shutdown, TcpStream, ToSocketAddrs, UdpSocket as StdUdpSocket};
12
13#[cfg(not(feature = "async-io-mini"))]
14use async_io::Async;
15#[cfg(feature = "async-io-mini")]
16use async_io_mini::Async;
17
18use futures_lite::io::{AsyncReadExt, AsyncWriteExt};
19
20use embedded_io_async::{ErrorType, Read, Write};
21
22use edge_nal::{
23 AddrType, Dns, MulticastV4, MulticastV6, Readable, TcpAccept, TcpBind, TcpConnect, TcpShutdown,
24 TcpSplit, UdpBind, UdpConnect, UdpReceive, UdpSend, UdpSplit,
25};
26
27#[cfg(any(target_os = "linux", target_os = "android"))]
28pub use raw::*;
29
30#[derive(Default, Copy, Clone)]
37pub struct Stack(());
38
39impl Stack {
40 pub const fn new() -> Self {
42 Self(())
43 }
44}
45
46impl TcpConnect for Stack {
47 type Error = io::Error;
48
49 type Socket<'a>
50 = TcpSocket
51 where
52 Self: 'a;
53
54 async fn connect(&self, remote: SocketAddr) -> Result<Self::Socket<'_>, Self::Error> {
55 let socket = Async::<TcpStream>::connect(remote).await?;
56
57 Ok(TcpSocket(socket))
58 }
59}
60
61impl TcpBind for Stack {
62 type Error = io::Error;
63
64 type Accept<'a>
65 = TcpAcceptor
66 where
67 Self: 'a;
68
69 async fn bind(&self, local: SocketAddr) -> Result<Self::Accept<'_>, Self::Error> {
70 let acceptor = Async::<net::TcpListener>::bind(local).map(TcpAcceptor)?;
71
72 Ok(acceptor)
73 }
74}
75
76pub struct TcpAcceptor(Async<net::TcpListener>);
78
79impl TcpAccept for TcpAcceptor {
80 type Error = io::Error;
81
82 type Socket<'a>
83 = TcpSocket
84 where
85 Self: 'a;
86
87 #[cfg(not(target_os = "espidf"))]
88 async fn accept(&self) -> Result<(SocketAddr, Self::Socket<'_>), Self::Error> {
89 let socket = self.0.accept().await.map(|(socket, _)| socket)?;
90
91 Ok((socket.as_ref().peer_addr()?, TcpSocket(socket)))
92 }
93
94 #[cfg(target_os = "espidf")]
95 async fn accept(&self) -> Result<(SocketAddr, Self::Socket<'_>), Self::Error> {
96 loop {
111 match self.0.as_ref().accept() {
112 Ok((socket, _)) => break Ok((socket.peer_addr()?, TcpSocket(Async::new(socket)?))),
113 Err(err) if err.kind() == io::ErrorKind::WouldBlock => {
114 #[cfg(not(feature = "async-io-mini"))]
115 use async_io::Timer;
116 #[cfg(feature = "async-io-mini")]
117 use async_io_mini::Timer;
118
119 Timer::after(core::time::Duration::from_millis(20)).await;
120 }
121 Err(err) => break Err(err),
122 }
123 }
124 }
125}
126
127pub struct TcpSocket(Async<TcpStream>);
129
130impl TcpSocket {
131 pub const fn new(socket: Async<TcpStream>) -> Self {
136 Self(socket)
137 }
138
139 pub fn release(self) -> Async<TcpStream> {
141 self.0
142 }
143}
144
145impl Deref for TcpSocket {
146 type Target = Async<TcpStream>;
147
148 fn deref(&self) -> &Self::Target {
149 &self.0
150 }
151}
152
153impl ErrorType for TcpSocket {
154 type Error = io::Error;
155}
156
157impl Read for TcpSocket {
158 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
159 self.0.read(buf).await
160 }
161}
162
163impl Write for TcpSocket {
164 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
165 self.0.write(buf).await
166 }
167
168 async fn flush(&mut self) -> Result<(), Self::Error> {
169 self.0.flush().await
170 }
171}
172
173impl Readable for TcpSocket {
174 async fn readable(&mut self) -> Result<(), Self::Error> {
175 self.0.readable().await
176 }
177}
178
179impl ErrorType for &TcpSocket {
180 type Error = io::Error;
181}
182
183impl Read for &TcpSocket {
184 async fn read(&mut self, buf: &mut [u8]) -> Result<usize, Self::Error> {
185 (&self.0).read(buf).await
186 }
187}
188
189impl Write for &TcpSocket {
190 async fn write(&mut self, buf: &[u8]) -> Result<usize, Self::Error> {
191 (&self.0).write(buf).await
192 }
193
194 async fn flush(&mut self) -> Result<(), Self::Error> {
195 (&self.0).flush().await
196 }
197}
198
199impl Readable for &TcpSocket {
200 async fn readable(&mut self) -> Result<(), Self::Error> {
201 self.0.readable().await
202 }
203}
204
205impl TcpSplit for TcpSocket {
206 type Read<'a>
207 = &'a TcpSocket
208 where
209 Self: 'a;
210
211 type Write<'a>
212 = &'a TcpSocket
213 where
214 Self: 'a;
215
216 fn split(&mut self) -> (Self::Read<'_>, Self::Write<'_>) {
217 let socket = &*self;
218
219 (socket, socket)
220 }
221}
222
223impl TcpShutdown for TcpSocket {
224 async fn close(&mut self, what: edge_nal::Close) -> Result<(), Self::Error> {
225 match what {
226 edge_nal::Close::Read => self.0.as_ref().shutdown(Shutdown::Read)?,
227 edge_nal::Close::Write => self.0.as_ref().shutdown(Shutdown::Write)?,
228 edge_nal::Close::Both => self.0.as_ref().shutdown(Shutdown::Both)?,
229 }
230
231 Ok(())
232 }
233
234 async fn abort(&mut self) -> Result<(), Self::Error> {
235 Ok(())
238 }
239}
240
241impl UdpConnect for Stack {
242 type Error = io::Error;
243
244 type Socket<'a>
245 = UdpSocket
246 where
247 Self: 'a;
248
249 async fn connect(
250 &self,
251 local: SocketAddr,
252 remote: SocketAddr,
253 ) -> Result<Self::Socket<'_>, Self::Error> {
254 let socket = Async::<StdUdpSocket>::bind(local)?;
255
256 socket.as_ref().connect(remote)?;
257
258 Ok(UdpSocket(socket))
259 }
260}
261
262impl UdpBind for Stack {
263 type Error = io::Error;
264
265 type Socket<'a>
266 = UdpSocket
267 where
268 Self: 'a;
269
270 async fn bind(&self, local: SocketAddr) -> Result<Self::Socket<'_>, Self::Error> {
271 let socket = Async::<StdUdpSocket>::bind(local)?;
272
273 socket.as_ref().set_broadcast(true)?;
274
275 Ok(UdpSocket(socket))
276 }
277}
278
279pub struct UdpSocket(Async<StdUdpSocket>);
281
282impl UdpSocket {
283 pub const fn new(socket: Async<StdUdpSocket>) -> Self {
288 Self(socket)
289 }
290
291 pub fn release(self) -> Async<StdUdpSocket> {
293 self.0
294 }
295
296 pub fn join_multicast_v4(
302 &self,
303 multiaddr: &Ipv4Addr,
304 interface: &Ipv4Addr,
305 ) -> Result<(), io::Error> {
306 #[cfg(not(target_os = "espidf"))]
307 self.as_ref().join_multicast_v4(multiaddr, interface)?;
308
309 #[cfg(target_os = "espidf")]
310 self.setsockopt_ipproto_ip(
311 multiaddr, interface, 3, )?;
313
314 Ok(())
315 }
316
317 pub fn leave_multicast_v4(
323 &self,
324 multiaddr: &Ipv4Addr,
325 interface: &Ipv4Addr,
326 ) -> Result<(), io::Error> {
327 #[cfg(not(target_os = "espidf"))]
328 self.as_ref().leave_multicast_v4(multiaddr, interface)?;
329
330 #[cfg(target_os = "espidf")]
331 self.setsockopt_ipproto_ip(
332 multiaddr, interface, 4, )?;
334
335 Ok(())
336 }
337
338 #[cfg(target_os = "espidf")]
339 pub fn setsockopt_ipproto_ip(
340 &self,
341 multiaddr: &Ipv4Addr,
342 interface: &Ipv4Addr,
343 option: u32,
344 ) -> Result<(), io::Error> {
345 let mreq = sys::ip_mreq {
352 imr_multiaddr: sys::in_addr {
353 s_addr: u32::from_ne_bytes(multiaddr.octets()),
354 },
355 imr_interface: sys::in_addr {
356 s_addr: u32::from_ne_bytes(interface.octets()),
357 },
358 };
359
360 use std::os::fd::AsRawFd;
361
362 syscall_los!(unsafe {
363 sys::setsockopt(
364 self.0.as_raw_fd(),
365 sys::IPPROTO_IP as _,
366 option as _,
367 &mreq as *const _ as *const _,
368 core::mem::size_of::<sys::ip_mreq>() as _,
369 )
370 })?;
371
372 Ok(())
373 }
374}
375
376impl Deref for UdpSocket {
377 type Target = Async<StdUdpSocket>;
378
379 fn deref(&self) -> &Self::Target {
380 &self.0
381 }
382}
383
384impl ErrorType for &UdpSocket {
385 type Error = io::Error;
386}
387
388impl UdpReceive for &UdpSocket {
389 async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), Self::Error> {
390 let remote = self.0.as_ref().peer_addr();
391
392 let (len, remote) = if let Ok(remote) = remote {
393 let fut = pin!(self.0.recv(buffer));
395 let len = fut.await?;
396
397 (len, remote)
398 } else {
399 let fut = pin!(self.0.recv_from(buffer));
401 let (len, remote) = fut.await?;
402
403 (len, remote)
404 };
405
406 Ok((len, remote))
407 }
408}
409
410impl UdpSend for &UdpSocket {
411 async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> {
412 let is_remote = self.0.as_ref().peer_addr().is_ok();
413
414 if is_remote {
415 let mut offset = 0;
417
418 loop {
419 let fut = pin!(self.0.send(&data[offset..]));
420 offset += fut.await?;
421
422 if offset == data.len() {
423 break;
424 }
425 }
426 } else {
427 let mut offset = 0;
429
430 loop {
431 let fut = pin!(self.0.send_to(&data[offset..], remote));
432 offset += fut.await?;
433
434 if offset == data.len() {
435 break;
436 }
437 }
438 }
439
440 Ok(())
441 }
442}
443
444impl MulticastV4 for &UdpSocket {
445 async fn join_v4(
446 &mut self,
447 multicast_addr: Ipv4Addr,
448 interface: Ipv4Addr,
449 ) -> Result<(), Self::Error> {
450 self.join_multicast_v4(&multicast_addr, &interface)
451 }
452
453 async fn leave_v4(
454 &mut self,
455 multicast_addr: Ipv4Addr,
456 interface: Ipv4Addr,
457 ) -> Result<(), Self::Error> {
458 self.leave_multicast_v4(&multicast_addr, &interface)
459 }
460}
461
462impl MulticastV6 for &UdpSocket {
463 async fn join_v6(
464 &mut self,
465 multicast_addr: Ipv6Addr,
466 interface: u32,
467 ) -> Result<(), Self::Error> {
468 self.0
469 .as_ref()
470 .join_multicast_v6(&multicast_addr, interface)
471 }
472
473 async fn leave_v6(
474 &mut self,
475 multicast_addr: Ipv6Addr,
476 interface: u32,
477 ) -> Result<(), Self::Error> {
478 self.0
479 .as_ref()
480 .leave_multicast_v6(&multicast_addr, interface)
481 }
482}
483
484impl Readable for &UdpSocket {
485 async fn readable(&mut self) -> Result<(), Self::Error> {
486 self.0.readable().await
487 }
488}
489
490impl ErrorType for UdpSocket {
491 type Error = io::Error;
492}
493
494impl UdpReceive for UdpSocket {
495 async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, SocketAddr), Self::Error> {
496 let mut rself = &*self;
497
498 let fut = pin!(rself.receive(buffer));
499 fut.await
500 }
501}
502
503impl UdpSend for UdpSocket {
504 async fn send(&mut self, remote: SocketAddr, data: &[u8]) -> Result<(), Self::Error> {
505 let mut rself = &*self;
506
507 let fut = pin!(rself.send(remote, data));
508 fut.await
509 }
510}
511
512impl MulticastV4 for UdpSocket {
513 async fn join_v4(
514 &mut self,
515 multicast_addr: Ipv4Addr,
516 interface: Ipv4Addr,
517 ) -> Result<(), Self::Error> {
518 self.join_multicast_v4(&multicast_addr, &interface)
519 }
520
521 async fn leave_v4(
522 &mut self,
523 multicast_addr: Ipv4Addr,
524 interface: Ipv4Addr,
525 ) -> Result<(), Self::Error> {
526 self.leave_multicast_v4(&multicast_addr, &interface)
527 }
528}
529
530impl MulticastV6 for UdpSocket {
531 async fn join_v6(
532 &mut self,
533 multicast_addr: Ipv6Addr,
534 interface: u32,
535 ) -> Result<(), Self::Error> {
536 self.0
537 .as_ref()
538 .join_multicast_v6(&multicast_addr, interface)
539 }
540
541 async fn leave_v6(
542 &mut self,
543 multicast_addr: Ipv6Addr,
544 interface: u32,
545 ) -> Result<(), Self::Error> {
546 self.0
547 .as_ref()
548 .leave_multicast_v6(&multicast_addr, interface)
549 }
550}
551
552impl Readable for UdpSocket {
553 async fn readable(&mut self) -> Result<(), Self::Error> {
554 let mut rself = &*self;
555
556 let fut = pin!(rself.readable());
557 fut.await
558 }
559}
560
561impl UdpSplit for UdpSocket {
562 type Receive<'a>
563 = &'a Self
564 where
565 Self: 'a;
566
567 type Send<'a>
568 = &'a Self
569 where
570 Self: 'a;
571
572 fn split(&mut self) -> (Self::Receive<'_>, Self::Send<'_>) {
573 let socket = &*self;
574
575 (socket, socket)
576 }
577}
578
579impl Dns for Stack {
580 type Error = io::Error;
581
582 async fn get_host_by_name(
583 &self,
584 host: &str,
585 addr_type: AddrType,
586 ) -> Result<IpAddr, Self::Error> {
587 let host = host.to_string();
588
589 dns_lookup_host(&host, addr_type)
590 }
591
592 async fn get_host_by_address(
593 &self,
594 _addr: IpAddr,
595 _result: &mut [u8],
596 ) -> Result<usize, Self::Error> {
597 Err(io::ErrorKind::Unsupported.into())
598 }
599}
600
601fn dns_lookup_host(host: &str, addr_type: AddrType) -> Result<IpAddr, io::Error> {
603 (host, 0_u16)
604 .to_socket_addrs()?
605 .find(|addr| match addr_type {
606 AddrType::IPv4 => matches!(addr, std::net::SocketAddr::V4(_)),
607 AddrType::IPv6 => matches!(addr, std::net::SocketAddr::V6(_)),
608 AddrType::Either => true,
609 })
610 .map(|addr| match addr {
611 std::net::SocketAddr::V4(v4) => v4.ip().octets().into(),
612 std::net::SocketAddr::V6(v6) => v6.ip().octets().into(),
613 })
614 .ok_or_else(|| io::ErrorKind::AddrNotAvailable.into())
615}
616
617#[cfg(any(target_os = "linux", target_os = "android"))]
620mod raw {
621 use core::ops::Deref;
622 use core::pin::pin;
623
624 use std::io::{self, ErrorKind};
625 use std::os::fd::{AsFd, AsRawFd};
626
627 #[cfg(not(feature = "async-io-mini"))]
628 use async_io::Async;
629 #[cfg(feature = "async-io-mini")]
630 use async_io_mini::Async;
631
632 use edge_nal::{MacAddr, RawBind, RawReceive, RawSend, RawSplit, Readable};
633 use embedded_io_async::ErrorType;
634
635 use crate::sys;
636 use crate::syscall_los;
637
638 #[derive(Default, Copy, Clone)]
640 pub struct Interface(u32);
641
642 impl Interface {
643 pub const fn new(interface: u32) -> Self {
645 Self(interface)
646 }
647 }
648
649 impl RawBind for Interface {
650 type Error = io::Error;
651
652 type Socket<'a>
653 = RawSocket
654 where
655 Self: 'a;
656
657 async fn bind(&self) -> Result<Self::Socket<'_>, Self::Error> {
658 let socket = syscall_los!(unsafe {
659 sys::socket(
660 sys::PF_PACKET,
661 sys::SOCK_DGRAM,
662 (sys::ETH_P_IP as u16).to_be() as _,
663 )
664 })?;
665
666 let sockaddr = sys::sockaddr_ll {
667 sll_family: sys::AF_PACKET as _,
668 sll_protocol: (sys::ETH_P_IP as u16).to_be() as _,
669 sll_ifindex: self.0 as _,
670 sll_hatype: 0,
671 sll_pkttype: 0,
672 sll_halen: 0,
673 sll_addr: Default::default(),
674 };
675
676 syscall_los!(unsafe {
677 sys::bind(
678 socket,
679 &sockaddr as *const _ as *const _,
680 core::mem::size_of::<sys::sockaddr_ll>() as _,
681 )
682 })?;
683
684 let socket = {
690 use std::os::fd::FromRawFd;
691
692 unsafe { std::net::UdpSocket::from_raw_fd(socket) }
693 };
694
695 socket.set_broadcast(true)?;
696
697 Ok(RawSocket(Async::new(socket)?, self.0 as _))
698 }
699 }
700
701 pub struct RawSocket(Async<std::net::UdpSocket>, u32);
703
704 impl RawSocket {
705 pub const fn new(socket: Async<std::net::UdpSocket>, interface: u32) -> Self {
711 Self(socket, interface)
712 }
713
714 pub fn release(self) -> (Async<std::net::UdpSocket>, u32) {
716 (self.0, self.1)
717 }
718 }
719
720 impl Deref for RawSocket {
721 type Target = Async<std::net::UdpSocket>;
722
723 fn deref(&self) -> &Self::Target {
724 &self.0
725 }
726 }
727
728 impl ErrorType for &RawSocket {
729 type Error = io::Error;
730 }
731
732 impl RawReceive for &RawSocket {
733 async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, MacAddr), Self::Error> {
734 let fut = pin!(self.0.read_with(|io| {
735 let mut storage: sys::sockaddr_storage = unsafe { core::mem::zeroed() };
736 let mut addrlen = core::mem::size_of_val(&storage) as sys::socklen_t;
737
738 let ret = syscall_los!(unsafe {
739 sys::recvfrom(
740 io.as_fd().as_raw_fd(),
741 buffer.as_mut_ptr() as *mut _,
742 buffer.len(),
743 0,
744 &mut storage as *mut _ as *mut _,
745 &mut addrlen,
746 )
747 })?;
748
749 let sockaddr = as_sockaddr_ll(&storage, addrlen as usize)?;
750
751 let mut mac = [0; 6];
752 mac.copy_from_slice(&sockaddr.sll_addr[..6]);
753
754 Ok((ret as usize, mac))
755 }));
756
757 fut.await
758 }
759 }
760
761 impl RawSend for &RawSocket {
762 async fn send(&mut self, mac: MacAddr, data: &[u8]) -> Result<(), Self::Error> {
763 let mut sockaddr = sys::sockaddr_ll {
764 sll_family: sys::AF_PACKET as _,
765 sll_protocol: (sys::ETH_P_IP as u16).to_be() as _,
766 sll_ifindex: self.1 as _,
767 sll_hatype: 0,
768 sll_pkttype: 0,
769 sll_halen: 0,
770 sll_addr: Default::default(),
771 };
772
773 sockaddr.sll_halen = mac.len() as _;
774 sockaddr.sll_addr[..mac.len()].copy_from_slice(&mac);
775
776 let fut = pin!(self.0.write_with(|io| {
777 let len = core::cmp::min(data.len(), u16::MAX as usize);
778
779 let ret = syscall_los!(unsafe {
780 sys::sendto(
781 io.as_fd().as_raw_fd(),
782 data.as_ptr() as *const _,
783 len,
784 sys::MSG_NOSIGNAL,
785 &sockaddr as *const _ as *const _,
786 core::mem::size_of::<sys::sockaddr_ll>() as _,
787 )
788 })?;
789 Ok(ret as usize)
790 }));
791
792 let len = fut.await?;
793
794 assert_eq!(len, data.len());
795
796 Ok(())
797 }
798 }
799
800 impl Readable for &RawSocket {
801 async fn readable(&mut self) -> Result<(), Self::Error> {
802 self.0.readable().await
803 }
804 }
805
806 impl ErrorType for RawSocket {
807 type Error = io::Error;
808 }
809
810 impl RawReceive for RawSocket {
811 async fn receive(&mut self, buffer: &mut [u8]) -> Result<(usize, MacAddr), Self::Error> {
812 let mut rself = &*self;
813
814 let fut = pin!(rself.receive(buffer));
815
816 fut.await
817 }
818 }
819
820 impl RawSend for RawSocket {
821 async fn send(&mut self, mac: MacAddr, data: &[u8]) -> Result<(), Self::Error> {
822 let mut rself = &*self;
823
824 let fut = pin!(rself.send(mac, data));
825
826 fut.await
827 }
828 }
829
830 impl RawSplit for RawSocket {
831 type Receive<'a>
832 = &'a Self
833 where
834 Self: 'a;
835
836 type Send<'a>
837 = &'a Self
838 where
839 Self: 'a;
840
841 fn split(&mut self) -> (Self::Receive<'_>, Self::Send<'_>) {
842 let socket = &*self;
843
844 (socket, socket)
845 }
846 }
847
848 impl Readable for RawSocket {
849 async fn readable(&mut self) -> Result<(), Self::Error> {
850 self.0.readable().await
851 }
852 }
853
854 fn as_sockaddr_ll(
855 storage: &sys::sockaddr_storage,
856 len: usize,
857 ) -> io::Result<&sys::sockaddr_ll> {
858 match storage.ss_family as core::ffi::c_int {
859 sys::AF_PACKET => {
860 assert!(len >= core::mem::size_of::<sys::sockaddr_ll>());
861 Ok(unsafe { (storage as *const _ as *const sys::sockaddr_ll).as_ref() }.unwrap())
862 }
863 _ => Err(io::Error::new(ErrorKind::InvalidInput, "invalid argument")),
864 }
865 }
866}
867
868#[cfg(any(target_os = "linux", target_os = "android", target_os = "espidf"))]
869mod sys {
870 pub use libc::*;
871
872 #[macro_export]
873 macro_rules! syscall {
874 ($ret:expr) => {{
875 let result = $ret;
876
877 if result != 0 {
878 Err(::std::io::Error::from_raw_os_error(result))
879 } else {
880 Ok(result)
881 }
882 }};
883 }
884
885 #[macro_export]
886 macro_rules! syscall_los {
887 ($ret:expr) => {{
888 let result = $ret;
889
890 if result == -1 {
891 Err(::std::io::Error::last_os_error())
892 } else {
893 Ok(result)
894 }
895 }};
896 }
897
898 #[macro_export]
899 macro_rules! syscall_los_eagain {
900 ($ret:expr) => {{
901 #[allow(unreachable_patterns)]
902 match syscall_los!($ret) {
903 Ok(_) => Ok(()),
904 Err(e)
905 if matches!(
906 e.raw_os_error(),
907 Some(sys::EINPROGRESS) | Some(sys::EAGAIN) | Some(sys::EWOULDBLOCK)
908 ) =>
909 {
910 Ok(())
911 }
912 Err(e) => Err(e),
913 }?;
914
915 Ok::<_, io::Error>(())
916 }};
917 }
918}