diff options
Diffstat (limited to 'src/router/router.rs')
| -rw-r--r-- | src/router/router.rs | 197 |
1 files changed, 127 insertions, 70 deletions
diff --git a/src/router/router.rs b/src/router/router.rs index c438d75..7c36382 100644 --- a/src/router/router.rs +++ b/src/router/router.rs @@ -1,92 +1,149 @@ -use emissary_util::storage::{Storage, StorageBundle}; +use emissary_core::router::Router; +use emissary_core::{Config, Ntcp2Config, SamConfig, TransitConfig}; +use emissary_util::port_mapper::{PortMapper, PortMapperConfig}; use emissary_util::reseeder::Reseeder; +use emissary_util::runtime::tokio::Runtime as TokioRuntime; +use emissary_util::storage::{Storage, StorageBundle}; +use serde::{Deserialize, Serialize}; use std::path::PathBuf; +use std::sync::Arc; +use std::future::Future; - -pub trait RouterConfigUtils { - async fn config(&mut self) -> Result<(StorageBundle, Storage), Box<dyn std::error::Error>>; - async fn prepare_router(&mut self) -> Result<(), Box<dyn std::error::Error>>; - async fn reseed(&mut self, config: &StorageBundle, storage: &Storage) -> Result<(), Box<dyn std::error::Error>>; +pub trait RouterUtils { + fn config(&mut self) -> impl Future<Output = Result<(), Box<dyn std::error::Error>>> + Send; + fn reseed(&mut self) -> impl Future<Output = Result<(), Box<dyn std::error::Error>>> + Send; + fn start(self) -> impl Future<Output = Result<Router<TokioRuntime>, Box<dyn std::error::Error>>> + Send; } +#[derive(Debug, Deserialize, Serialize)] pub struct EmissaryConfig { - Storage: Option<PathBuf>, - AutoUpdate: Option<bool>, - HttpProxtPort: Option<u16>, - SocksProxyPort: Option<u16>, + pub storage: Option<PathBuf>, + pub auto_update: Option<bool>, + pub http_proxy_port: Option<u16>, + pub socks_proxy_port: Option<u16>, } -impl RouterConfigUtils for EmissaryConfig { - /// Configures the router with the given configuration. - /// - /// If the `Storage` field is `None`, it will be set to `/var/lib/mesk/router/`. - /// - /// # Errors - /// - /// Returns an error if there's an issue while configuring the router. - async fn config(&mut self) -> Result<(StorageBundle, Storage), Box<dyn std::error::Error>> { - self.Storage.get_or_insert_with(|| PathBuf::from("/var/lib/mesk/router/")); - self.AutoUpdate.get_or_insert(true); - self.HttpProxtPort.get_or_insert(4445); - self.SocksProxyPort.get_or_insert(4446); - - let storage = Storage::new(self.Storage.clone().into()).await?; - - let StorageBundle { - ntcp2_iv, - ntcp2_key, - profiles, - router_info, - routers, - signing_key, - static_key, - ssu2_intro_key, - ssu2_static_key, - } = storage.load().await; - - Ok((StorageBundle { - ntcp2_iv, - ntcp2_key, - profiles, - router_info, - routers, - signing_key, - static_key, - ssu2_intro_key, - ssu2_static_key, - }, storage)) +pub struct Emissary { + config: EmissaryConfig, + storage: Option<Storage>, + storage_bundle: Option<StorageBundle>, +} + +impl Emissary { + pub fn new(config: EmissaryConfig) -> Self { + Self { + config, + storage: None, + storage_bundle: None, + } + } + + fn ensure_configured(&self) -> Result<(), Box<dyn std::error::Error>> { + if self.storage.is_none() || self.storage_bundle.is_none() { + Err("Router not configured. Call `config()` first.".into()) + } else { + Ok(()) + } + } +} + +impl RouterUtils for Emissary { + async fn config(&mut self) -> Result<(), Box<dyn std::error::Error>> { + if self.config.storage.is_none() { + self.config.storage = Some(PathBuf::from("/var/lib/mesk/router/")); + } + if self.config.auto_update.is_none() { + self.config.auto_update = Some(true); + } + if self.config.http_proxy_port.is_none() { + self.config.http_proxy_port = Some(4445); + } + if self.config.socks_proxy_port.is_none() { + self.config.socks_proxy_port = Some(4446); + } + + let storage = Storage::new(Some(self.config.storage.clone().unwrap())).await?; + let bundle = storage.load().await; + + self.storage = Some(storage); + self.storage_bundle = Some(bundle); + + Ok(()) } - async fn reseed(&mut self, config: &StorageBundle, storage: &Storage) -> Result<(), Box<dyn std::error::Error>> { - let mut routers = config.routers.clone(); - - - if routers.is_empty() { + async fn reseed(&mut self) -> Result<(), Box<dyn std::error::Error>> { + self.ensure_configured()?; + + let storage = self.storage.as_ref().unwrap(); + let mut bundle = self.storage_bundle.take().unwrap(); + + if bundle.routers.is_empty() { match Reseeder::reseed(None, false).await { Ok(reseed_routers) => { for info in reseed_routers { - let _ = storage + if let Err(e) = storage .store_router_info(info.name.to_string(), info.router_info.clone()) - .await; - routers.push(info.router_info); + .await + { + log::warn!("Failed to store reseeded router info: {}", e); + } + bundle.routers.push(info.router_info); } } - Err(_) if routers.is_empty() => { - return Err("Could not reseed routers.".into()); - } - Err(error) => { - log::warn!( - "Failed to reseed routers: {} - using existing routers", error.to_string(), - ); + Err(e) => { + if bundle.routers.is_empty() { + self.storage_bundle = Some(bundle); + return Err(format!("Reseed failed and no routers available: {}", e).into()); + } else { + log::warn!("Reseed failed, but using existing routers: {}", e); + } } } - } + } + + self.storage_bundle = Some(bundle); Ok(()) } - async fn prepare_router(&mut self) -> Result<(), Box<dyn std::error::Error>> { - - - Ok(()) + async fn start(self) -> Result<Router<TokioRuntime>, Box<dyn std::error::Error>> { + let storage = self.storage.unwrap(); + let bundle = self.storage_bundle.unwrap(); + + let config = Config { + ntcp2: Some(Ntcp2Config { + port: 25515, + key: bundle.ntcp2_key, + iv: bundle.ntcp2_iv, + publish: true, + host: None, + }), + samv3_config: Some(SamConfig { + tcp_port: self.config.http_proxy_port.unwrap_or(4445), + udp_port: self.config.socks_proxy_port.unwrap_or(4446), + host: "127.0.0.1".to_string(), + }), + routers: bundle.routers, + profiles: bundle.profiles, + router_info: bundle.router_info, + static_key: Some(bundle.static_key), + signing_key: Some(bundle.signing_key), + transit: Some(TransitConfig { + max_tunnels: Some(1000), + }), + ..Default::default() + }; + + let (router, _events, router_info) = Router::<TokioRuntime>::new( + config, + None, // AddressBook + Some(Arc::new(storage.clone())), + ) + .await + .map_err(|e| format!("Router creation failed: {}", e))?; + + // Сохраняем router_info, если он новый + storage.store_local_router_info(router_info).await?; + + Ok(router) } -}
\ No newline at end of file +} |
