diff --git a/Cargo.lock b/Cargo.lock index c9496fc..f7c7817 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -76,7 +76,7 @@ dependencies = [ [[package]] name = "fourth" -version = "0.1.0" +version = "0.1.1" dependencies = [ "futures", "log", diff --git a/Cargo.toml b/Cargo.toml index 7203959..494433c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "fourth" -version = "0.1.0" -edition = "2018" +version = "0.1.1" +edition = "2021" authors = ["LI Rui "] license = "Apache-2.0" description = "Simple and fast layer 4 proxy in Rust" diff --git a/src/config.rs b/src/config.rs index 67d3cad..01f766c 100644 --- a/src/config.rs +++ b/src/config.rs @@ -54,9 +54,11 @@ fn load_config(path: &str) -> Result { } let log_level = parsed.log.clone().unwrap_or_else(|| "info".to_string()); - std::env::set_var("FOURTH_LOG", log_level.clone()); - pretty_env_logger::init_custom_env("FOURTH_LOG"); - debug!("Set log level to {}", log_level); + if !log_level.eq("disable") { + std::env::set_var("FOURTH_LOG", log_level.clone()); + pretty_env_logger::init_custom_env("FOURTH_LOG"); + debug!("Set log level to {}", log_level); + } debug!("Config version {}", parsed.version); @@ -74,3 +76,17 @@ impl From for ConfigError { ConfigError::Yaml(err) } } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_load_config() { + let config = Config::new("tests/config.yaml").unwrap(); + assert_eq!(config.base.version, 1); + assert_eq!(config.base.log.unwrap(), "disable"); + assert_eq!(config.base.servers.len(), 2); + assert_eq!(config.base.upstream.len(), 2); + } +} diff --git a/src/servers/mod.rs b/src/servers/mod.rs index c042a4c..3f83ec4 100644 --- a/src/servers/mod.rs +++ b/src/servers/mod.rs @@ -206,3 +206,30 @@ where Err(_) => Ok(0), } } + +#[cfg(test)] +mod test { + use std::thread::{self, sleep}; + use std::time::Duration; + + use super::*; + + #[tokio::test] + async fn test_echo_server() { + use crate::config::Config; + let config = Config::new("tests/config.yaml").unwrap(); + let mut server = Server::new(config.base); + thread::spawn(move || { + let _ = server.run(); + }); + sleep(Duration::from_secs(1)); // wait for server to start + let mut conn = TcpStream::connect("127.0.0.1:54956").await.unwrap(); + let mut buf = [0u8; 1]; + for i in 0..=255u8 { + conn.write(&[i]).await.unwrap(); + conn.read(&mut buf).await.unwrap(); + assert_eq!(&buf, &[i]); + } + conn.shutdown().await.unwrap(); + } +} diff --git a/src/servers/tls.rs b/src/servers/tls.rs index 9bf87a4..398c36a 100644 --- a/src/servers/tls.rs +++ b/src/servers/tls.rs @@ -51,3 +51,53 @@ pub fn get_sni(buf: &[u8]) -> Vec { snis } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn test_sni_extract() { + const BUF: [u8; 517] = [ + 0x16, 0x03, 0x01, 0x02, 0x00, 0x01, 0x00, 0x01, 0xfc, 0x03, 0x03, 0x35, 0x7a, 0xba, + 0x3d, 0x89, 0xd2, 0x5e, 0x7a, 0xa2, 0xd4, 0xe5, 0x6d, 0xd5, 0xa3, 0x98, 0x41, 0xb0, + 0xae, 0x41, 0xfc, 0xe6, 0x64, 0xfd, 0xae, 0x0b, 0x27, 0x6d, 0x90, 0xa8, 0x0a, 0xfa, + 0x90, 0x20, 0x59, 0x6f, 0x13, 0x18, 0x4a, 0xd1, 0x1c, 0xc4, 0x83, 0x8c, 0xfc, 0x93, + 0xac, 0x6b, 0x3b, 0xac, 0x67, 0xd0, 0x36, 0xb0, 0xa2, 0x1b, 0x04, 0xf7, 0xde, 0x02, + 0xfb, 0x96, 0x1e, 0xdc, 0x76, 0xa8, 0x00, 0x20, 0x2a, 0x2a, 0x13, 0x01, 0x13, 0x02, + 0x13, 0x03, 0xc0, 0x2b, 0xc0, 0x2f, 0xc0, 0x2c, 0xc0, 0x30, 0xcc, 0xa9, 0xcc, 0xa8, + 0xc0, 0x13, 0xc0, 0x14, 0x00, 0x9c, 0x00, 0x9d, 0x00, 0x2f, 0x00, 0x35, 0x01, 0x00, + 0x01, 0x93, 0xea, 0xea, 0x00, 0x00, 0x00, 0x00, 0x00, 0x13, 0x00, 0x11, 0x00, 0x00, + 0x0e, 0x77, 0x77, 0x77, 0x2e, 0x6c, 0x69, 0x72, 0x75, 0x69, 0x2e, 0x74, 0x65, 0x63, + 0x68, 0x00, 0x17, 0x00, 0x00, 0xff, 0x01, 0x00, 0x01, 0x00, 0x00, 0x0a, 0x00, 0x0a, + 0x00, 0x08, 0xba, 0xba, 0x00, 0x1d, 0x00, 0x17, 0x00, 0x18, 0x00, 0x0b, 0x00, 0x02, + 0x01, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x10, 0x00, 0x0e, 0x00, 0x0c, 0x02, 0x68, + 0x32, 0x08, 0x68, 0x74, 0x74, 0x70, 0x2f, 0x31, 0x2e, 0x31, 0x00, 0x05, 0x00, 0x05, + 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x12, 0x00, 0x10, 0x04, 0x03, 0x08, + 0x04, 0x04, 0x01, 0x05, 0x03, 0x08, 0x05, 0x05, 0x01, 0x08, 0x06, 0x06, 0x01, 0x00, + 0x12, 0x00, 0x00, 0x00, 0x33, 0x00, 0x2b, 0x00, 0x29, 0xba, 0xba, 0x00, 0x01, 0x00, + 0x00, 0x1d, 0x00, 0x20, 0x3b, 0x45, 0xf9, 0xbc, 0x6e, 0x23, 0x86, 0x41, 0xa5, 0xb2, + 0xf5, 0x03, 0xec, 0x67, 0x4a, 0xd7, 0x9a, 0x17, 0x9f, 0x0c, 0x38, 0x6d, 0x36, 0xf3, + 0x4e, 0x5d, 0xa4, 0x7d, 0x15, 0x79, 0xa4, 0x3f, 0x00, 0x2d, 0x00, 0x02, 0x01, 0x01, + 0x00, 0x2b, 0x00, 0x0b, 0x0a, 0xba, 0xba, 0x03, 0x04, 0x03, 0x03, 0x03, 0x02, 0x03, + 0x01, 0x00, 0x1b, 0x00, 0x03, 0x02, 0x00, 0x02, 0x44, 0x69, 0x00, 0x05, 0x00, 0x03, + 0x02, 0x68, 0x32, 0xda, 0xda, 0x00, 0x01, 0x00, 0x00, 0x15, 0x00, 0xc5, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + ]; + let sni = get_sni(&BUF); + assert!(sni[0] == "www.lirui.tech".to_string()); + } +} diff --git a/tests/config.yaml b/tests/config.yaml new file mode 100644 index 0000000..08709a6 --- /dev/null +++ b/tests/config.yaml @@ -0,0 +1,21 @@ +version: 1 +log: disable + +servers: + test_server: + listen: + - "0.0.0.0:21341" + - "[::]:21341" + tls: true + sni: + proxy.test.com: proxy + www.test.com: web + default: ban + echo_server: + listen: + - "0.0.0.0:54956" + default: echo + +upstream: + web: "127.0.0.1:8080" + proxy: "www.example.com:1024" \ No newline at end of file