1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
use moka::future::Cache;
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
use tokio::task::JoinHandle;
use tracing::{error, info};
use crate::config::Config;
use crate::packet::question::DnsQuestion;
use crate::packet::{Result, Packet};
use super::binding::Binding;
use super::resolver::Resolver;
pub struct Server {
addr: SocketAddr,
config: Arc<Config>,
cache: Cache<DnsQuestion, (Packet, u64)>,
}
impl Server {
pub async fn new(config: Config) -> Result<Self> {
let addr = format!("[::]:{}", config.get_port()).parse::<SocketAddr>()?;
let cache = Cache::builder()
.time_to_live(Duration::from_secs(60 * 60))
.max_capacity(1_000)
.build();
Ok(Self {
addr,
config: Arc::new(config),
cache,
})
}
pub async fn run(&self) -> Result<()> {
let tcp = Binding::tcp(self.addr).await?;
let tcp_handle = self.listen(tcp);
let udp = Binding::udp(self.addr).await?;
let udp_handle = self.listen(udp);
info!("Fallback DNS Server is set to: {:?}", self.config.get_fallback_ns());
info!("Listening for TCP and UDP traffic on [::]:{}", self.config.get_port());
tokio::join!(tcp_handle)
.0
.expect("Failed to join tcp thread");
tokio::join!(udp_handle)
.0
.expect("Failed to join udp thread");
Ok(())
}
fn listen(&self, mut binding: Binding) -> JoinHandle<()> {
let config = self.config.clone();
let cache = self.cache.clone();
tokio::spawn(async move {
let mut id = 0;
loop {
let Ok(connection) = binding.connect().await else { continue };
info!("Received request on {}", binding.name());
let resolver = Resolver::new(id, connection, config.clone(), cache.clone());
if let Err(err) = resolver.handle_query().await {
error!("{} request {} failed: {:?}", binding.name(), id, err);
};
id += 1;
}
})
}
}
|