Working on IP geo parsers && packet router

This commit is contained in:
namilsk 2026-03-17 19:19:14 +03:00
parent b2e7bb0317
commit 0d8f7c4373
No known key found for this signature in database
GPG key ID: 2B2F0A4D870B4F9F
6 changed files with 83 additions and 29 deletions

View file

@ -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"),

View file

@ -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>;
pub 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"
/// ```
/// 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())
}
}

View file

@ -1 +1,2 @@
mod geoip2;
pub mod geoip2;
pub mod toml;

15
src/geoparsers/toml.rs Normal file
View file

@ -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))
}

View file

@ -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()
}

View file

@ -0,0 +1,9 @@
use crate::geoparsers::geoip2::GeoIpService;
struct Router {
geoip: GeoIpService,
// geosite: GeoSiteService
// sniffer: Sniffer
}