Skip to main content

device_envoy_core/
dns.rs

1//! A device abstraction for resolving hostnames.
2
3use core::future::Future;
4
5use embassy_net::{Stack, dns::DnsQueryType};
6
7/// One resolved address (embassy-net's address type re-exported for callers).
8pub use embassy_net::IpAddress;
9
10/// Addresses returned by a single lookup.
11pub type Addresses = heapless::Vec<IpAddress, 4>;
12
13/// Platform-independent contract for resolving a hostname.
14pub trait Dns {
15    /// Error returned by the platform DNS implementation.
16    type Error;
17
18    /// Resolve `hostname` to zero or more addresses.
19    fn resolve(&mut self, hostname: &str) -> impl Future<Output = Result<Addresses, Self::Error>>;
20}
21
22/// A DNS resolver backed by an embassy-net stack.
23pub struct DnsWithStack<'a> {
24    stack: Stack<'a>,
25}
26
27impl<'a> DnsWithStack<'a> {
28    /// Create a resolver backed by `stack`.
29    pub const fn new(stack: Stack<'a>) -> Self {
30        Self { stack }
31    }
32}
33
34impl Dns for DnsWithStack<'_> {
35    type Error = embassy_net::dns::Error;
36
37    async fn resolve(&mut self, hostname: &str) -> Result<Addresses, Self::Error> {
38        let resolved_addresses = self.stack.dns_query(hostname, DnsQueryType::A).await?;
39        let mut addresses = Addresses::new();
40        for address in resolved_addresses {
41            if addresses.push(address).is_err() {
42                break;
43            }
44        }
45        Ok(addresses)
46    }
47}