use emissary_util::storage::{Storage, StorageBundle}; use emissary_util::reseeder::Reseeder; use std::path::PathBuf; pub trait RouterConfigUtils { async fn config(&mut self) -> Result<(StorageBundle, Storage), Box>; async fn prepare_router(&mut self) -> Result<(), Box>; async fn reseed(&mut self, config: &StorageBundle, storage: &Storage) -> Result<(), Box>; } pub struct EmissaryConfig { Storage: Option, AutoUpdate: Option, HttpProxtPort: Option, SocksProxyPort: Option, } 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> { 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)) } async fn reseed(&mut self, config: &StorageBundle, storage: &Storage) -> Result<(), Box> { let mut routers = config.routers.clone(); if routers.is_empty() { match Reseeder::reseed(None, false).await { Ok(reseed_routers) => { for info in reseed_routers { let _ = storage .store_router_info(info.name.to_string(), info.router_info.clone()) .await; 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(), ); } } } Ok(()) } async fn prepare_router(&mut self) -> Result<(), Box> { Ok(()) } }