Skip to content

Commit

Permalink
migrating to the new framework
Browse files Browse the repository at this point in the history
  • Loading branch information
junkurihara committed Oct 5, 2023
1 parent 1889c8b commit 0e46b63
Show file tree
Hide file tree
Showing 13 changed files with 338 additions and 53 deletions.
3 changes: 3 additions & 0 deletions dap-bin/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
doh-auth-proxy-lib = { path = "../dap-lib/" }

anyhow = "1.0.75"
mimalloc = { version = "*", default-features = false }
serde = { version = "1.0.188", default-features = false, features = ["derive"] }
Expand All @@ -51,3 +53,4 @@ hot_reload = "0.1.4"
# logging
tracing = { version = "0.1.37" }
tracing-subscriber = { version = "0.3.17", features = ["env-filter"] }
url = "2.4.1"
1 change: 1 addition & 0 deletions dap-bin/src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
mod parse;
mod service;
mod toml;
mod utils_verifier;

pub use {
self::toml::ConfigToml,
Expand Down
15 changes: 6 additions & 9 deletions dap-bin/src/config/parse.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use super::toml::ConfigToml;
use crate::error::{anyhow, ensure};
use clap::{Arg, ArgAction};
use doh_auth_proxy_lib::ProxyConfig;

/// Parsed options
pub struct Opts {
Expand Down Expand Up @@ -39,14 +40,10 @@ pub fn parse_opts() -> Result<Opts, anyhow::Error> {
})
}

