diff options
-rw-r--r-- | src/config.rs | 100 | ||||
-rw-r--r-- | src/manager/mod.rs | 6 | ||||
-rw-r--r-- | src/proto.rs | 208 |
3 files changed, 275 insertions, 39 deletions
diff --git a/src/config.rs b/src/config.rs index b755739..6269525 100644 --- a/src/config.rs +++ b/src/config.rs @@ -7,8 +7,8 @@ use serde_derive; use std::collections::HashMap; use std::path::PathBuf; -#[serde(deny_unknown_fields)] #[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] +#[serde(deny_unknown_fields)] pub struct Source { pub url: String, pub psk: Option<Key>, @@ -18,21 +18,17 @@ pub struct Source { pub required: bool, } -#[serde(deny_unknown_fields)] #[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] +#[serde(deny_unknown_fields)] pub struct Peer { pub source: Option<String>, pub psk: Option<Key>, } -#[serde(deny_unknown_fields)] -#[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug)] pub struct GlobalConfig { - #[serde(default = "default_min_keepalive")] pub min_keepalive: u32, - #[serde(default = "default_max_keepalive")] pub max_keepalive: u32, - #[serde(default, rename = "peer")] pub peers: HashMap<Key, Peer>, } @@ -59,13 +55,11 @@ impl GlobalConfig { } } -#[serde(deny_unknown_fields)] -#[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug)] pub struct UpdaterConfig { pub cache_directory: Option<PathBuf>, // Number of seconds between regular updates. - #[serde(default = "default_refresh_sec")] pub refresh_sec: u32, } @@ -79,21 +73,93 @@ impl Default for UpdaterConfig { } } -#[serde(deny_unknown_fields)] #[derive(serde_derive::Serialize, serde_derive::Deserialize, Default, Clone, Debug)] +#[serde(from = "ConfigRepr", into = "ConfigRepr")] pub struct Config { pub runtime_directory: Option<PathBuf>, - - #[serde(flatten)] pub global: GlobalConfig, - - #[serde(flatten)] pub updater: UpdaterConfig, - - #[serde(rename = "source")] pub sources: HashMap<String, Source>, } +#[derive(serde_derive::Serialize, serde_derive::Deserialize)] +#[serde(deny_unknown_fields)] +struct ConfigRepr { + runtime_directory: Option<PathBuf>, + cache_directory: Option<PathBuf>, + + #[serde(default = "default_min_keepalive")] + min_keepalive: u32, + #[serde(default = "default_max_keepalive")] + max_keepalive: u32, + #[serde(default, rename = "peer")] + peers: HashMap<Key, Peer>, + + #[serde(default = "default_refresh_sec")] + refresh_sec: u32, + + #[serde(default, rename = "source")] + sources: HashMap<String, Source>, +} + +impl From<Config> for ConfigRepr { + #[inline] + fn from(v: Config) -> Self { + let Config { + runtime_directory, + global, + updater, + sources, + } = v; + let GlobalConfig { + min_keepalive, + max_keepalive, + peers, + } = global; + let UpdaterConfig { + cache_directory, + refresh_sec, + } = updater; + Self { + runtime_directory, + cache_directory, + min_keepalive, + max_keepalive, + peers, + refresh_sec, + sources, + } + } +} + +impl From<ConfigRepr> for Config { + #[inline] + fn from(v: ConfigRepr) -> Self { + let ConfigRepr { + runtime_directory, + cache_directory, + min_keepalive, + max_keepalive, + peers, + refresh_sec, + sources, + } = v; + Self { + runtime_directory, + global: GlobalConfig { + min_keepalive, + max_keepalive, + peers, + }, + updater: UpdaterConfig { + cache_directory, + refresh_sec, + }, + sources, + } + } +} + #[inline] const fn default_min_keepalive() -> u32 { 10 diff --git a/src/manager/mod.rs b/src/manager/mod.rs index 20ec061..8df4d23 100644 --- a/src/manager/mod.rs +++ b/src/manager/mod.rs @@ -139,10 +139,10 @@ impl Manager { .next .as_ref() .and_then(|next| { - if ts >= next.update_at { - Some(&next.config) + if ts >= next.0 { + Some(&next.1) } else { - t_cfg = t_cfg.min(next.update_at); + t_cfg = t_cfg.min(next.0); None } }) diff --git a/src/proto.rs b/src/proto.rs index 9421e53..e546b2f 100644 --- a/src/proto.rs +++ b/src/proto.rs @@ -6,55 +6,146 @@ use crate::model::{Endpoint, Ipv4Net, Ipv6Net, Key}; use serde_derive; use std::time::SystemTime; -#[serde(deny_unknown_fields)] -#[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] +#[derive(Clone, PartialEq, Eq, Debug)] pub struct Peer { pub public_key: Key, - #[serde(default)] pub ipv4: Vec<Ipv4Net>, - #[serde(default)] pub ipv6: Vec<Ipv6Net>, } -#[serde(deny_unknown_fields)] +#[serde(from = "ServerRepr", into = "ServerRepr")] #[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] pub struct Server { - #[serde(flatten)] pub peer: Peer, pub endpoint: Endpoint, - #[serde(default)] pub keepalive: u32, } +#[derive(serde_derive::Serialize, serde_derive::Deserialize)] #[serde(deny_unknown_fields)] +struct ServerRepr { + public_key: Key, + #[serde(default)] + ipv4: Vec<Ipv4Net>, + #[serde(default)] + ipv6: Vec<Ipv6Net>, + endpoint: Endpoint, + #[serde(default)] + keepalive: u32, +} + +impl From<Server> for ServerRepr { + #[inline] + fn from(v: Server) -> Self { + let Server { + peer, + endpoint, + keepalive, + } = v; + let Peer { + public_key, + ipv4, + ipv6, + } = peer; + Self { + public_key, + ipv4, + ipv6, + endpoint, + keepalive, + } + } +} + +impl From<ServerRepr> for Server { + #[inline] + fn from(v: ServerRepr) -> Self { + let ServerRepr { + public_key, + ipv4, + ipv6, + endpoint, + keepalive, + } = v; + Self { + peer: Peer { + public_key, + ipv4, + ipv6, + }, + endpoint, + keepalive, + } + } +} + #[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] +#[serde(from = "RoadWarriorRepr", into = "RoadWarriorRepr")] pub struct RoadWarrior { - #[serde(flatten)] pub peer: Peer, pub base: Key, } #[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] -pub struct SourceConfig { +#[serde(deny_unknown_fields)] +pub struct RoadWarriorRepr { + public_key: Key, #[serde(default)] - pub servers: Vec<Server>, + ipv4: Vec<Ipv4Net>, #[serde(default)] - pub road_warriors: Vec<RoadWarrior>, + ipv6: Vec<Ipv6Net>, + pub base: Key, } -#[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] -pub struct SourceNextConfig { - #[serde(with = "serde_utc")] - pub update_at: SystemTime, - #[serde(flatten)] - pub config: SourceConfig, +impl From<RoadWarrior> for RoadWarriorRepr { + #[inline] + fn from(v: RoadWarrior) -> Self { + let RoadWarrior { peer, base } = v; + let Peer { + public_key, + ipv4, + ipv6, + } = peer; + Self { + public_key, + ipv4, + ipv6, + base, + } + } +} + +impl From<RoadWarriorRepr> for RoadWarrior { + #[inline] + fn from(v: RoadWarriorRepr) -> Self { + let RoadWarriorRepr { + public_key, + ipv4, + ipv6, + base, + } = v; + Self { + peer: Peer { + public_key, + ipv4, + ipv6, + }, + base, + } + } +} + +#[derive(Clone, PartialEq, Eq, Debug)] +pub struct SourceConfig { + pub servers: Vec<Server>, + pub road_warriors: Vec<RoadWarrior>, } #[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] +#[serde(from = "SourceRepr", into = "SourceRepr")] pub struct Source { - #[serde(flatten)] pub config: SourceConfig, - pub next: Option<SourceNextConfig>, + pub next: Option<(SystemTime, SourceConfig)>, } impl Source { @@ -69,6 +160,85 @@ impl Source { } } +#[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] +struct SourceNextRepr { + #[serde(default)] + servers: Vec<Server>, + #[serde(default)] + road_warriors: Vec<RoadWarrior>, + #[serde(with = "serde_utc")] + update_at: SystemTime, +} + +#[derive(serde_derive::Serialize, serde_derive::Deserialize, Clone, PartialEq, Eq, Debug)] +struct SourceRepr { + #[serde(default)] + servers: Vec<Server>, + #[serde(default)] + road_warriors: Vec<RoadWarrior>, + next: Option<SourceNextRepr>, +} + +impl From<Source> for SourceRepr { + #[inline] + fn from(v: Source) -> Self { + let Source { config, next } = v; + let SourceConfig { + servers, + road_warriors, + } = config; + Self { + servers, + road_warriors, + next: next.map( + #[inline] + |next| { + let (update_at, next) = next; + SourceNextRepr { + servers: next.servers, + road_warriors: next.road_warriors, + update_at, + } + }, + ), + } + } +} + +impl From<SourceRepr> for Source { + #[inline] + fn from(v: SourceRepr) -> Self { + let SourceRepr { + servers, + road_warriors, + next, + } = v; + Self { + config: SourceConfig { + servers, + road_warriors, + }, + next: next.map( + #[inline] + |next| { + let SourceNextRepr { + servers, + road_warriors, + update_at, + } = next; + ( + update_at, + SourceConfig { + servers, + road_warriors, + }, + ) + }, + ), + } + } +} + mod serde_utc { use chrono::{DateTime, SecondsFormat, TimeZone, Utc}; use serde::*; |