summaryrefslogtreecommitdiff
path: root/src/geoparsers/geoip2.rs
diff options
context:
space:
mode:
authornamilsk <namilsk@namilsk.tech>2026-03-17 19:19:14 +0300
committernamilsk <namilsk@namilsk.tech>2026-03-17 19:19:14 +0300
commit0d8f7c437399531d700c2e01b4e0b33ba72bd689 (patch)
tree57677d4efa4766b19dda5da6354674cf7ef77d0c /src/geoparsers/geoip2.rs
parentb2e7bb0317cd75946c275620de0aa9e579c0fae5 (diff)
Working on IP geo parsers && packet router
Diffstat (limited to 'src/geoparsers/geoip2.rs')
-rw-r--r--src/geoparsers/geoip2.rs61
1 files changed, 40 insertions, 21 deletions
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())
+ }
+}