Reworked DNS-resolver.

pull/313/head
Revertron 2 years ago
parent 287e88c7e2
commit e5657d6802

9
Cargo.lock generated

@ -84,7 +84,7 @@ dependencies = [
[[package]] [[package]]
name = "alfis" name = "alfis"
version = "0.8.2" version = "0.8.3"
dependencies = [ dependencies = [
"base64", "base64",
"bincode", "bincode",
@ -115,6 +115,7 @@ dependencies = [
"sha2 0.10.6", "sha2 0.10.6",
"signature", "signature",
"simplelog", "simplelog",
"spmc",
"sqlite", "sqlite",
"thread-priority", "thread-priority",
"time 0.3.14", "time 0.3.14",
@ -1189,6 +1190,12 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]]
name = "spmc"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "02a8428da277a8e3a15271d79943e80ccc2ef254e78813a166a08d65e4c3ece5"
[[package]] [[package]]
name = "sqlite" name = "sqlite"
version = "0.26.0" version = "0.26.0"

@ -43,6 +43,7 @@ ureq = { version = "2.5", optional = true }
lru = "0.8.1" lru = "0.8.1"
derive_more = "0.99.17" derive_more = "0.99.17"
lazy_static = "1.4.0" lazy_static = "1.4.0"
spmc = "0.3.0"
# Optional dependencies regulated by features # Optional dependencies regulated by features
web-view = { version = "0.7.3", features = [], optional = true } web-view = { version = "0.7.3", features = [], optional = true }

@ -1,12 +1,11 @@
//! UDP and TCP server implementations for DNS //! UDP and TCP server implementations for DNS
use std::collections::VecDeque;
use std::io::Write; use std::io::Write;
use std::net::{Shutdown, SocketAddr, TcpListener, TcpStream, UdpSocket}; use std::net::{Shutdown, SocketAddr, TcpListener, TcpStream, UdpSocket};
use std::num::NonZeroUsize; use std::num::NonZeroUsize;
use std::sync::atomic::Ordering; use std::sync::atomic::Ordering;
use std::sync::mpsc::{channel, Sender}; use std::sync::mpsc::{channel, Sender};
use std::sync::{Arc, Condvar, Mutex}; use std::sync::Arc;
use std::thread::Builder; use std::thread::Builder;
use derive_more::{Display, Error, From}; use derive_more::{Display, Error, From};
@ -162,14 +161,12 @@ pub fn execute_query(context: Arc<ServerContext>, request: &DnsPacket) -> DnsPac
/// a new thread is spawned to service the request asynchronously. /// a new thread is spawned to service the request asynchronously.
pub struct DnsUdpServer { pub struct DnsUdpServer {
context: Arc<ServerContext>, context: Arc<ServerContext>,
request_queue: Arc<Mutex<VecDeque<(SocketAddr, DnsPacket)>>>,
request_cond: Arc<Condvar>,
thread_count: usize thread_count: usize
} }
impl DnsUdpServer { impl DnsUdpServer {
pub fn new(context: Arc<ServerContext>, thread_count: usize) -> DnsUdpServer { pub fn new(context: Arc<ServerContext>, thread_count: usize) -> DnsUdpServer {
DnsUdpServer { context, request_queue: Arc::new(Mutex::new(VecDeque::new())), request_cond: Arc::new(Condvar::new()), thread_count } DnsUdpServer { context, thread_count }
} }
} }
@ -181,6 +178,8 @@ impl DnsServer for DnsUdpServer {
// Bind the socket // Bind the socket
let socket = UdpSocket::bind(self.context.dns_listen.as_str())?; let socket = UdpSocket::bind(self.context.dns_listen.as_str())?;
let (mut sender, receiver) = spmc::channel::<(SocketAddr, DnsPacket)>();
// Spawn threads for handling requests // Spawn threads for handling requests
for thread_id in 0..self.thread_count { for thread_id in 0..self.thread_count {
let socket_clone = match socket.try_clone() { let socket_clone = match socket.try_clone() {
@ -192,23 +191,16 @@ impl DnsServer for DnsUdpServer {
}; };
let context = Arc::clone(&self.context); let context = Arc::clone(&self.context);
let request_cond = self.request_cond.clone(); let receiver = receiver.clone();
let request_queue = self.request_queue.clone();
let name = "DnsUdpServer-request-".to_string() + &thread_id.to_string(); let name = "DnsUdpServer-request-".to_string() + &thread_id.to_string();
let _ = Builder::new().name(name).spawn(move || { let _ = Builder::new().name(name).spawn(move || {
loop { loop {
// Acquire lock, and wait on the condition until data is // Receive source address and packet from channel
// available. Then proceed with popping an entry of the queue. let (src, request) = match receiver.recv() {
let (src, request) = match request_queue Ok((src, request)) => (src, request),
.lock() Err(e) => {
.ok() debug!("Not expected to happen! Error: {}", e);
.and_then(|x| request_cond.wait(x).ok())
.and_then(|mut x| x.pop_front())
{
Some(x) => x,
None => {
debug!("Not expected to happen!");
continue; continue;
} }
}; };
@ -278,15 +270,9 @@ impl DnsServer for DnsUdpServer {
} }
working_ids.put(key, cur_time); working_ids.put(key, cur_time);
// Acquire lock, add request to queue, and notify waiting threads using the condition. if let Err(e) = sender.send((src, request)) {
match self.request_queue.lock() { warn!("Error sending work to DNS resolver threads! Error: {}", e);
Ok(mut queue) => { continue;
queue.push_back((src, request));
self.request_cond.notify_one();
}
Err(e) => {
debug!("Failed to send UDP request for processing: {}", e);
}
} }
} }
})?; })?;

Loading…
Cancel
Save