use crate::config::Config; use maxminddb::{Reader, geoip2}; use serde::Deserialize; use std::net::IpAddr; // 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), /// 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, } pub type Rules = Vec; /// Type for deserializing the routing rules like: #[derive(serde::Deserialize)] pub struct Rule { pub target: RouteType, pub action: RouteAction, } pub struct GeoIpService { reader: Reader>, } impl GeoIpService { pub fn new(config: Config) -> Result> { 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, Box> { let result = self.reader.lookup(ip)?; result .decode::()? .ok_or_else(|| "Couldnt lookup IP geo.".into()) } }