diff --git a/src/main.rs b/src/main.rs index 73e468a..92c4fc9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ use std::io::Write; -use std::net::ToSocketAddrs; +use std::net::{AddrParseError, IpAddr, ToSocketAddrs}; use std::process; use log::debug; @@ -26,6 +26,9 @@ struct ConfigOpts { location: String, username: String, token: String, + + #[clap(short, long)] + no_dns: bool, } #[derive(Clap, Debug)] @@ -78,6 +81,9 @@ struct WireguardConfigData { public_key: String, address: String, endpoint: String, + + #[serde(rename = "DNS")] + dns: String, } #[derive(Debug)] @@ -86,6 +92,15 @@ struct WireguardKeyPair { private_key: String, } +impl WireguardConfigData { + fn dns(&self) -> Result, AddrParseError> { + self.dns + .split(',') + .map(|s: &str| -> Result { s.trim().parse() }) + .collect() + } +} + fn main() -> Result<(), anyhow::Error> { env_logger::init(); let opts = Opts::parse(); @@ -135,11 +150,12 @@ fn get_config(_opts: &Opts, config_opts: &ConfigOpts) -> Result<(), anyhow::Erro .into_json()?; debug!("config = {:?}", &config); - write_config(&mut std::io::stdout().lock(), &config, &keys) + write_config(&mut std::io::stdout().lock(), &config_opts, &config, &keys) } fn write_config( output: &mut dyn Write, + config_opts: &ConfigOpts, config: &WireguardConfig, keys: &WireguardKeyPair, ) -> Result<(), anyhow::Error> { @@ -151,6 +167,11 @@ fn write_config( writeln!(output, "[Interface]")?; writeln!(output, "PrivateKey = {}", &keys.private_key)?; writeln!(output, "Address = {}", &config.data.address)?; + if !config_opts.no_dns { + write!(output, "DNS = ")?; + write_list(output, config.data.dns()?)?; + } + writeln!(output)?; writeln!(output, "[Peer]")?; writeln!(output, "PublicKey = {}", &config.data.public_key)?; @@ -160,6 +181,21 @@ fn write_config( Ok(()) } +fn write_list(output: &mut dyn Write, values: I) -> Result<(), std::io::Error> +where + I: IntoIterator, + T: std::fmt::Display, +{ + for (i, value) in values.into_iter().enumerate() { + if i != 0 { + write!(output, ", ")?; + } + write!(output, "{}", value)?; + } + writeln!(output)?; + Ok(()) +} + fn check(opts: &Opts) -> Result<(), anyhow::Error> { let url = format!("{}/check", BASE_URL); let result: CheckResult = ureq::get(&url).call()?.into_json()?;