1 use crate::crypto::*;
2 use crate::dnscrypt_certs::*;
3 use crate::errors::*;
4 
5 use std::fs;
6 use std::mem;
7 use std::net::{IpAddr, SocketAddr};
8 use std::path::{Path, PathBuf};
9 use tokio::io::AsyncWriteExt;
10 
11 #[derive(Serialize, Deserialize, Debug, Clone)]
12 pub struct AccessControlConfig {
13     pub enabled: bool,
14     pub tokens: Vec<String>,
15 }
16 
17 #[derive(Serialize, Deserialize, Debug, Clone)]
18 pub struct AnonymizedDNSConfig {
19     pub enabled: bool,
20     pub allowed_ports: Vec<u16>,
21     pub allow_non_reserved_ports: Option<bool>,
22     pub blacklisted_ips: Vec<IpAddr>,
23 }
24 
25 #[cfg(feature = "metrics")]
26 #[derive(Serialize, Deserialize, Debug, Clone)]
27 pub struct MetricsConfig {
28     pub r#type: String,
29     pub listen_addr: SocketAddr,
30     pub path: String,
31 }
32 
33 #[derive(Serialize, Deserialize, Debug, Clone)]
34 pub struct DNSCryptConfig {
35     pub enabled: Option<bool>,
36     pub provider_name: String,
37     pub key_cache_capacity: usize,
38     pub dnssec: bool,
39     pub no_filters: bool,
40     pub no_logs: bool,
41 }
42 
43 #[derive(Serialize, Deserialize, Debug, Clone)]
44 pub struct TLSConfig {
45     pub upstream_addr: Option<SocketAddr>,
46 }
47 
48 #[derive(Serialize, Deserialize, Debug, Clone)]
49 pub struct ListenAddrConfig {
50     pub local: SocketAddr,
51     pub external: SocketAddr,
52 }
53 
54 #[derive(Serialize, Deserialize, Debug, Clone)]
55 pub struct FilteringConfig {
56     pub domain_blacklist: Option<PathBuf>,
57     pub undelegated_list: Option<PathBuf>,
58     pub ignore_unqualified_hostnames: Option<bool>,
59 }
60 
61 #[derive(Serialize, Deserialize, Debug, Clone)]
62 pub struct Config {
63     pub listen_addrs: Vec<ListenAddrConfig>,
64     pub external_addr: Option<IpAddr>,
65     pub upstream_addr: SocketAddr,
66     pub state_file: PathBuf,
67     pub udp_timeout: u32,
68     pub tcp_timeout: u32,
69     pub udp_max_active_connections: u32,
70     pub tcp_max_active_connections: u32,
71     pub cache_capacity: usize,
72     pub cache_ttl_min: u32,
73     pub cache_ttl_max: u32,
74     pub cache_ttl_error: u32,
75     pub user: Option<String>,
76     pub group: Option<String>,
77     pub chroot: Option<String>,
78     pub filtering: FilteringConfig,
79     pub dnscrypt: DNSCryptConfig,
80     pub tls: TLSConfig,
81     pub daemonize: bool,
82     pub pid_file: Option<PathBuf>,
83     pub log_file: Option<PathBuf>,
84     pub my_ip: Option<String>,
85     pub client_ttl_holdon: Option<u32>,
86     #[cfg(feature = "metrics")]
87     pub metrics: Option<MetricsConfig>,
88     pub anonymized_dns: Option<AnonymizedDNSConfig>,
89     pub access_control: Option<AccessControlConfig>,
90 }
91 
92 impl Config {
from_string(toml: &str) -> Result<Config, Error>93     pub fn from_string(toml: &str) -> Result<Config, Error> {
94         let config: Config = match toml::from_str(toml) {
95             Ok(config) => config,
96             Err(e) => bail!("Parse error in the configuration file: {}", e),
97         };
98         Ok(config)
99     }
100 
from_path(path: impl AsRef<Path>) -> Result<Config, Error>101     pub fn from_path(path: impl AsRef<Path>) -> Result<Config, Error> {
102         let toml = fs::read_to_string(path)?;
103         Config::from_string(&toml)
104     }
105 }
106 
107 #[derive(Serialize, Deserialize, Debug)]
108 pub struct State {
109     pub provider_kp: SignKeyPair,
110     pub dnscrypt_encryption_params_set: Vec<DNSCryptEncryptionParams>,
111 }
112 
113 impl State {
with_key_pair(provider_kp: SignKeyPair, key_cache_capacity: usize) -> Self114     pub fn with_key_pair(provider_kp: SignKeyPair, key_cache_capacity: usize) -> Self {
115         let dnscrypt_encryption_params_set =
116             DNSCryptEncryptionParams::new(&provider_kp, key_cache_capacity, None);
117         State {
118             provider_kp,
119             dnscrypt_encryption_params_set,
120         }
121     }
122 
new(key_cache_capacity: usize) -> Self123     pub fn new(key_cache_capacity: usize) -> Self {
124         let provider_kp = SignKeyPair::new();
125         State::with_key_pair(provider_kp, key_cache_capacity)
126     }
127 
async_save(&self, path: impl AsRef<Path>) -> Result<(), Error>128     pub async fn async_save(&self, path: impl AsRef<Path>) -> Result<(), Error> {
129         let path_tmp = path.as_ref().with_extension("tmp");
130         let mut fpb = tokio::fs::OpenOptions::new();
131         let fpb = fpb.create(true).write(true);
132         let mut fp = fpb.open(&path_tmp).await?;
133         let state_bin = toml::to_vec(&self)?;
134         fp.write_all(&state_bin).await?;
135         fp.sync_data().await?;
136         mem::drop(fp);
137         tokio::fs::rename(path_tmp, path).await?;
138         Ok(())
139     }
140 
from_file(path: impl AsRef<Path>, key_cache_capacity: usize) -> Result<Self, Error>141     pub fn from_file(path: impl AsRef<Path>, key_cache_capacity: usize) -> Result<Self, Error> {
142         let state_bin = fs::read(path)?;
143         let mut state: State = toml::from_slice(&state_bin)?;
144         for params_set in &mut state.dnscrypt_encryption_params_set {
145             params_set.add_key_cache(key_cache_capacity);
146         }
147         Ok(state)
148     }
149 }
150