diff --git a/Cargo.lock b/Cargo.lock deleted file mode 100644 index f8ba4d9..0000000 --- a/Cargo.lock +++ /dev/null @@ -1,410 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -[[package]] -name = "ansi_term" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b" -dependencies = [ - "winapi", -] - -[[package]] -name = "arrayref" -version = "0.3.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4c527152e37cf757a3f78aae5a06fbeefdb07ccc535c980a3208ee3060dd544" - -[[package]] -name = "arrayvec" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cff77d8686867eceff3105329d4698d96c2391c176d5d03adc90c7389162b5b8" - -[[package]] -name = "atty" -version = "0.2.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d9b39be18770d11421cdb1b9947a45dd3f37e93092cbf377614828a319d5fee8" -dependencies = [ - "hermit-abi", - "libc", - "winapi", -] - -[[package]] -name = "autocfg" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cdb031dd78e28731d87d56cc8ffef4a8f36ca26c38fe2de700543e627f8a464a" - -[[package]] -name = "base64" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3441f0f7b02788e948e47f457ca01f1d7e6d92c693bc132c22b087d3141c03ff" - -[[package]] -name = "bitflags" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693" - -[[package]] -name = "blake2b_simd" -version = "0.5.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d8fb2d74254a3a0b5cac33ac9f8ed0e44aa50378d9dbb2e5d83bd21ed1dc2c8a" -dependencies = [ - "arrayref", - "arrayvec", - "constant_time_eq", -] - -[[package]] -name = "byteorder" -version = "1.3.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08c48aae112d48ed9f069b33538ea9e3e90aa263cfa3d1c24309612b1f7472de" - -[[package]] -name = "cfg-if" -version = "0.1.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" - -[[package]] -name = "clap" -version = "2.33.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37e58ac78573c40708d45522f0d80fa2f01cc4f9b4e2bf749807255454312002" -dependencies = [ - "ansi_term", - "atty", - "bitflags", - "strsim", - "textwrap", - "unicode-width", - "vec_map", -] - -[[package]] -name = "constant_time_eq" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" - -[[package]] -name = "crossbeam-utils" -version = "0.7.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3c7c73a2d1e9fc0886a08b93e98eb643461230d5f1925e4036204d5f2e261a8" -dependencies = [ - "autocfg", - "cfg-if", - "lazy_static", -] - -[[package]] -name = "dirs" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fd78930633bd1c6e35c4b42b1df7b0cbc6bc191146e512bb3bedf243fcc3901" -dependencies = [ - "libc", - "redox_users", - "winapi", -] - -[[package]] -name = "fuchsia-cprng" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06f77d526c1a601b7c4cdd98f54b5eaabffc14d5f2f0296febdc7f357c6d3ba" - -[[package]] -name = "getrandom" -version = "0.1.14" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abc8dd8451921606d809ba32e95b6111925cd2906060d2dcc29c070220503eb" -dependencies = [ - "cfg-if", - "libc", - "wasi", -] - -[[package]] -name = "hermit-abi" -version = "0.1.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3deed196b6e7f9e44a2ae8d94225d80302d81208b1bb673fd21fe634645c85a9" -dependencies = [ - "libc", -] - -[[package]] -name = "itoa" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc6f3ad7b9d11a0c00842ff8de1b60ee58661048eb8049ed33c73594f359d7e6" - -[[package]] -name = "lazy_static" -version = "1.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" - -[[package]] -name = "libc" -version = "0.2.76" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "755456fae044e6fa1ebbbd1b3e902ae19e73097ed4ed87bb79934a867c007bc3" - -[[package]] -name = "proc-macro2" -version = "1.0.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "175c513d55719db99da20232b06cda8bab6b83ec2d04e3283edf0213c37c1a29" -dependencies = [ - "unicode-xid", -] - -[[package]] -name = "quote" -version = "1.0.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa563d17ecb180e500da1cfd2b028310ac758de548efdd203e18f283af693f37" -dependencies = [ - "proc-macro2", -] - -[[package]] -name = "rand" -version = "0.3.23" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ac302d8f83c0c1974bf758f6b041c6c8ada916fbb44a609158ca8b064cc76c" -dependencies = [ - "libc", - "rand 0.4.6", -] - -[[package]] -name = "rand" -version = "0.4.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "552840b97013b1a26992c11eac34bdd778e464601a4c2054b5f0bff7c6761293" -dependencies = [ - "fuchsia-cprng", - "libc", - "rand_core 0.3.1", - "rdrand", - "winapi", -] - -[[package]] -name = "rand_core" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a6fdeb83b075e8266dcc8762c22776f6877a63111121f5f8c7411e5be7eed4b" -dependencies = [ - "rand_core 0.4.2", -] - -[[package]] -name = "rand_core" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c33a3c44ca05fa6f1807d8e6743f3824e8509beca625669633be0acbdf509dc" - -[[package]] -name = "rdrand" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "678054eb77286b51581ba43620cc911abf02758c91f93f479767aed0f90458b2" -dependencies = [ - "rand_core 0.3.1", -] - -[[package]] -name = "redox_syscall" -version = "0.1.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41cc0f7e4d5d4544e8861606a285bb08d3e70712ccc7d2b84d7c0ccfaf4b05ce" - -[[package]] -name = "redox_users" -version = "0.3.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0737333e7a9502c789a36d7c7fa6092a49895d4faa31ca5df163857ded2e9d" -dependencies = [ - "getrandom", - "redox_syscall", - "rust-argon2", -] - -[[package]] -name = "rust-argon2" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9dab61250775933275e84053ac235621dfb739556d5c54a2f2e9313b7cf43a19" -dependencies = [ - "base64", - "blake2b_simd", - "constant_time_eq", - "crossbeam-utils", -] - -[[package]] -name = "rust_util" -version = "0.6.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d72591d92aa26f51aa81812b9bc15cc6e82d8f1e99d5bf14c72a0c9ef204adc9" -dependencies = [ - "lazy_static", - "libc", - "serde", - "serde_json", - "term", - "term_size", -] - -[[package]] -name = "ryu" -version = "1.0.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "71d301d4193d031abdd79ff7e3dd721168a9572ef3fe51a1517aba235bd8f86e" - -[[package]] -name = "serde" -version = "1.0.115" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e54c9a88f2da7238af84b5101443f0c0d0a3bbdc455e34a5c9497b1903ed55d5" -dependencies = [ - "serde_derive", -] - -[[package]] -name = "serde_derive" -version = "1.0.115" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "609feed1d0a73cc36a0182a840a9b37b4a82f0b1150369f0536a9e3f2a31dc48" -dependencies = [ - "proc-macro2", - "quote", - "syn", -] - -[[package]] -name = "serde_json" -version = "1.0.57" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "164eacbdb13512ec2745fb09d51fd5b22b0d65ed294a1dcf7285a360c80a675c" -dependencies = [ - "itoa", - "ryu", - "serde", -] - -[[package]] -name = "simple-rust-udp-proxy" -version = "0.1.0" -dependencies = [ - "clap", - "rand 0.3.23", - "rust_util", - "serde", - "serde_json", -] - -[[package]] -name = "strsim" -version = "0.8.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ea5119cdb4c55b55d432abb513a0429384878c15dde60cc77b1c99de1a95a6a" - -[[package]] -name = "syn" -version = "1.0.40" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "963f7d3cc59b59b9325165add223142bbf1df27655d07789f109896d353d8350" -dependencies = [ - "proc-macro2", - "quote", - "unicode-xid", -] - -[[package]] -name = "term" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edd106a334b7657c10b7c540a0106114feadeb4dc314513e97df481d5d966f42" -dependencies = [ - "byteorder", - "dirs", - "winapi", -] - -[[package]] -name = "term_size" -version = "0.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e4129646ca0ed8f45d09b929036bafad5377103edd06e50bf574b353d2b08d9" -dependencies = [ - "libc", - "winapi", -] - -[[package]] -name = "textwrap" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d326610f408c7a4eb6f51c37c330e496b08506c9457c9d34287ecc38809fb060" -dependencies = [ - "unicode-width", -] - -[[package]] -name = "unicode-width" -version = "0.1.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9337591893a19b88d8d87f2cec1e73fad5cdfd10e5a6f349f498ad6ea2ffb1e3" - -[[package]] -name = "unicode-xid" -version = "0.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7fe0bb3479651439c9112f72b6c505038574c9fbb575ed1bf3b797fa39dd564" - -[[package]] -name = "vec_map" -version = "0.8.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bddf1187be692e79c5ffeab891132dfb0f236ed36a43c7ed39f1165ee20191" - -[[package]] -name = "wasi" -version = "0.9.0+wasi-snapshot-preview1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cccddf32554fecc6acb585f82a32a72e28b48f8c4c1883ddfeeeaa96f7d8e519" - -[[package]] -name = "winapi" -version = "0.3.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" -dependencies = [ - "winapi-i686-pc-windows-gnu", - "winapi-x86_64-pc-windows-gnu", -] - -[[package]] -name = "winapi-i686-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" - -[[package]] -name = "winapi-x86_64-pc-windows-gnu" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" diff --git a/src/main.rs b/src/main.rs index 9eb0da7..33afc76 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,7 +13,10 @@ use std::sync::mpsc::channel; use std::thread; use std::time::Duration; use clap::{ Arg, App }; +use rust_util::util_msg::{ is_logger_level_enabled, MessageType }; +use rust_util::util_net::IpAddressMaskGroup; +const LOCAL_ADDR: &str = "127.0.0.1"; const TIMEOUT: u64 = 3 * 60 * 100; //3 minutes fn main() { @@ -33,34 +36,48 @@ fn main() { .arg(Arg::with_name("allowed_list").short("A").long("allowed-list").takes_value(true).multiple(true).help("Allowed IP list, e.g. 127.0.0.1, 120.0.0.0/8")) .get_matches(); - let local_port: i32 = matches.value_of("local_port").unwrap().parse().unwrap(); - let remote_port: i32 = matches.value_of("remote_port").unwrap().parse().unwrap(); + let local_port: u16 = matches.value_of("local_port").unwrap().parse().unwrap(); + let remote_port: u16 = matches.value_of("remote_port").unwrap().parse().unwrap(); let remote_host = matches.value_of("host").unwrap(); let bind_addr = match matches.value_of("bind") { Some(addr) => addr.to_owned(), - None => "127.0.0.1".to_owned(), + None => LOCAL_ADDR.to_owned(), }; + let allowed_ip_address_mask_list = IpAddressMaskGroup::parse( + &matches.values_of("allowed_list") + .map(|l| l.map(|i| i.to_owned()).collect::>()) + .unwrap_or_else(|| vec![]) + ); + debugging!("Allowed ip address mask list count: {}", allowed_ip_address_mask_list.ip_address_mask_group.len()); + if is_logger_level_enabled(MessageType::DEBUG) { + allowed_ip_address_mask_list.ip_address_mask_group.iter().for_each(|ip| { + debugging!("- {}", ip); + }); + } - forward(&bind_addr, local_port, &remote_host, remote_port); + forward(&bind_addr, local_port, &remote_host, remote_port, &allowed_ip_address_mask_list); } -fn forward(bind_addr: &str, local_port: i32, remote_host: &str, remote_port: i32) { +fn forward(bind_addr: &str, local_port: u16, remote_host: &str, remote_port: u16, allowed_ip_address_mask_list: &IpAddressMaskGroup) { let local_addr = format!("{}:{}", bind_addr, local_port); + debugging!("Listen address and port: {}", local_addr); let local = UdpSocket::bind(&local_addr).unwrap_or_else(|_| panic!("Unable to bind to {}", &local_addr)); information!("Listening on {}", local.local_addr().unwrap()); let remote_addr = format!("{}:{}", remote_host, remote_port); - let responder = local.try_clone() - .unwrap_or_else(|_| panic!("Failed to clone primary listening address socket {}", local.local_addr().unwrap())); + let responder = local.try_clone().unwrap_or_else( + |_| panic!("Failed to clone primary listening address socket {}", local.local_addr().unwrap()) + ); let (main_sender, main_receiver) = channel::<(_, Vec)>(); thread::spawn(move || { debugging!("Started new thread to deal out responses to clients"); loop { let (dest, buf) = main_receiver.recv().unwrap(); let to_send = buf.as_slice(); - responder.send_to(to_send, dest) - .unwrap_or_else(|_| panic!("Failed to forward response from upstream server to client {}", dest)); + responder.send_to(to_send, dest).unwrap_or_else( + |_| panic!("Failed to forward response from upstream server to client {}", dest) + ); } }); @@ -68,7 +85,10 @@ fn forward(bind_addr: &str, local_port: i32, remote_host: &str, remote_port: i32 let mut buf = [0; 64 * 1024]; loop { let (num_bytes, src_addr) = local.recv_from(&mut buf).expect("Didn't receive data"); - // TODO check src_addr ... + if !allowed_ip_address_mask_list.is_empty_or_matches(&src_addr) { + information!("Banned source address: {}", src_addr); + continue; + } //we create a new thread for each unique client let mut remove_existing = false; @@ -79,7 +99,7 @@ fn forward(bind_addr: &str, local_port: i32, remote_host: &str, remote_port: i32 let client_id = format!("{}", src_addr); if remove_existing { - debugging!("Removing existing forwarder from map."); + debugging!("Removing existing forwarder from map: {}", client_id); client_map.remove(&client_id); } @@ -96,12 +116,14 @@ fn forward(bind_addr: &str, local_port: i32, remote_host: &str, remote_port: i32 //connection to 0.0.0.0 in all cases. let temp_outgoing_addr = format!("0.0.0.0:{}", 1024 + rand::random::()); debugging!("Establishing new forwarder for client {} on {}", src_addr, &temp_outgoing_addr); - let upstream_send = UdpSocket::bind(&temp_outgoing_addr) - .unwrap_or_else(|_| panic!("Failed to bind to transient address {}", &temp_outgoing_addr)); - let upstream_recv = upstream_send.try_clone() - .unwrap_or_else(|_| panic!("Failed to clone client-specific connection to upstream!")); + let upstream_send = UdpSocket::bind(&temp_outgoing_addr).unwrap_or_else( + |_| panic!("Failed to bind to transient address {}", &temp_outgoing_addr) + ); + let upstream_recv = upstream_send.try_clone().unwrap_or_else( + |_| panic!("Failed to clone client-specific connection to upstream!") + ); - let mut timeouts : u64 = 0; + let mut timeouts: u64 = 0; let timed_out = Arc::new(AtomicBool::new(false)); let local_timed_out = timed_out.clone(); @@ -112,15 +134,14 @@ fn forward(bind_addr: &str, local_port: i32, remote_host: &str, remote_port: i32 match upstream_recv.recv_from(&mut from_upstream) { Ok((bytes_rcvd, _)) => { let to_send = from_upstream[..bytes_rcvd].to_vec(); - local_send_queue.send((src_addr, to_send)) - .expect("Failed to queue response from upstream server for forwarding!"); + local_send_queue.send((src_addr, to_send)).expect("Failed to queue response from upstream server for forwarding!"); }, Err(_) => { if local_timed_out.load(Ordering::Relaxed) { debugging!("Terminating forwarder thread for client {} due to timeout", src_addr); break; } - } + }, }; } }); @@ -128,8 +149,9 @@ fn forward(bind_addr: &str, local_port: i32, remote_host: &str, remote_port: i32 loop { match receiver.recv_timeout(Duration::from_millis(TIMEOUT)) { Ok(from_client) => { - upstream_send.send_to(from_client.as_slice(), &remote_addr_copy) - .unwrap_or_else(|_| panic!("Failed to forward packet from client {} to upstream server!", src_addr)); + upstream_send.send_to(from_client.as_slice(), &remote_addr_copy).unwrap_or_else( + |_| panic!("Failed to forward packet from client {} to upstream server!", src_addr) + ); timeouts = 0; //reset timeout count }, Err(_) => { @@ -139,7 +161,7 @@ fn forward(bind_addr: &str, local_port: i32, remote_host: &str, remote_port: i32 timed_out.store(true, Ordering::Relaxed); break; } - } + }, }; } }); @@ -157,7 +179,7 @@ fn forward(bind_addr: &str, local_port: i32, remote_host: &str, remote_port: i32 debugging!("New connection received from previously timed-out client {}", client_id); remove_existing = true; continue; - } + }, } } }