1use crate::dns::{get_forward_authority, load_zone};
2use std::net::SocketAddr;
3use std::str::FromStr;
4use tokio::net::UdpSocket;
5use trust_dns_resolver::Name;
6use trust_dns_server::authority::Catalog;
7use trust_dns_server::ServerFuture;
8
9mod config;
10mod dns;
11mod error;
12
13pub use config::Config;
14pub use error::SimpleDnsError;
15
16pub struct SimpleDns {
17 addr: SocketAddr,
18 catalog: Catalog,
19}
20
21impl SimpleDns {
22 pub async fn try_load(config: Config) -> Result<Self, SimpleDnsError> {
23 let mut catalog = Catalog::new();
24 for (domain, records) in config.domains {
25 let name = Name::from_str(&domain)?;
26 let authority = load_zone(&domain, records)?;
27
28 catalog.upsert(name.into(), authority);
29 }
30
31 let origin = Name::from_str(".")?;
32 let authority = get_forward_authority(origin.clone()).await?;
33 catalog.upsert(origin.into(), authority);
34
35 Ok(SimpleDns {
36 addr: config.bind,
37 catalog,
38 })
39 }
40
41 pub async fn run(self) -> Result<(), SimpleDnsError> {
42 let mut server_fut = ServerFuture::new(self.catalog);
43 let udp_socket = UdpSocket::bind(self.addr).await?;
44 server_fut.register_socket(udp_socket);
45
46 server_fut.block_until_done().await?;
47
48 Ok(())
49 }
50}