diff --git a/crates/alknet-core/Cargo.toml b/crates/alknet-core/Cargo.toml index 8b7ac8c..6f73df6 100644 --- a/crates/alknet-core/Cargo.toml +++ b/crates/alknet-core/Cargo.toml @@ -14,6 +14,7 @@ default = [] tls = ["dep:tokio-rustls", "dep:rustls", "dep:rustls-pki-types", "dep:webpki-roots"] iroh = ["dep:iroh", "dep:url"] acme = ["dep:rustls-acme", "dep:futures", "tls"] +irpc = [] testutil = [] transport-traits = [] diff --git a/crates/alknet-core/src/config/config_service.rs b/crates/alknet-core/src/config/config_service.rs new file mode 100644 index 0000000..173eca5 --- /dev/null +++ b/crates/alknet-core/src/config/config_service.rs @@ -0,0 +1,94 @@ +use std::sync::Arc; + +use arc_swap::ArcSwap; + +use super::{DynamicConfig, ForwardingPolicy, RateLimitConfig}; + +pub struct ConfigServiceImpl { + dynamic: Arc>, +} + +impl ConfigServiceImpl { + pub fn new(dynamic: Arc>) -> Self { + Self { dynamic } + } + + pub fn forwarding_policy(&self) -> Arc { + Arc::new(self.dynamic.load().forwarding.clone()) + } + + pub fn rate_limits(&self) -> Arc { + Arc::new(self.dynamic.load().rate_limits.clone()) + } + + pub fn reload(&self, new_config: DynamicConfig) { + self.dynamic.store(Arc::new(new_config)); + } +} + +impl std::fmt::Debug for ConfigServiceImpl { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.debug_struct("ConfigServiceImpl").finish() + } +} + +#[cfg(feature = "irpc")] +#[allow(dead_code)] +pub enum ConfigProtocol { + GetForwardingPolicy, + GetRateLimits, + ReloadForwarding { policy: ForwardingPolicy }, + ReloadRateLimits { limits: RateLimitConfig }, +} + +#[cfg(test)] +mod tests { + use super::*; + use crate::config::AuthPolicy; + + #[test] + fn config_service_impl_forwarding_policy() { + let (arc_swap, _) = super::super::new_dynamic_config(); + let service = ConfigServiceImpl::new(Arc::clone(&arc_swap)); + let policy = service.forwarding_policy(); + assert_eq!(policy.default, ForwardingPolicy::allow_all().default); + } + + #[test] + fn config_service_impl_rate_limits() { + let (arc_swap, _) = super::super::new_dynamic_config(); + let service = ConfigServiceImpl::new(Arc::clone(&arc_swap)); + let limits = service.rate_limits(); + assert_eq!(limits.max_auth_attempts, 10); + } + + #[test] + fn config_service_impl_reload() { + let (arc_swap, _) = super::super::new_dynamic_config(); + let service = ConfigServiceImpl::new(Arc::clone(&arc_swap)); + assert_eq!( + service.forwarding_policy().default, + ForwardingPolicy::allow_all().default + ); + + let new_config = DynamicConfig { + auth: AuthPolicy::empty(), + forwarding: ForwardingPolicy::deny_all(), + rate_limits: RateLimitConfig::default(), + }; + service.reload(new_config); + + assert_eq!( + service.forwarding_policy().default, + ForwardingPolicy::deny_all().default + ); + } + + #[test] + fn config_service_impl_debug() { + let (arc_swap, _) = super::super::new_dynamic_config(); + let service = ConfigServiceImpl::new(Arc::clone(&arc_swap)); + let debug_str = format!("{:?}", service); + assert!(debug_str.contains("ConfigServiceImpl")); + } +} diff --git a/crates/alknet-core/src/config/mod.rs b/crates/alknet-core/src/config/mod.rs index dd4879c..e3d0f30 100644 --- a/crates/alknet-core/src/config/mod.rs +++ b/crates/alknet-core/src/config/mod.rs @@ -1,6 +1,8 @@ +pub mod config_service; pub mod dynamic_config; pub mod static_config; +pub use config_service::ConfigServiceImpl; pub use dynamic_config::{ new_dynamic_config, AuthPolicy, ConfigReloadHandle, DynamicConfig, ForwardingAction, ForwardingPolicy, ForwardingRule, RateLimitConfig, diff --git a/crates/alknet-core/src/lib.rs b/crates/alknet-core/src/lib.rs index 6566828..122ca19 100644 --- a/crates/alknet-core/src/lib.rs +++ b/crates/alknet-core/src/lib.rs @@ -64,8 +64,8 @@ pub mod testutil; pub use client::channel_manager::{ChannelManager, ForwardRequest}; pub use client::connect::{ClientSession, ConnectError, ConnectOptions, TransportMode}; pub use config::{ - AuthPolicy, ConfigReloadHandle, DynamicConfig, ForwardingAction, ForwardingPolicy, - ForwardingRule, RateLimitConfig, StaticConfig, + AuthPolicy, ConfigReloadHandle, ConfigServiceImpl, DynamicConfig, ForwardingAction, + ForwardingPolicy, ForwardingRule, RateLimitConfig, StaticConfig, }; pub use error::{AuthError, ChannelError, ConfigError, ForwardError, TransportError}; pub use server::serve::{ServeError, ServeOptions, ServeTransportMode, Server};