web_faith_dns/
settings.rs1use std::{fmt, net::SocketAddr, time::Duration};
3
4use hickory_resolver::{
5 config::{NameServerConfig, ProtocolConfig},
6 proto::rr::Name,
7};
8
9use crate::transport::{ServerSpec, Transport};
10
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
14#[non_exhaustive]
15pub enum ResolverSource {
16 Configured,
18 Conventional,
20}
21
22impl fmt::Display for ResolverSource {
23 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
24 f.write_str(match self {
25 Self::Configured => "configured",
26 Self::Conventional => "conventional",
27 })
28 }
29}
30
31#[derive(Clone, Debug)]
33#[non_exhaustive]
34pub struct ResolverReport {
35 pub address: SocketAddr,
37 pub transport: Transport,
39 pub source: ResolverSource,
41}
42
43pub const DEFAULT_MAX_STALE: Duration = Duration::from_secs(3600);
49
50#[derive(Clone, Debug)]
52pub struct ResolverConfig {
53 pub servers: Vec<ServerSpec>,
55 pub timeout: Option<Duration>,
58 pub ndots: Option<usize>,
60 pub search_domains: Option<Vec<Name>>,
62 pub hosts_file: Option<bool>,
64 pub exempt_domains: Vec<Name>,
66 pub serve_stale: Option<Duration>,
70}
71
72impl Default for ResolverConfig {
73 fn default() -> Self {
74 Self {
75 servers: Vec::new(),
76 timeout: None,
77 ndots: None,
78 search_domains: None,
79 hosts_file: None,
80 exempt_domains: Vec::new(),
81 serve_stale: Some(DEFAULT_MAX_STALE),
84 }
85 }
86}
87
88pub(crate) fn exempt_suffixes(system: Vec<Name>, configured: &[Name]) -> Vec<Name> {
98 let mut names = vec![
99 Name::from_ascii("localhost").unwrap(),
100 Name::from_ascii("local").unwrap(),
101 ];
102 names.extend(
103 system
104 .into_iter()
105 .chain(configured.iter().cloned())
106 .filter(|name| !name.is_root()),
107 );
108 names
109}
110
111pub(crate) fn report(
113 name_servers: &[NameServerConfig],
114 source: ResolverSource,
115) -> Vec<ResolverReport> {
116 let mut reports = Vec::new();
117 for server in name_servers {
118 for connection in &server.connections {
119 let transport = match connection.protocol {
120 ProtocolConfig::Udp => Transport::Udp,
121 ProtocolConfig::Tcp => Transport::Tcp,
122 ProtocolConfig::Tls { .. } => Transport::Tls,
123 ProtocolConfig::Https { .. } => Transport::Https,
124 ProtocolConfig::Quic { .. } => Transport::Quic,
125 ProtocolConfig::H3 { .. } => Transport::H3,
126 };
127 reports.push(ResolverReport {
128 address: SocketAddr::new(server.ip, connection.port),
129 transport,
130 source,
131 });
132 }
133 }
134 reports
135}
136
137#[cfg(test)]
138mod tests;