1#![allow(unused)]
2
3use std::{net::SocketAddr, sync::mpsc::channel};
4
5use crate::{
6 custom_handler::{CustomHandler, EmptyHandler, HandlerHolder},
7 dns_socket::DnsSocket,
8};
9
10pub struct Builder {
11 icann_resolver: SocketAddr,
12 listen: SocketAddr,
13 handler: HandlerHolder,
14}
15
16impl Builder {
17 pub fn new() -> Self {
18 Self {
19 icann_resolver: SocketAddr::from(([192, 168, 1, 1], 53)),
20 listen: SocketAddr::from(([0, 0, 0, 0], 53)),
21 handler: HandlerHolder::new(EmptyHandler::new()),
22 }
23 }
24
25 pub fn icann_resolver(mut self, icann_resolver: SocketAddr) -> Self {
27 self.icann_resolver = icann_resolver;
28 self
29 }
30
31 pub fn listen(mut self, listen: SocketAddr) -> Self {
33 self.listen = listen;
34 self
35 }
36
37 pub fn handler(mut self, handler: impl CustomHandler + 'static) -> Self {
39 self.handler = HandlerHolder::new(handler);
40 self
41 }
42
43 pub async fn build(self) -> tokio::io::Result<AnyDNS> {
45 AnyDNS::new(self.listen, self.icann_resolver, self.handler).await
46 }
47}
48
49#[derive(Debug)]
50pub struct AnyDNS {
51 join_handle: tokio::task::JoinHandle<()>,
52}
53
54impl AnyDNS {
55 pub async fn new(
56 listener: SocketAddr,
57 icann_fallback: SocketAddr,
58 handler: HandlerHolder,
59 ) -> tokio::io::Result<Self> {
60 let mut socket = DnsSocket::new(listener, icann_fallback, handler).await?;
61 let join_handle = tokio::spawn(async move {
62 socket.receive_loop().await;
63 });
64
65 let server = Self { join_handle };
66
67 Ok(server)
68 }
69
70 pub fn stop(self) {
74 self.join_handle.abort();
75 }
76
77 pub async fn wait_on_ctrl_c(&self) {
81 match tokio::signal::ctrl_c().await {
82 Ok(()) => {}
83 Err(err) => {
84 eprintln!("Unable to listen for shutdown signal Ctrl+C: {}", err);
85 }
86 }
87 }
88}
89
90#[cfg(test)]
91mod tests {
92 use std::{net::SocketAddr, thread::sleep, time::Duration};
93
94 use crate::server::Builder;
95
96 #[tokio::test]
97 async fn run() {
98 let listening: SocketAddr = "0.0.0.0:34255".parse().unwrap();
99 let dns = Builder::new().listen(listening).build().await.unwrap();
100 println!("Started");
101 sleep(Duration::from_secs(5));
102 println!("Stop");
103 dns.stop();
104 println!("Stopped");
105
106 }
119}