embassy/embassy-net/src/dns.rs

109 lines
3.1 KiB
Rust
Raw Normal View History

2023-05-15 00:39:57 +02:00
//! DNS client compatible with the `embedded-nal-async` traits.
//!
//! This exists only for compatibility with crates that use `embedded-nal-async`.
//! Prefer using [`Stack::dns_query`](crate::Stack::dns_query) directly if you're
//! not using `embedded-nal-async`.
2023-01-31 22:06:41 +01:00
use heapless::Vec;
pub use smoltcp::socket::dns::{DnsQuery, Socket};
2023-02-10 17:43:23 +01:00
pub(crate) use smoltcp::socket::dns::{GetQueryResultError, StartQueryError};
2023-01-31 22:06:41 +01:00
pub use smoltcp::wire::{DnsQueryType, IpAddress};
2023-02-10 17:43:23 +01:00
use crate::{Driver, Stack};
2023-01-31 22:06:41 +01:00
/// Errors returned by DnsSocket.
#[derive(Debug, PartialEq, Eq, Clone, Copy)]
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
pub enum Error {
/// Invalid name
InvalidName,
/// Name too long
NameTooLong,
/// Name lookup failed
Failed,
}
impl From<GetQueryResultError> for Error {
fn from(_: GetQueryResultError) -> Self {
Self::Failed
}
}
impl From<StartQueryError> for Error {
fn from(e: StartQueryError) -> Self {
match e {
2023-02-10 18:44:51 +01:00
StartQueryError::NoFreeSlot => Self::Failed,
2023-01-31 22:06:41 +01:00
StartQueryError::InvalidName => Self::InvalidName,
StartQueryError::NameTooLong => Self::NameTooLong,
}
}
}
2023-05-15 00:39:57 +02:00
/// DNS client compatible with the `embedded-nal-async` traits.
///
/// This exists only for compatibility with crates that use `embedded-nal-async`.
/// Prefer using [`Stack::dns_query`](crate::Stack::dns_query) directly if you're
/// not using `embedded-nal-async`.
2023-02-10 17:43:23 +01:00
pub struct DnsSocket<'a, D>
where
D: Driver + 'static,
{
stack: &'a Stack<D>,
2023-01-31 22:06:41 +01:00
}
2023-02-10 17:43:23 +01:00
impl<'a, D> DnsSocket<'a, D>
where
D: Driver + 'static,
{
/// Create a new DNS socket using the provided stack.
2023-01-31 22:06:41 +01:00
///
/// NOTE: If using DHCP, make sure it has reconfigured the stack to ensure the DNS servers are updated.
2023-02-10 17:43:23 +01:00
pub fn new(stack: &'a Stack<D>) -> Self {
Self { stack }
2023-01-31 22:06:41 +01:00
}
/// Make a query for a given name and return the corresponding IP addresses.
pub async fn query(&self, name: &str, qtype: DnsQueryType) -> Result<Vec<IpAddress, 1>, Error> {
2023-02-10 17:43:23 +01:00
self.stack.dns_query(name, qtype).await
}
}
2023-01-31 22:06:41 +01:00
2023-08-07 13:43:09 +02:00
#[cfg(feature = "nightly")]
2023-02-10 17:43:23 +01:00
impl<'a, D> embedded_nal_async::Dns for DnsSocket<'a, D>
where
D: Driver + 'static,
{
type Error = Error;
2023-02-06 20:18:12 +01:00
2023-02-10 17:43:23 +01:00
async fn get_host_by_name(
&self,
host: &str,
addr_type: embedded_nal_async::AddrType,
) -> Result<embedded_nal_async::IpAddr, Self::Error> {
use embedded_nal_async::{AddrType, IpAddr};
let qtype = match addr_type {
AddrType::IPv6 => DnsQueryType::Aaaa,
_ => DnsQueryType::A,
};
let addrs = self.query(host, qtype).await?;
if let Some(first) = addrs.get(0) {
Ok(match first {
2023-06-05 16:00:53 +02:00
#[cfg(feature = "proto-ipv4")]
2023-02-10 17:43:23 +01:00
IpAddress::Ipv4(addr) => IpAddr::V4(addr.0.into()),
2023-02-10 19:38:17 +01:00
#[cfg(feature = "proto-ipv6")]
2023-02-10 17:43:23 +01:00
IpAddress::Ipv6(addr) => IpAddr::V6(addr.0.into()),
2023-01-31 22:06:41 +01:00
})
2023-02-10 17:43:23 +01:00
} else {
Err(Error::Failed)
}
2023-01-31 22:06:41 +01:00
}
2023-02-10 17:43:23 +01:00
async fn get_host_by_address(
&self,
_addr: embedded_nal_async::IpAddr,
_result: &mut [u8],
) -> Result<usize, Self::Error> {
2023-02-10 17:43:23 +01:00
todo!()
2023-01-31 22:06:41 +01:00
}
}