2019-09-18 10:34:19 +00:00
|
|
|
use crate::crypto::*;
|
2019-09-19 18:47:44 +00:00
|
|
|
use crate::dnscrypt_certs::*;
|
2019-09-18 10:34:19 +00:00
|
|
|
use crate::errors::*;
|
|
|
|
|
2019-09-20 00:31:31 +00:00
|
|
|
use std::fs::File;
|
2019-09-19 10:30:31 +00:00
|
|
|
use std::io::prelude::*;
|
2019-09-20 00:31:31 +00:00
|
|
|
use std::mem;
|
2019-09-19 10:09:00 +00:00
|
|
|
use std::net::{IpAddr, SocketAddr};
|
2019-09-19 10:30:31 +00:00
|
|
|
use std::path::{Path, PathBuf};
|
2019-09-20 00:31:31 +00:00
|
|
|
use tokio::prelude::*;
|
2019-09-19 18:47:44 +00:00
|
|
|
|
2019-10-13 20:47:57 +00:00
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
|
|
pub struct AnonymizedDNSConfig {
|
|
|
|
pub enabled: bool,
|
2019-10-14 09:10:55 +00:00
|
|
|
pub allowed_ports: Vec<u16>,
|
2019-10-17 20:44:43 +00:00
|
|
|
pub allow_non_reserved_ports: Option<bool>,
|
2019-10-14 09:10:55 +00:00
|
|
|
pub blacklisted_ips: Vec<IpAddr>,
|
2019-10-13 20:47:57 +00:00
|
|
|
}
|
|
|
|
|
2019-10-01 18:58:51 +00:00
|
|
|
#[cfg(feature = "metrics")]
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
|
|
|
pub struct MetricsConfig {
|
|
|
|
pub r#type: String,
|
|
|
|
pub listen_addr: SocketAddr,
|
|
|
|
pub path: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
2019-09-19 10:09:00 +00:00
|
|
|
pub struct DNSCryptConfig {
|
2019-12-21 23:50:09 +00:00
|
|
|
pub enabled: Option<bool>,
|
2019-09-19 10:09:00 +00:00
|
|
|
pub provider_name: String,
|
2019-09-20 08:39:42 +00:00
|
|
|
pub key_cache_capacity: usize,
|
2019-09-22 11:44:45 +00:00
|
|
|
pub dnssec: bool,
|
|
|
|
pub no_filters: bool,
|
|
|
|
pub no_logs: bool,
|
2019-09-19 10:09:00 +00:00
|
|
|
}
|
|
|
|
|
2019-10-01 18:58:51 +00:00
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
2019-09-19 10:09:00 +00:00
|
|
|
pub struct TLSConfig {
|
|
|
|
pub upstream_addr: Option<SocketAddr>,
|
|
|
|
}
|
|
|
|
|
2019-10-01 18:58:51 +00:00
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
2019-09-22 11:44:45 +00:00
|
|
|
pub struct ListenAddrConfig {
|
|
|
|
pub local: SocketAddr,
|
|
|
|
pub external: SocketAddr,
|
|
|
|
}
|
|
|
|
|
2019-10-01 18:58:51 +00:00
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
2019-09-25 13:51:13 +00:00
|
|
|
pub struct FilteringConfig {
|
|
|
|
pub domain_blacklist: Option<PathBuf>,
|
2019-12-07 18:51:37 +00:00
|
|
|
pub undelegated_list: Option<PathBuf>,
|
2019-12-07 22:25:32 +00:00
|
|
|
pub ignore_unqualified_hostnames: Option<bool>,
|
2019-09-25 13:51:13 +00:00
|
|
|
}
|
|
|
|
|
2019-10-01 18:58:51 +00:00
|
|
|
#[derive(Serialize, Deserialize, Debug, Clone)]
|
2019-09-19 10:09:00 +00:00
|
|
|
pub struct Config {
|
2019-09-22 11:44:45 +00:00
|
|
|
pub listen_addrs: Vec<ListenAddrConfig>,
|
2019-10-19 09:36:16 +00:00
|
|
|
pub external_addr: Option<IpAddr>,
|
2019-09-19 10:09:00 +00:00
|
|
|
pub upstream_addr: SocketAddr,
|
|
|
|
pub state_file: PathBuf,
|
|
|
|
pub udp_timeout: u32,
|
|
|
|
pub tcp_timeout: u32,
|
|
|
|
pub udp_max_active_connections: u32,
|
|
|
|
pub tcp_max_active_connections: u32,
|
2019-09-20 22:53:20 +00:00
|
|
|
pub cache_capacity: usize,
|
2019-09-21 10:18:27 +00:00
|
|
|
pub cache_ttl_min: u32,
|
|
|
|
pub cache_ttl_max: u32,
|
|
|
|
pub cache_ttl_error: u32,
|
2019-09-19 10:57:24 +00:00
|
|
|
pub user: Option<String>,
|
|
|
|
pub group: Option<String>,
|
|
|
|
pub chroot: Option<String>,
|
2019-09-25 13:51:13 +00:00
|
|
|
pub filtering: FilteringConfig,
|
2019-09-19 10:09:00 +00:00
|
|
|
pub dnscrypt: DNSCryptConfig,
|
|
|
|
pub tls: TLSConfig,
|
2019-09-21 14:19:39 +00:00
|
|
|
pub daemonize: bool,
|
|
|
|
pub pid_file: Option<PathBuf>,
|
2019-09-21 14:29:13 +00:00
|
|
|
pub log_file: Option<PathBuf>,
|
2019-10-01 18:58:51 +00:00
|
|
|
#[cfg(feature = "metrics")]
|
|
|
|
pub metrics: Option<MetricsConfig>,
|
2019-10-13 20:47:57 +00:00
|
|
|
pub anonymized_dns: Option<AnonymizedDNSConfig>,
|
2019-09-19 10:09:00 +00:00
|
|
|
}
|
2019-09-18 10:34:19 +00:00
|
|
|
|
2019-09-19 10:30:31 +00:00
|
|
|
impl Config {
|
|
|
|
pub fn from_string(toml: &str) -> Result<Config, Error> {
|
|
|
|
let config: Config = match toml::from_str(toml) {
|
|
|
|
Ok(config) => config,
|
2019-11-01 19:56:07 +00:00
|
|
|
Err(e) => bail!("Parse error in the configuration file: {}", e),
|
2019-09-19 10:30:31 +00:00
|
|
|
};
|
|
|
|
Ok(config)
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn from_path<P: AsRef<Path>>(path: P) -> Result<Config, Error> {
|
|
|
|
let mut fd = File::open(path)?;
|
|
|
|
let mut toml = String::new();
|
|
|
|
fd.read_to_string(&mut toml)?;
|
|
|
|
Config::from_string(&toml)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-18 10:34:19 +00:00
|
|
|
#[derive(Serialize, Deserialize, Debug)]
|
|
|
|
pub struct State {
|
|
|
|
pub provider_kp: SignKeyPair,
|
2019-09-19 18:47:44 +00:00
|
|
|
pub dnscrypt_encryption_params_set: Vec<DNSCryptEncryptionParams>,
|
2019-09-18 10:34:19 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
impl State {
|
2019-09-20 09:25:24 +00:00
|
|
|
pub fn with_key_pair(provider_kp: SignKeyPair, key_cache_capacity: usize) -> Self {
|
2019-09-20 08:39:42 +00:00
|
|
|
let dnscrypt_encryption_params_set = vec![DNSCryptEncryptionParams::new(
|
|
|
|
&provider_kp,
|
|
|
|
key_cache_capacity,
|
|
|
|
)];
|
2019-09-19 18:47:44 +00:00
|
|
|
State {
|
|
|
|
provider_kp,
|
|
|
|
dnscrypt_encryption_params_set,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-09-20 09:25:24 +00:00
|
|
|
pub fn new(key_cache_capacity: usize) -> Self {
|
|
|
|
let provider_kp = SignKeyPair::new();
|
|
|
|
State::with_key_pair(provider_kp, key_cache_capacity)
|
|
|
|
}
|
|
|
|
|
2019-09-20 00:31:31 +00:00
|
|
|
pub async fn async_save<P: AsRef<Path>>(&self, path: P) -> Result<(), Error> {
|
|
|
|
let path_tmp = path.as_ref().with_extension("tmp");
|
|
|
|
let mut fpb = tokio::fs::OpenOptions::new();
|
|
|
|
let fpb = fpb.create(true).write(true);
|
|
|
|
let mut fp = fpb.open(&path_tmp).await?;
|
2019-09-19 18:47:44 +00:00
|
|
|
let state_bin = toml::to_vec(&self)?;
|
2019-09-20 00:31:31 +00:00
|
|
|
fp.write_all(&state_bin).await?;
|
|
|
|
fp.sync_data().await?;
|
|
|
|
mem::drop(fp);
|
|
|
|
tokio::fs::rename(path_tmp, path).await?;
|
2019-09-19 18:47:44 +00:00
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2019-09-20 08:39:42 +00:00
|
|
|
pub fn from_file<P: AsRef<Path>>(path: P, key_cache_capacity: usize) -> Result<Self, Error> {
|
2019-09-19 18:47:44 +00:00
|
|
|
let mut fp = File::open(path.as_ref())?;
|
|
|
|
let mut state_bin = vec![];
|
|
|
|
fp.read_to_end(&mut state_bin)?;
|
2019-09-20 08:39:42 +00:00
|
|
|
let mut state: State = toml::from_slice(&state_bin)?;
|
|
|
|
for params_set in &mut state.dnscrypt_encryption_params_set {
|
|
|
|
params_set.add_key_cache(key_cache_capacity);
|
|
|
|
}
|
2019-09-19 18:47:44 +00:00
|
|
|
Ok(state)
|
2019-09-18 10:34:19 +00:00
|
|
|
}
|
|
|
|
}
|