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