use crate::server::RequestHandler;
use std::net::SocketAddr;
use std::sync::Arc;
use std::time::Duration;
#[cfg(any(feature = "doh", feature = "dot"))]
use crate::server::TlsConfig;
#[derive(Clone)]
pub struct ServerConfig {
pub udp_addr: Option<SocketAddr>,
pub tcp_addr: Option<SocketAddr>,
pub max_connections: usize,
pub timeout: Duration,
pub max_udp_size: usize,
pub max_tcp_size: usize,
pub handler: Option<Arc<dyn RequestHandler>>,
#[cfg(any(feature = "doh", feature = "dot"))]
pub tls_config: Option<TlsConfig>,
pub cert_path: Option<String>,
pub key_path: Option<String>,
pub doh_path: Option<String>,
}
impl std::fmt::Debug for ServerConfig {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_struct("ServerConfig")
.field("udp_addr", &self.udp_addr)
.field("tcp_addr", &self.tcp_addr)
.field("max_connections", &self.max_connections)
.field("timeout", &self.timeout)
.field("max_udp_size", &self.max_udp_size)
.field("max_tcp_size", &self.max_tcp_size)
.field("handler", &self.handler.as_ref().map(|_| "<handler>"))
.field("cert_path", &self.cert_path)
.field("key_path", &self.key_path)
.field("doh_path", &self.doh_path)
.finish()
}
}
impl Default for ServerConfig {
fn default() -> Self {
Self {
udp_addr: Some("127.0.0.1:5353".parse().unwrap()),
tcp_addr: Some("127.0.0.1:5353".parse().unwrap()),
max_connections: 1000,
timeout: Duration::from_secs(5),
max_udp_size: 512,
max_tcp_size: 65535,
handler: None,
#[cfg(any(feature = "doh", feature = "dot"))]
tls_config: None,
cert_path: None,
key_path: None,
doh_path: None,
}
}
}
impl ServerConfig {
pub fn new(udp_addr: Option<SocketAddr>, tcp_addr: Option<SocketAddr>) -> Self {
Self {
udp_addr,
tcp_addr,
..Default::default()
}
}
pub fn with_udp_addr(mut self, addr: SocketAddr) -> Self {
self.udp_addr = Some(addr);
self
}
pub fn with_tcp_addr(mut self, addr: SocketAddr) -> Self {
self.tcp_addr = Some(addr);
self
}
pub fn with_max_connections(mut self, max: usize) -> Self {
self.max_connections = max;
self
}
pub fn with_timeout(mut self, timeout: Duration) -> Self {
self.timeout = timeout;
self
}
pub fn with_max_udp_size(mut self, size: usize) -> Self {
self.max_udp_size = size;
self
}
pub fn with_max_tcp_size(mut self, size: usize) -> Self {
self.max_tcp_size = size;
self
}
pub fn with_handler(mut self, handler: Arc<dyn RequestHandler>) -> Self {
self.handler = Some(handler);
self
}
#[cfg(any(feature = "doh", feature = "dot"))]
pub fn with_tls_config(mut self, tls_config: TlsConfig) -> Self {
self.tls_config = Some(tls_config);
self
}
pub fn with_cert_paths(mut self, cert_path: String, key_path: String) -> Self {
self.cert_path = Some(cert_path);
self.key_path = Some(key_path);
self
}
pub fn with_doh_path(mut self, path: String) -> Self {
self.doh_path = Some(path);
self
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::str::FromStr;
#[test]
fn test_default_config() {
let config = ServerConfig::default();
assert!(config.udp_addr.is_some());
assert!(config.tcp_addr.is_some());
assert_eq!(config.max_connections, 1000);
assert_eq!(config.timeout, Duration::from_secs(5));
assert_eq!(config.max_udp_size, 512);
assert_eq!(config.max_tcp_size, 65535);
}
#[test]
fn test_builder_pattern() {
let addr = SocketAddr::from_str("192.0.2.1:53").unwrap();
let config = ServerConfig::default()
.with_udp_addr(addr)
.with_max_connections(500)
.with_timeout(Duration::from_secs(10));
assert_eq!(config.udp_addr, Some(addr));
assert_eq!(config.max_connections, 500);
assert_eq!(config.timeout, Duration::from_secs(10));
}
#[test]
fn test_new_config() {
let udp = SocketAddr::from_str("192.0.2.1:53").unwrap();
let tcp = SocketAddr::from_str("192.0.2.2:53").unwrap();
let config = ServerConfig::new(Some(udp), Some(tcp));
assert_eq!(config.udp_addr, Some(udp));
assert_eq!(config.tcp_addr, Some(tcp));
}
}