std_embedded_nal_async/
dns.rs1use core::net::{IpAddr, SocketAddr};
4use embedded_nal_async::AddrType;
5
6#[derive(Debug)]
9struct NotFound;
10
11impl core::fmt::Display for NotFound {
12 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
13 write!(f, "Not found")
14 }
15}
16
17impl std::error::Error for NotFound {}
18
19#[derive(Debug)]
22struct TooLong;
23
24impl core::fmt::Display for TooLong {
25 fn fmt(&self, f: &mut core::fmt::Formatter) -> core::fmt::Result {
26 write!(f, "Name too long")
27 }
28}
29
30impl std::error::Error for TooLong {}
31
32impl embedded_nal_async::Dns for crate::Stack {
33 type Error = std::io::Error;
34
35 async fn get_host_by_name(
36 &self,
37 hostname: &str,
38 addr_type: AddrType,
39 ) -> Result<IpAddr, Self::Error> {
40 let accept_v4 = addr_type != AddrType::IPv6;
41 let accept_v6 = addr_type != AddrType::IPv4;
42
43 let fake_port = 1234u16;
46
47 for addr in async_net::resolve((hostname, fake_port)).await? {
48 match addr {
49 SocketAddr::V4(v) if accept_v4 => {
50 return Ok(v.ip().octets().into());
51 }
52 SocketAddr::V6(v) if accept_v6 => {
53 return Ok(v.ip().octets().into());
54 }
55 _ => continue,
56 }
57 }
58
59 Err(Self::Error::new(std::io::ErrorKind::NotFound, NotFound))
60 }
61
62 async fn get_host_by_address(
63 &self,
64 addr: IpAddr,
65 result: &mut [u8],
66 ) -> Result<usize, Self::Error> {
67 let fakesocketaddr = std::net::SocketAddr::new(addr, 1234);
68
69 let (name, _service) =
70 blocking::unblock(move || dns_lookup::getnameinfo(&fakesocketaddr, 0)).await?;
71
72 if name.parse::<IpAddr>().is_ok() {
73 return Err(Self::Error::new(std::io::ErrorKind::NotFound, NotFound));
76 }
77
78 if let Some(result) = result.get_mut(..name.len()) {
79 result.copy_from_slice(name.as_bytes());
80 Ok(result.len())
81 } else {
82 Err(Self::Error::new(std::io::ErrorKind::OutOfMemory, TooLong))
83 }
84 }
85}