diff --git a/README.md b/README.md index eadbe92..8ac0944 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ RUST_LOG=trace cargo run -- --allow=http://localhost/allow.txt \ * use http://127.0.0.1:8010 for API: * `/api/allow/{domain.com}` - add rule to the current session (and `--cache` if defined) * `/api/block/{domain.com}` - delete rule from the current session (and `--cache` if defined) - * `/api/list` - return active rules (from server memory) + * `/api/rules` - return active rules (from server memory) * `/api/cache/clean` - clean the `--cache` file (returns deleted rules or `null` if not enabled) ### Allow list example diff --git a/src/main.rs b/src/main.rs index 24bac33..041784c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,5 +1,5 @@ -mod list; mod opt; +mod rules; mod stats; use anyhow::Context; @@ -7,10 +7,10 @@ use fast_socks5::{ ReplyError, Result, Socks5Command, SocksError, server::{DnsResolveHelper as _, Socks5ServerProtocol, run_tcp_proxy, run_udp_proxy}, }; -use list::List; use log::*; use opt::{AuthMode, Opt}; use rocket::{State, http::Status, serde::json::Json}; +use rules::Rules; use stats::{Snap, Total}; use std::{future::Future, sync::Arc, time::Instant}; use structopt::StructOpt; @@ -29,11 +29,11 @@ async fn api_totals(totals: &State>, startup_time: &State) - #[rocket::get("/api/allow/")] async fn api_allow( rule: &str, - list: &State>, + rules: &State>, totals: &State>, ) -> Result, Status> { - let result = list.allow(rule).await; - totals.set_entries(list.rules().await); + let result = rules.allow(rule).await; + totals.set_entries(rules.rules().await); info!("Delete `{rule}` from the in-memory rules (operation status: {result:?})"); Ok(Json(result.map_err(|e| { error!("Allow request handle error for `{rule}`: `{e}`"); @@ -44,11 +44,11 @@ async fn api_allow( #[rocket::get("/api/block/")] async fn api_block( rule: &str, - list: &State>, + rules: &State>, totals: &State>, ) -> Result, Status> { - let result = list.block(rule).await; - totals.set_entries(list.rules().await); + let result = rules.block(rule).await; + totals.set_entries(rules.rules().await); info!("Add `{rule}` to the in-memory rules (operation status: {result:?})"); Ok(Json(result.map_err(|e| { error!("Block request handle error for `{rule}`: `{e}`"); @@ -56,16 +56,16 @@ async fn api_block( })?)) } -#[rocket::get("/api/list")] -async fn api_list(list: &State>) -> Result>, Status> { - let result = list.list().await; - info!("Get list rules (total: {})", result.len()); +#[rocket::get("/api/rules")] +async fn api_rules(rules: &State>) -> Result>, Status> { + let result = rules.list().await; + info!("Get rules (total: {})", result.len()); Ok(Json(result)) } #[rocket::get("/api/cache/clean")] -async fn api_cache_clean(list: &State>) -> Result>>, Status> { - let result = list.cache_clean().await; +async fn api_cache_clean(rules: &State>) -> Result>>, Status> { + let result = rules.cache_clean().await; info!("Clean cache file: {result:?}"); Ok(Json(result.map_err(|e| { error!("Could not handle cache clean request: `{e}`"); @@ -79,19 +79,19 @@ async fn rocket() -> _ { let opt: &'static Opt = Box::leak(Box::new(Opt::from_args())); - let list = Arc::new( - List::from_opt(&opt.allow_list, opt.cache.clone()) + let rules = Arc::new( + Rules::from_opt(&opt.allow_list, opt.cache.clone()) .await .unwrap(), ); - let totals = Arc::new(Total::with_rules(list.rules().await)); + let totals = Arc::new(Total::with_rules(rules.rules().await)); tokio::spawn({ - let socks_list = list.clone(); + let socks_rules = rules.clone(); let socks_totals = totals.clone(); async move { - if let Err(err) = spawn_socks_server(opt, socks_list, socks_totals).await { + if let Err(err) = spawn_socks_server(opt, socks_rules, socks_totals).await { error!("SOCKS server failed: `{err}`"); } } @@ -103,7 +103,7 @@ async fn rocket() -> _ { address: opt.api_addr.ip(), ..rocket::Config::release_default() }) - .manage(list) + .manage(rules) .manage(totals) .manage(Instant::now()) .mount( @@ -113,13 +113,17 @@ async fn rocket() -> _ { api_totals, api_allow, api_block, - api_list, + api_rules, api_cache_clean ], ) } -async fn spawn_socks_server(opt: &'static Opt, list: Arc, totals: Arc) -> Result<()> { +async fn spawn_socks_server( + opt: &'static Opt, + rules: Arc, + totals: Arc, +) -> Result<()> { if opt.allow_udp && opt.public_addr.is_none() { return Err(SocksError::ArgumentInputError( "Can't allow UDP if public-addr is not set", @@ -138,7 +142,7 @@ async fn spawn_socks_server(opt: &'static Opt, list: Arc, totals: Arc { - spawn_and_log_error(serve_socks5(opt, socket, list.clone(), totals.clone())); + spawn_and_log_error(serve_socks5(opt, socket, rules.clone(), totals.clone())); } Err(err) => error!("accept error = {:?}", err), } @@ -148,7 +152,7 @@ async fn spawn_socks_server(opt: &'static Opt, list: Arc, totals: Arc, + rules: Arc, totals: Arc, ) -> Result<(), SocksError> { totals.increase_request(); @@ -170,7 +174,7 @@ async fn serve_socks5( let (host, _) = request.2.clone().into_string_and_port(); - if !list.any(&host).await { + if !rules.any(&host).await { totals.increase_blocked(); info!("Blocked connection attempt to: {host}"); request diff --git a/src/list.rs b/src/rules.rs similarity index 85% rename from src/list.rs rename to src/rules.rs index a95a75a..468844f 100644 --- a/src/list.rs +++ b/src/rules.rs @@ -8,14 +8,14 @@ use log::*; use std::{collections::HashSet, path::PathBuf}; use tokio::{fs, sync::RwLock}; -pub struct List { +pub struct Rules { /// In-memory registry, based on `--allow-list` + `--cache` index: RwLock>, /// FS cache for JSON/API changes, based on `--cache` value cache: Cache, } -impl List { +impl Rules { /// Build new List object pub async fn from_opt(list: &Vec, cache: Option) -> Result { fn handle(this: &mut HashSet, line: &str) -> Option { @@ -27,27 +27,27 @@ impl List { let mut index = HashSet::new(); - let mut list_rules_total = 0; + let mut rules_total = 0; - for i in list { - for line in if i.contains("://") { - let response = reqwest::get(i).await?; + for l in list { + for line in if l.contains("://") { + let response = reqwest::get(l).await?; let status = response.status(); if status.is_success() { response.text().await? } else { - warn!("Could not receive remote list `{i}`: `{status}`"); + warn!("Could not receive remote list `{l}`: `{status}`"); continue; } } else { - fs::read_to_string(i).await? + fs::read_to_string(l).await? } .lines() { if handle(&mut index, line).is_some_and(|status| !status) { - warn!("List `{i}` contains duplicated entry: `{line}`") + warn!("Ruleset `{l}` contains duplicated entry: `{line}`") } - list_rules_total += 1 + rules_total += 1 } } @@ -65,9 +65,7 @@ impl List { }); let len = index.len(); - info!( - "Total rules parsed: {len} (lists: {list_rules_total} / cache: {cache_rules_total:?})", - ); + info!("Total rules parsed: {len} (riles: {rules_total} / cache: {cache_rules_total:?})",); Ok(Self { index: RwLock::new(index), diff --git a/src/list/cache.rs b/src/rules/cache.rs similarity index 100% rename from src/list/cache.rs rename to src/rules/cache.rs diff --git a/src/list/item.rs b/src/rules/item.rs similarity index 83% rename from src/list/item.rs rename to src/rules/item.rs index 138e443..583e381 100644 --- a/src/list/item.rs +++ b/src/rules/item.rs @@ -9,10 +9,10 @@ pub enum Item { impl Item { pub fn from_line(rule: &str) -> Self { if let Some(item) = rule.strip_prefix(".") { - debug!("Add `{rule}` to the whitelist"); + debug!("Init `{rule}` rule"); Self::Ending(item.to_string()) } else { - debug!("Add `{rule}` exact match to the whitelist"); + debug!("Init `{rule}` exact match rule"); Self::Exact(rule.to_string()) } }