pub fn build_settings(
config: &ConfigToml,
// ) -> std::result::Result<(ProxyConfig, AppConfigList<CryptoFileSource>), anyhow::Error> {
) -> std::result::Result<(), anyhow::Error> {
println!("{:#?}", config);
// ///////////////////////////////////
// // build proxy config
// let proxy_config: ProxyConfig = config.try_into()?;
pub fn build_settings(config: &ConfigToml) -> std::result::Result<ProxyConfig, anyhow::Error> {
///////////////////////////////////
// build proxy config
let proxy_config: ProxyConfig = config.try_into()?;

// ///////////////////////////////////
// // backend_apps
Expand Down Expand Up @@ -92,5 +89,5 @@ pub fn build_settings(
// };

// Ok((proxy_config, app_config_list))
Ok(())
Ok(proxy_config)
}
73 changes: 72 additions & 1 deletion dap-bin/src/config/toml.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
use crate::error::*;
use super::utils_verifier::*;
use crate::{error::*, log::*};
use doh_auth_proxy_lib::{DoHMethod, NextHopRelayConfig, ProxyConfig, SubseqRelayConfig, TargetConfig};
use serde::Deserialize;
use std::fs;
use tokio::time::Duration;

#[derive(Deserialize, Debug, Default, PartialEq, Eq, Clone)]
pub struct ConfigToml {
Expand Down Expand Up @@ -42,3 +45,71 @@ impl ConfigToml {
toml::from_str(&config_str).map_err(|e| anyhow!(e))
}
}

impl TryInto<ProxyConfig> for &ConfigToml {
type Error = anyhow::Error;

fn try_into(self) -> Result<ProxyConfig, Self::Error> {
let mut proxy_config = ProxyConfig::default();

/////////////////////////////
// listen addresses
if let Some(val) = &self.listen_addresses {
if !val.iter().all(|v| verify_sock_addr(v).is_ok()) {
bail!("Invalid listen address");
}
proxy_config.listen_addresses = val.iter().map(|x| x.parse().unwrap()).collect();
};

/////////////////////////////
// bootstrap dns
if let Some(val) = &self.bootstrap_dns {
if !val.iter().all(|v| verify_sock_addr(v).is_ok()) {
bail!("Invalid bootstrap DNS address");
}
proxy_config.bootstrap_dns = val.iter().map(|x| x.parse().unwrap()).collect()
};
info!("Bootstrap DNS: {:?}", proxy_config.bootstrap_dns);
if let Some(val) = self.reboot_period {
proxy_config.rebootstrap_period_sec = Duration::from_secs((val as u64) * 60);
}
info!(
"Target DoH Address is re-fetched every {:?} min via Bootsrap DNS",
proxy_config.rebootstrap_period_sec.as_secs() / 60
);

/////////////////////////////
// cache size
if let Some(val) = self.max_cache_size {
proxy_config.max_cache_size = val;
}
info!("Max cache size: {} (entries)", proxy_config.max_cache_size);

/////////////////////////////
// DoH target and method
if let Some(val) = &self.target_urls {
if !val.iter().all(|x| verify_target_url(x).is_ok()) {
bail!("Invalid target urls");
}
proxy_config.target_config.doh_target_urls = val.to_owned();
}
info!(
"Target (O)DoH resolvers: {:?}",
proxy_config.target_config.doh_target_urls
);
if let Some(val) = &self.target_randomization {
if !val {
proxy_config.target_config.target_randomization = false;
info!("Target randomization is disbled");
}
}
if let Some(val) = self.use_get_method {
if val {
proxy_config.target_config.doh_method = DoHMethod::Get;
info!("Use GET method for query");
}
}

Ok(proxy_config)
}
}
31 changes: 31 additions & 0 deletions dap-bin/src/config/utils_verifier.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// functions to verify the startup arguments as correct
use std::net::SocketAddr;
use url::Url;

pub(crate) fn verify_sock_addr(arg_val: &str) -> Result<(), String> {
match arg_val.parse::<SocketAddr>() {
Ok(_addr) => Ok(()),
Err(_) => Err(format!(
"Could not parse \"{}\" as a valid socket address (with port).",
arg_val
)),
}
}

pub(crate) fn verify_target_url(arg_val: &str) -> Result<(), String> {
let url = match Url::parse(arg_val) {
Ok(addr) => addr,
Err(_) => return Err(format!("Could not parse \"{}\" as a valid url.", arg_val)),
};

match url.scheme() {
"http" => (),
"https" => (),
_ => return Err("Invalid scheme".to_string()),
};

if url.cannot_be_a_base() {
return Err("Invalid scheme".to_string());
}
Ok(())
}
77 changes: 36 additions & 41 deletions dap-bin/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ use crate::{
constants::CONFIG_WATCH_DELAY_SECS,
log::*,
};
use doh_auth_proxy_lib::entrypoint;
use hot_reload::{ReloaderReceiver, ReloaderService};

fn main() {
Expand Down Expand Up @@ -69,21 +70,18 @@ async fn proxy_service_without_watcher(
std::process::exit(1);
}
};
// let (proxy_conf, app_conf) = match build_settings(&config_toml) {
match build_settings(&config_toml) {

let proxy_conf = match build_settings(&config_toml) {
Ok(v) => v,
Err(e) => {
error!("Invalid configuration: {e}");
return Err(anyhow::anyhow!(e));
}
};
println!("build");

// entrypoint(&proxy_conf, &app_conf, &runtime_handle, None)
// .await
// .map_err(|e| anyhow::anyhow!(e))
tokio::time::sleep(tokio::time::Duration::from_secs(10)).await;
Ok(())
entrypoint(&proxy_conf, &runtime_handle, None)
.await
.map_err(|e| anyhow::anyhow!(e))
}

async fn proxy_service_with_watcher(
Expand All @@ -94,8 +92,7 @@ async fn proxy_service_with_watcher(
// Initial loading
config_rx.changed().await?;
let config_toml = config_rx.borrow().clone().unwrap();
// let (mut proxy_conf, mut app_conf) = match build_settings(&config_toml) {
match build_settings(&config_toml) {
let mut proxy_conf = match build_settings(&config_toml) {
Ok(v) => v,
Err(e) => {
error!("Invalid configuration: {e}");
Expand All @@ -104,38 +101,36 @@ async fn proxy_service_with_watcher(
};

// Notifier for proxy service termination
let _term_notify = std::sync::Arc::new(tokio::sync::Notify::new());
let term_notify = std::sync::Arc::new(tokio::sync::Notify::new());

// Continuous monitoring
// loop {
// tokio::select! {
// _ = entrypoint(&proxy_conf, &app_conf, &runtime_handle, Some(term_notify.clone())) => {
// error!("proxy entrypoint exited");
// break;
// }
// _ = config_rx.changed() => {
// if config_rx.borrow().is_none() {
// error!("Something wrong in config reloader receiver");
// break;
// }
// let config_toml = config_rx.borrow().clone().unwrap();
// match build_settings(&config_toml) {
// Ok((p, a)) => {
// (proxy_conf, app_conf) = (p, a)
// },
// Err(e) => {
// error!("Invalid configuration. Configuration does not updated: {e}");
// continue;
// }
// };
// info!("Configuration updated. Terminate all spawned proxy services and force to re-bind TCP/UDP sockets");
// term_notify.notify_waiters();
// // tokio::time::sleep(tokio::time::Duration::from_secs(1)).await;
// }
// else => break
// }
// }
loop {
tokio::select! {
_ = entrypoint(&proxy_conf, &runtime_handle, Some(term_notify.clone())) => {
error!("proxy entrypoint exited");
break;
}
_ = config_rx.changed() => {
if config_rx.borrow().is_none() {
error!("Something wrong in config reloader receiver");
break;
}
let config_toml = config_rx.borrow().clone().unwrap();
match build_settings(&config_toml) {
Ok(p) => {
proxy_conf = p
},
Err(e) => {
error!("Invalid configuration. Configuration does not updated: {e}");
continue;
}
};
info!("Configuration updated. Terminate all spawned proxy services and force to re-bind TCP/UDP sockets");
term_notify.notify_waiters();
}
else => break
}
}

// Err(anyhow::anyhow!("proxy or continuous monitoring service exited"))
Ok(())
Err(anyhow::anyhow!("proxy or continuous monitoring service exited"))
}
11 changes: 11 additions & 0 deletions dap-lib/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,14 @@ publish = false
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
rand = "0.8.5"
tokio = { version = "1.32.0", features = [
"net",
"rt-multi-thread",
"time",
"sync",
"macros",
] }
futures = { version = "0.3.28", default-features = false }
anyhow = "1.0.75"
tracing = "0.1.37"
5 changes: 5 additions & 0 deletions dap-lib/src/client/mod.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#[derive(PartialEq, Eq, Debug, Clone)]
pub enum DoHMethod {
Get,
Post,
}
46 changes: 46 additions & 0 deletions dap-lib/src/constants.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
////////////////////////////////
// Constant Values for Config //
////////////////////////////////
// Cannot override by config.toml
pub const UDP_BUFFER_SIZE: usize = 2048; // TODO: バッファサイズめちゃ適当
pub const UDP_CHANNEL_CAPACITY: usize = 1024; // TODO: channelキャパシティめちゃ適当
pub const MAX_CONNECTIONS: usize = 128; // TODO: 最大接続数(UDP+TCP)めちゃ適当
pub const TIMEOUT_SEC: u64 = 10;

// pub const CREDENTIAL_USERNAME_FIELD: &str = "username";
// pub const CREDENTIAL_API_KEY_FIELD: &str = "password";
// pub const CREDENTIAL_CLIENT_ID_FIELD: &str = "client_id";

pub const MIN_TTL: u32 = 10; // TTL for overridden records (plugin)

////////////////////////////////
// Default Values for Config //
////////////////////////////////
// Can override by specifying values in config.toml
pub const LISTEN_ADDRESSES: &[&str] = &["127.0.0.1:50053", "[::1]:50053"];

pub const BOOTSTRAP_DNS: &[&str] = &["1.1.1.1:53"];
pub const REBOOTSTRAP_PERIOD_MIN: u64 = 60;
pub const DOH_TARGET_URL: &[&str] = &["https://dns.google/dns-query"];

pub const MAX_CACHE_SIZE: usize = 16384;

///////////////////////////////
// Constant Values for Proxy //
///////////////////////////////
// Cannot override below by config.toml
pub const ODOH_CONFIG_PATH: &str = "/.well-known/odohconfigs"; // client
pub const ENDPOINT_LOGIN_PATH: &str = "/tokens"; // client::credential
pub const ENDPOINT_REFRESH_PATH: &str = "/refresh"; // client::credential
pub const ENDPOINT_JWKS_PATH: &str = "/jwks"; // client::credential

// pub const CREDENTIAL_REFRESH_BEFORE_EXPIRATION_IN_SECS: i64 = 600; // refresh 10 minutes before expiration // proxy
// pub const CREDENTIAL_REFRESH_MARGIN: i64 = 10; // at least 10 secs must be left to refresh // client::credential
// pub const CREDENTIAL_CHECK_PERIOD_SECS: u64 = 60; // proxy
// // every 60 secs, token is checked. then if the refresh condition is satisfied, refresh.
// // this is to rapidly recover from the hibernation of PC on which this is working. (at most 60 secs is needed for recovery)
// pub const ENDPOINT_RELOGIN_WAITING_SEC: u64 = 10; // proxy
// pub const MAX_LOGIN_ATTEMPTS: usize = 5; // proxy

pub const HEALTHCHECK_TARGET_FQDN: &str = "dns.google."; // client
pub const HEALTHCHECK_TARGET_ADDR: &str = "8.8.8.8"; // client
5 changes: 5 additions & 0 deletions dap-lib/src/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
pub use anyhow::{anyhow, bail, ensure, Context, Result};
// use std::io;
// use thiserror::Error;

// pub type Result<T> = std::result::Result<T, RpxyError>;
Loading

0 comments on commit 0e46b63

Please sign in to comment.