diff options
| author | namilsk <namilsk@namilsk.tech> | 2026-03-17 19:19:14 +0300 |
|---|---|---|
| committer | namilsk <namilsk@namilsk.tech> | 2026-03-17 19:19:14 +0300 |
| commit | 0d8f7c437399531d700c2e01b4e0b33ba72bd689 (patch) | |
| tree | 57677d4efa4766b19dda5da6354674cf7ef77d0c /src | |
| parent | b2e7bb0317cd75946c275620de0aa9e579c0fae5 (diff) | |
Working on IP geo parsers && packet router
Diffstat (limited to 'src')
| -rw-r--r-- | src/config.rs | 14 | ||||
| -rw-r--r-- | src/geoparsers/geoip2.rs | 61 | ||||
| -rw-r--r-- | src/geoparsers/mod.rs | 3 | ||||
| -rw-r--r-- | src/geoparsers/toml.rs | 15 | ||||
| -rw-r--r-- | src/main.rs | 12 | ||||
| -rw-r--r-- | src/routing.rs | 9 |
6 files changed, 84 insertions, 30 deletions
diff --git a/src/config.rs b/src/config.rs index 6552a65..846a1b5 100644 --- a/src/config.rs +++ b/src/config.rs @@ -9,7 +9,7 @@ pub enum RunTypes { #[derive(Serialize, Deserialize)] pub struct Config { - /// Paths to v2ray `geosite.dat', `geoip.dat` + /// Paths to `geosite.dat', `geolite2.mmdb` pub geo_files: [String; 2], /// Routing settings similar to v2ray pub routing: String, @@ -17,11 +17,21 @@ pub struct Config { pub mode: RunTypes, } +// TODO: Think how to add other anonymisers +// Like VPN on localhost:10808 +// it can be like: +// ```toml +// [[proxy]] +// name = "VPN" +// addr = "127.0.0.1:10808" +// type = "SOCKS5" # ... +// ``` + impl Default for Config { fn default() -> Self { Self { geo_files: [ - String::from("/etc/nsc/data/geoip.dat"), + String::from("/etc/nsc/data/geolite2.mmdb"), String::from("/etc/nsc/data/geosite.dat"), ], routing: String::from("/etc/nsc/routing.toml"), diff --git a/src/geoparsers/geoip2.rs b/src/geoparsers/geoip2.rs index 9323280..9f2cc8b 100644 --- a/src/geoparsers/geoip2.rs +++ b/src/geoparsers/geoip2.rs @@ -1,42 +1,61 @@ -use ipnet::IpNet; use crate::config::Config; +use maxminddb::{Reader, geoip2}; +use serde::Deserialize; +use std::net::IpAddr; -/// Enum for declaring GeoSite/IP routing +// For now only MMDB because i cant found .proto schemes of +// V2Ray GeoSite.dat :(( +// TODO: V2Ray protobuf parsing && Test 4 ts + +/// Interface enum for `dst_addr` info +#[derive(Debug, Deserialize)] pub enum RouteType { /// GeoSite MMDB type, like `category-ads-all` GeoSite(String), - /// Subnet - GeoIp(IpNet), + /// Result with GeoCode like "RU" + GeoIp(String), + // String because enum will used as interface in result of `route_packet`. } /// Routing actions +#[derive(Debug, Deserialize)] pub enum RouteAction { + #[serde(alias = "block")] Block, + #[serde(alias = "proxy")] Proxy, + #[serde(alias = "direct")] Direct, } -type Rules = Vec<Rule>; - -/// Type for declaring the routing rules like: -/// ```toml -/// [rule] -/// action = enum RouteAction -/// target = enum RouteType -/// -/// [rule] -/// target = "geosite:category-ads-all" -/// action = "block" -/// ``` +pub type Rules = Vec<Rule>; + +/// Type for deserializing the routing rules like: +#[derive(serde::Deserialize)] pub struct Rule { pub target: RouteType, pub action: RouteAction, } -pub fn parse_ruleset(config: Config) -> Result<Rules, Box<dyn std::error::Error>> { - let reader = maxminddb::Reader::open_readfile(config.geo_files[0].clone())?; - - // Ok(()) - todo!(); +pub struct GeoIpService { + reader: Reader<Vec<u8>>, } +impl GeoIpService { + pub fn new(config: Config) -> Result<Self, Box<dyn std::error::Error>> { + let path = config.geo_files.get(0).unwrap(); + let reader = Reader::open_readfile(path)?; + Ok(Self { reader }) + } + + pub fn lookup_country<'a>( + &'a self, + ip: IpAddr, + ) -> Result<maxminddb::geoip2::Country<'a>, Box<dyn std::error::Error>> { + let result = self.reader.lookup(ip)?; + + result + .decode::<geoip2::Country>()? + .ok_or_else(|| "Couldnt lookup IP geo.".into()) + } +} diff --git a/src/geoparsers/mod.rs b/src/geoparsers/mod.rs index 9f95b8f..43af0f3 100644 --- a/src/geoparsers/mod.rs +++ b/src/geoparsers/mod.rs @@ -1 +1,2 @@ -mod geoip2; +pub mod geoip2; +pub mod toml; diff --git a/src/geoparsers/toml.rs b/src/geoparsers/toml.rs new file mode 100644 index 0000000..3638aa7 --- /dev/null +++ b/src/geoparsers/toml.rs @@ -0,0 +1,15 @@ +use crate::config::Config; +use crate::geoparsers::geoip2::Rules; + +pub fn parse_rules(config: Config) -> Result<Option<Rules>, Box<dyn std::error::Error>> { + let data = match std::fs::read_to_string(config.routing) { + Ok(result) => result, + Err(_) => { + println!("Couldnt find your `rules.toml`; Using default mode. All to anonymizers"); + return Ok(None); + } + }; + + let rules: Rules = toml::from_str(&data)?; + Ok(Some(rules)) +} diff --git a/src/main.rs b/src/main.rs index d90ae5d..594f751 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,13 +1,13 @@ -// mod config; -// mod geoparsers; -// pub mod sniffing; -// mod startup; +mod routing; +mod config; +mod geoparsers; +pub mod sniffing; +mod startup; use nsc::startup::init; use std::io::Read; -fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static> ->{ +fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync + 'static>> { init() } diff --git a/src/routing.rs b/src/routing.rs index e69de29..21e355b 100644 --- a/src/routing.rs +++ b/src/routing.rs @@ -0,0 +1,9 @@ +use crate::geoparsers::geoip2::GeoIpService; + +struct Router { + geoip: GeoIpService, + // geosite: GeoSiteService + // sniffer: Sniffer +} + + |
