Reworked DNS-resolver.
This commit is contained in:
Generated
+8
-1
@@ -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 }
|
||||||
|
|||||||
+13
-27
@@ -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);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
|
|||||||
Reference in New Issue
Block a user