diff --git a/Cargo.lock b/Cargo.lock index 3b2d6a9..095c479 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -59,9 +59,9 @@ dependencies = [ [[package]] name = "autocfg" -version = "1.0.1" +version = "1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" +checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" [[package]] name = "base64" @@ -142,6 +142,7 @@ dependencies = [ "tracing", "tracing-futures", "tracing-subscriber", + "trust-dns-resolver", "uuid", "wildmatch", ] @@ -181,6 +182,7 @@ dependencies = [ "tracing", "tracing-futures", "tracing-subscriber", + "trust-dns-resolver", "uuid", "wildmatch", ] @@ -216,6 +218,7 @@ dependencies = [ "tracing", "tracing-futures", "tracing-subscriber", + "trust-dns-resolver", "uuid", "wildmatch", ] @@ -247,6 +250,12 @@ dependencies = [ "vec_map", ] +[[package]] +name = "data-encoding" +version = "2.3.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ee2393c4a91429dffb4bedf19f4d6abf27d8a732c8ce4980305d782e5426d57" + [[package]] name = "default-net" version = "0.2.0" @@ -263,6 +272,18 @@ version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "56899898ce76aaf4a0f24d914c97ea6ed976d42fec6ad33fcbb0a1103e07b2b0" +[[package]] +name = "enum-as-inner" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "21cdad81446a7f7dc43f6a77409efeb9733d2fa65553efef6018ef257c959b73" +dependencies = [ + "heck 0.4.0", + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "fnv" version = "1.0.7" @@ -430,6 +451,12 @@ dependencies = [ "unicode-segmentation", ] +[[package]] +name = "heck" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2540771e65fc8cb83cd6e8a237f70c319bd5c29f78ed1084ba5d50eeac86f7f9" + [[package]] name = "hermit-abi" version = "0.1.19" @@ -439,6 +466,17 @@ dependencies = [ "libc", ] +[[package]] +name = "hostname" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3c731c3e10504cc8ed35cfe2f1db4c9274c3d35fa486e3b31df46f068ef3e867" +dependencies = [ + "libc", + "match_cfg", + "winapi 0.3.9", +] + [[package]] name = "http" version = "0.2.4" @@ -536,6 +574,17 @@ dependencies = [ "want", ] +[[package]] +name = "idna" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "418a0a6fab821475f634efe3ccc45c013f742efe03d853e8d3355d5cb850ecf8" +dependencies = [ + "matches", + "unicode-bidi", + "unicode-normalization", +] + [[package]] name = "indexmap" version = "1.7.0" @@ -555,6 +604,24 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "ipconfig" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "723519edce41262b05d4143ceb95050e4c614f483e78e9fd9e39a8275a84ad98" +dependencies = [ + "socket2 0.4.1", + "widestring", + "winapi 0.3.9", + "winreg", +] + +[[package]] +name = "ipnet" +version = "2.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "879d54834c8c76457ef4293a689b2a8c59b076067ad77b15efafbb05f92a592b" + [[package]] name = "ipnetwork" version = "0.16.0" @@ -628,9 +695,9 @@ checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" [[package]] name = "libc" -version = "0.2.100" +version = "0.2.125" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a1fa8cddc8fbbee11227ef194b5317ed014b8acbf15139bd716a18ad3fe99ec5" +checksum = "5916d2ae698f6de9bfb891ad7a8d65c09d232dc58cc4ac433c7da3b2fd84bc2b" [[package]] name = "linked-hash-map" @@ -640,10 +707,11 @@ checksum = "7fb9b38af92608140b86b693604b9ffcc5824240a484d1ecd4795bacb2fe88f3" [[package]] name = "lock_api" -version = "0.4.4" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0382880606dff6d15c9476c416d18690b72742aa7b605bb6dd6ec9030fbf07eb" +checksum = "327fa5b6a6940e4699ec49a9beae1ea4845c6bab9314e4f84ac68742139d8c53" dependencies = [ + "autocfg", "scopeguard", ] @@ -665,6 +733,21 @@ dependencies = [ "cfg-if", ] +[[package]] +name = "lru-cache" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "31e24f1ad8321ca0e8a1e0ac13f23cb668e6f5466c2c57319f6a5cf1cc8e3b1c" +dependencies = [ + "linked-hash-map", +] + +[[package]] +name = "match_cfg" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffbee8634e0d45d258acb448e7eaab3fce7a0a467395d4d9f228e3c1f01fb2e4" + [[package]] name = "matchers" version = "0.0.1" @@ -782,7 +865,17 @@ checksum = "6d7744ac029df22dca6284efe4e898991d28e3085c706c972bcd7da4a27a15eb" dependencies = [ "instant", "lock_api", - "parking_lot_core", + "parking_lot_core 0.8.3", +] + +[[package]] +name = "parking_lot" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87f5ec2493a61ac0506c0f4199f99070cbe83857b0337006a30f3e6719b8ef58" +dependencies = [ + "lock_api", + "parking_lot_core 0.9.3", ] [[package]] @@ -799,6 +892,19 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "parking_lot_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09a279cbf25cb0757810394fbc1e359949b59e348145c643a939a525692e6929" +dependencies = [ + "cfg-if", + "libc", + "redox_syscall", + "smallvec", + "windows-sys", +] + [[package]] name = "paw" version = "1.0.0" @@ -1180,6 +1286,12 @@ dependencies = [ "unicode-xid 0.2.2", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quote" version = "1.0.9" @@ -1273,6 +1385,16 @@ dependencies = [ "winapi 0.3.9", ] +[[package]] +name = "resolv-conf" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00" +dependencies = [ + "hostname", + "quick-error", +] + [[package]] name = "rustc-serialize" version = "0.3.24" @@ -1421,7 +1543,7 @@ version = "0.4.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7813934aecf5f51a54775e00068c237de98489463968231a51746bbbc03f9c10" dependencies = [ - "heck", + "heck 0.3.3", "proc-macro-error", "proc-macro2", "quote", @@ -1566,6 +1688,7 @@ dependencies = [ "tracing", "tracing-futures", "tracing-subscriber", + "trust-dns-resolver", "uuid", "wildmatch", ] @@ -1579,6 +1702,26 @@ dependencies = [ "unicode-width", ] +[[package]] +name = "thiserror" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bd829fe32373d27f76265620b5309d0340cb8550f523c1dda251d6298069069a" +dependencies = [ + "thiserror-impl", +] + +[[package]] +name = "thiserror-impl" +version = "1.0.31" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0396bc89e626244658bef819e22d0cc459e795a5ebe878e6ec336d1674a8d79a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "thread_local" version = "1.1.3" @@ -1588,6 +1731,21 @@ dependencies = [ "once_cell", ] +[[package]] +name = "tinyvec" +version = "1.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" +dependencies = [ + "tinyvec_macros", +] + +[[package]] +name = "tinyvec_macros" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" + [[package]] name = "tokio" version = "1.10.0" @@ -1601,7 +1759,7 @@ dependencies = [ "mio", "num_cpus", "once_cell", - "parking_lot", + "parking_lot 0.11.1", "pin-project-lite", "signal-hook-registry", "tokio-macros", @@ -1733,12 +1891,72 @@ dependencies = [ "serde_json", ] +[[package]] +name = "trust-dns-proto" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9c31f240f59877c3d4bb3b3ea0ec5a6a0cff07323580ff8c7a605cd7d08b255d" +dependencies = [ + "async-trait", + "cfg-if", + "data-encoding", + "enum-as-inner", + "futures-channel", + "futures-io", + "futures-util", + "idna", + "ipnet", + "lazy_static", + "log 0.4.14", + "rand", + "smallvec", + "thiserror", + "tinyvec", + "tokio", + "url", +] + +[[package]] +name = "trust-dns-resolver" +version = "0.21.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e4ba72c2ea84515690c9fcef4c6c660bb9df3036ed1051686de84605b74fd558" +dependencies = [ + "cfg-if", + "futures-util", + "ipconfig", + "lazy_static", + "log 0.4.14", + "lru-cache", + "parking_lot 0.12.0", + "resolv-conf", + "smallvec", + "thiserror", + "tokio", + "trust-dns-proto", +] + [[package]] name = "try-lock" version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "59547bce71d9c38b83d9c0e92b6066c4253371f15005def0c30d9657f50c7642" +[[package]] +name = "unicode-bidi" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "099b7128301d285f79ddd55b9a83d5e6b9e97c92e0ea0daebee7263e932de992" + +[[package]] +name = "unicode-normalization" +version = "0.1.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d54590932941a9e9266f0832deed84ebe1bf2e4c9e4a3554d393d18f5e854bf9" +dependencies = [ + "tinyvec", +] + [[package]] name = "unicode-segmentation" version = "1.8.0" @@ -1763,6 +1981,18 @@ version = "0.2.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3" +[[package]] +name = "url" +version = "2.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a507c383b2d33b5fc35d1861e77e6b383d158b2da5e14fe51b83dfedf6fd578c" +dependencies = [ + "form_urlencoded", + "idna", + "matches", + "percent-encoding", +] + [[package]] name = "uuid" version = "0.8.2" @@ -1801,6 +2031,12 @@ version = "0.10.2+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fd6fbd9a79829dd1ad0cc20627bf1ed606756a7f77edff7b66b7064f9cb327c6" +[[package]] +name = "widestring" +version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "17882f045410753661207383517a6f62ec3dbeb6a4ed2acce01f0728238d1983" + [[package]] name = "wildmatch" version = "2.1.0" @@ -1841,6 +2077,58 @@ version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" +[[package]] +name = "windows-sys" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ea04155a16a59f9eab786fe12a4a450e75cdb175f9e0d80da1e17db09f55b8d2" +dependencies = [ + "windows_aarch64_msvc", + "windows_i686_gnu", + "windows_i686_msvc", + "windows_x86_64_gnu", + "windows_x86_64_msvc", +] + +[[package]] +name = "windows_aarch64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9bb8c3fd39ade2d67e9874ac4f3db21f0d710bee00fe7cab16949ec184eeaa47" + +[[package]] +name = "windows_i686_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "180e6ccf01daf4c426b846dfc66db1fc518f074baa793aa7d9b9aaeffad6a3b6" + +[[package]] +name = "windows_i686_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e2e7917148b2812d1eeafaeb22a97e4813dfa60a3f8f78ebe204bcc88f12f024" + +[[package]] +name = "windows_x86_64_gnu" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4dcd171b8776c41b97521e5da127a2d86ad280114807d0b2ab1e462bc764d9e1" + +[[package]] +name = "windows_x86_64_msvc" +version = "0.36.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c811ca4a8c853ef420abd8592ba53ddbbac90410fab6903b3e79972a631f7680" + +[[package]] +name = "winreg" +version = "0.7.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0120db82e8a1e0b9fb3345a539c478767c0048d842860994d96113d5b667bd69" +dependencies = [ + "winapi 0.3.9", +] + [[package]] name = "ws2_32-sys" version = "0.2.1" diff --git a/Cargo.toml b/Cargo.toml index 5ca4fc4..32023ee 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,7 @@ bincode = "1.3.3" default-net = "0.2.0" system_gateway = {git="https://github.com/aruntomar/system_gateway"} base64 = "0.13.0" +trust-dns-resolver = "0.21.2" [dev-dependencies] test-case = "1.2" diff --git a/chaos-tproxy-controller/Cargo.toml b/chaos-tproxy-controller/Cargo.toml index c0fdfd1..efa442e 100644 --- a/chaos-tproxy-controller/Cargo.toml +++ b/chaos-tproxy-controller/Cargo.toml @@ -44,4 +44,5 @@ futures-util = { version = "0.3.7", default-features = false, features = ["alloc chaos-tproxy-proxy = {path = "../chaos-tproxy-proxy"} pnet = "0.28.0" default-net = "0.2.0" -system_gateway = {git="https://github.com/aruntomar/system_gateway"} \ No newline at end of file +system_gateway = {git="https://github.com/aruntomar/system_gateway"} +trust-dns-resolver = "0.21.2" \ No newline at end of file diff --git a/chaos-tproxy-controller/src/proxy/config.rs b/chaos-tproxy-controller/src/proxy/config.rs index 2c75781..3c29797 100644 --- a/chaos-tproxy-controller/src/proxy/config.rs +++ b/chaos-tproxy-controller/src/proxy/config.rs @@ -1,7 +1,11 @@ use std::convert::TryFrom; +use std::net::{IpAddr, Ipv4Addr}; +use std::sync::mpsc::channel; -use anyhow::{anyhow, Error}; +use anyhow::{anyhow, Error, Result}; use chaos_tproxy_proxy::raw_config::RawConfig as ProxyRawConfig; +use trust_dns_resolver::system_conf::read_system_conf; +use trust_dns_resolver::Resolver; use crate::raw_config::RawConfig; @@ -22,6 +26,37 @@ impl TryFrom for Config { .collect::>() .join(",") }), + proxy_ips: raw.proxy_domains.map(|domains| { + let ips: Vec = domains + .into_iter() + .map(|domain| { + let (config, opt) = read_system_conf()?; + let resolver = Resolver::new(config, opt)?; + + let (sender, receiver) = channel(); + let _ = std::thread::spawn(move || { + let _ = sender.send(resolver.lookup_ip(domain)); + }) + .join(); + + let rsp = receiver.recv()??; + let ips: Vec = rsp + .iter() + .filter_map(|ip| match ip { + IpAddr::V4(ipv4) => Some(ipv4), + IpAddr::V6(_) => None, + }) + .collect(); + Ok(ips) + }) + .filter_map(|r: Result>| { + r.map_err(|e| tracing::error!("resolve domain with error: {}", e)) + .ok() + }) + .flatten() + .collect(); + ips + }), safe_mode: match &raw.safe_mode { Some(b) => *b, None => false, @@ -54,73 +89,3 @@ pub(crate) fn get_free_port(ports: Option>) -> anyhow::Result { "never apply all ports in 1025-65535 to be proxy ports" )) } - -#[cfg(test)] -mod tests { - use std::convert::TryInto; - - use chaos_tproxy_proxy::raw_config::RawConfig as ProxyRawConfig; - - use crate::proxy::config::{get_free_port, Config}; - use crate::raw_config::RawConfig; - - #[test] - fn test_get_free_port() { - assert!(get_free_port(Some((u16::MIN..u16::MAX).collect())).is_err()); - } - - #[test] - fn test_try_into() { - let config: Config = RawConfig { - proxy_ports: None, - safe_mode: None, - interface: None, - rules: None, - - listen_port: None, - proxy_mark: None, - ignore_mark: None, - route_table: None, - } - .try_into() - .unwrap(); - assert_eq!( - config, - Config { - proxy_config: ProxyRawConfig { - proxy_ports: None, - listen_port: get_free_port(None).unwrap(), - safe_mode: false, - interface: None, - rules: vec![] - } - } - ); - - let config: Config = RawConfig { - proxy_ports: Some(vec![1025u16, 1026u16]), - safe_mode: Some(true), - interface: Some("ens33".parse().unwrap()), - rules: None, - - listen_port: None, - proxy_mark: None, - ignore_mark: None, - route_table: None, - } - .try_into() - .unwrap(); - assert_eq!( - config, - Config { - proxy_config: ProxyRawConfig { - proxy_ports: Some("1025,1026".parse().unwrap()), - listen_port: 1027u16, - safe_mode: true, - interface: Some("ens33".parse().unwrap()), - rules: vec![] - } - } - ); - } -} diff --git a/chaos-tproxy-controller/src/raw_config.rs b/chaos-tproxy-controller/src/raw_config.rs index 5105f40..49a8ecd 100644 --- a/chaos-tproxy-controller/src/raw_config.rs +++ b/chaos-tproxy-controller/src/raw_config.rs @@ -5,6 +5,7 @@ use serde::{Deserialize, Serialize}; #[serde(deny_unknown_fields)] // To prevent typos. pub struct RawConfig { pub proxy_ports: Option>, + pub proxy_domains: Option>, pub safe_mode: Option, pub interface: Option, pub rules: Option>, diff --git a/chaos-tproxy-proxy/Cargo.toml b/chaos-tproxy-proxy/Cargo.toml index e2bbbdb..985619d 100644 --- a/chaos-tproxy-proxy/Cargo.toml +++ b/chaos-tproxy-proxy/Cargo.toml @@ -35,3 +35,5 @@ bincode = "1.3.3" tempfile = "3.2.0" uuid = { version = "0.8", features = ["serde", "v4"] } base64 = "0.13.0" +trust-dns-resolver = "0.21.2" + diff --git a/chaos-tproxy-proxy/src/raw_config.rs b/chaos-tproxy-proxy/src/raw_config.rs index bc2e1c6..3ff880a 100644 --- a/chaos-tproxy-proxy/src/raw_config.rs +++ b/chaos-tproxy-proxy/src/raw_config.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; use std::convert::{TryFrom, TryInto}; +use std::net::Ipv4Addr; use std::time::Duration; use anyhow::{anyhow, Error}; @@ -19,6 +20,7 @@ use crate::proxy::http::config::Config; #[derive(Debug, Eq, PartialEq, Clone, Deserialize, Serialize, Default)] pub struct RawConfig { pub proxy_ports: Option, + pub proxy_ips: Option>, pub listen_port: u16, pub safe_mode: bool, pub interface: Option, diff --git a/tests/Cargo.toml b/tests/Cargo.toml index 21e2d74..624c250 100644 --- a/tests/Cargo.toml +++ b/tests/Cargo.toml @@ -42,3 +42,4 @@ chaos-tproxy-controller = {path = "../chaos-tproxy-controller"} pnet = "0.28.0" default-net = "0.2.0" system_gateway = {git="https://github.com/aruntomar/system_gateway"} +trust-dns-resolver = "0.21.2" \ No newline at end of file diff --git a/tests/integrations/test_http_action.rs b/tests/integrations/test_http_action.rs index 2fb44b6..dc1d6b8 100644 --- a/tests/integrations/test_http_action.rs +++ b/tests/integrations/test_http_action.rs @@ -1,7 +1,7 @@ +use chaos_tproxy_proxy::handler::http::action::{apply_request_action, Actions, ReplaceAction}; use http::header::CONTENT_LENGTH; use http::HeaderMap; use hyper::{Body, Client, Method, Request}; -use chaos_tproxy_proxy::handler::http::action::{apply_request_action, Actions, ReplaceAction}; #[tokio::test] #[ignore]