From 5a85406e30a1d883be9982ecaf6881bf563257f4 Mon Sep 17 00:00:00 2001 From: Herbert Wolverson Date: Mon, 1 May 2023 13:34:52 +0000 Subject: [PATCH] Refactor the long-term stats module into cleaner code. --- .../src/long_term_stats/license_types.rs | 74 ++++++++ .../license_utils.rs} | 177 +----------------- src/rust/lqos_bus/src/long_term_stats/mod.rs | 15 ++ .../src/long_term_stats/submissions.rs | 101 ++++++++++ 4 files changed, 194 insertions(+), 173 deletions(-) create mode 100644 src/rust/lqos_bus/src/long_term_stats/license_types.rs rename src/rust/lqos_bus/src/{long_term_stats.rs => long_term_stats/license_utils.rs} (52%) create mode 100644 src/rust/lqos_bus/src/long_term_stats/mod.rs create mode 100644 src/rust/lqos_bus/src/long_term_stats/submissions.rs diff --git a/src/rust/lqos_bus/src/long_term_stats/license_types.rs b/src/rust/lqos_bus/src/long_term_stats/license_types.rs new file mode 100644 index 00000000..e6d7df02 --- /dev/null +++ b/src/rust/lqos_bus/src/long_term_stats/license_types.rs @@ -0,0 +1,74 @@ +//! Data-types used for license key exchange and lookup. + +use serde::{Serialize, Deserialize}; +use dryoc::dryocbox::PublicKey; +use thiserror::Error; + +/// Network-transmitted query to ask the status of a license +/// key. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum LicenseRequest { + /// Check the validity of a key + LicenseCheck { + /// The Key to Check + key: String, + }, + /// Exchange Keys + KeyExchange { + /// The node ID of the requesting shaper node + node_id: String, + /// The pretty name of the requesting shaper node + node_name: String, + /// The license key of the requesting shaper node + license_key: String, + /// The sodium-style public key of the requesting shaper node + public_key: PublicKey, + }, +} + +/// License server responses for a key +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub enum LicenseReply { + /// The license is denied + Denied, + /// The license is valid + Valid { + /// When does the license expire? + expiry: u64, + /// Address to which statistics should be submitted + stats_host: String, + }, + /// Key Exchange + MyPublicKey { + /// The server's public key + public_key: PublicKey, + }, +} + +/// Errors that can occur when checking licenses +#[derive(Debug, Error)] +pub enum LicenseCheckError { + /// Serialization error + #[error("Unable to serialize license check")] + SerializeFail, + /// Network error + #[error("Unable to send license check")] + SendFail, + /// Network error + #[error("Unable to receive license result")] + ReceiveFail, + /// Deserialization error + #[error("Unable to deserialize license result")] + DeserializeFail, +} + +/// Stores a license id and node id for transport +#[derive(Debug, Serialize, Deserialize)] +pub struct NodeIdAndLicense { + /// The node id + pub node_id: String, + /// The license key + pub license_key: String, + /// The Sodium Nonce + pub nonce: [u8; 24], +} \ No newline at end of file diff --git a/src/rust/lqos_bus/src/long_term_stats.rs b/src/rust/lqos_bus/src/long_term_stats/license_utils.rs similarity index 52% rename from src/rust/lqos_bus/src/long_term_stats.rs rename to src/rust/lqos_bus/src/long_term_stats/license_utils.rs index 7168cf1a..5033ce60 100644 --- a/src/rust/lqos_bus/src/long_term_stats.rs +++ b/src/rust/lqos_bus/src/long_term_stats/license_utils.rs @@ -1,176 +1,8 @@ +//! Functions for talking to the license server + +use super::{LicenseCheckError, LicenseRequest, LicenseReply, LICENSE_SERVER}; use dryoc::dryocbox::PublicKey; -use serde::{Deserialize, Serialize}; -use thiserror::Error; -use tokio::{ - io::{AsyncReadExt, AsyncWriteExt}, - net::TcpStream, -}; - -/// Type that provides a minimum, maximum and average value -/// for a given statistic within the associated time period. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct StatsSummary { - /// Minimum value - pub min: (u64, u64), - /// Maximum value - pub max: (u64, u64), - /// Average value - pub avg: (u64, u64), -} - -/// Type that provides a minimum, maximum and average value -/// for a given RTT value within the associated time period. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct StatsRttSummary { - /// Minimum value - pub min: u32, - /// Maximum value - pub max: u32, - /// Average value - pub avg: u32, -} - -/// Type that holds total traffic statistics for a given time period -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct StatsTotals { - /// Total number of packets - pub packets: StatsSummary, - /// Total number of bits - pub bits: StatsSummary, - /// Total number of shaped bits - pub shaped_bits: StatsSummary, -} - -/// Type that holds per-host statistics for a given stats collation -/// period. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct StatsHost { - /// Host circuit_id as it appears in ShapedDevices.csv - pub circuit_id: String, - /// Device id as it appears in ShapedDevices.csv - pub device_id: String, - /// Parent node (hopefully in network.json!) - pub parent_node: String, - /// Device name as it appears in ShapedDevices.csv - pub device_name: String, - /// Circuit name as it appears in ShapedDevices.csv - pub circuit_name: String, - /// Host's IP address - pub ip_address: String, - /// Host's MAC address - pub mac: String, - /// Host's traffic statistics - pub bits: StatsSummary, - /// Host's RTT statistics - pub rtt: StatsRttSummary, - /// Positional arguments indicating which tree entries apply - pub tree_indices: Vec, -} - -/// Node inside a traffic summary tree -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct StatsTreeNode { - /// Name (from network.json) - pub name: String, - /// Maximum allowed throughput (from network.json) - pub max_throughput: (u32, u32), - /// Current throughput (from network.json) - pub current_throughput: (u32, u32), - /// RTT summaries - pub rtt: (u16, u16, u16), - /// Indices of parents in the tree - pub parents: Vec, - /// Index of immediate parent in the tree - pub immediate_parent: Option, - /// Node Type - pub node_type: Option, -} - -/// Collation of all stats for a given time period -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub struct StatsSubmission { - /// Timestamp of the collation (UNIX time) - pub timestamp: u64, - /// Total traffic statistics - pub totals: Option, - /// Per-host statistics - pub hosts: Option>, - /// Tree of traffic summaries - pub tree: Option>, - /// CPU utiliation on the shaper - pub cpu_usage: Vec, - /// RAM utilization on the shaper - pub ram_percent: u32, -} - -/// Network-transmitted query to ask the status of a license -/// key. -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub enum LicenseRequest { - /// Check the validity of a key - LicenseCheck { - /// The Key to Check - key: String, - }, - /// Exchange Keys - KeyExchange { - /// The node ID of the requesting shaper node - node_id: String, - /// The pretty name of the requesting shaper node - node_name: String, - /// The license key of the requesting shaper node - license_key: String, - /// The sodium-style public key of the requesting shaper node - public_key: PublicKey, - }, -} - -/// License server responses for a key -#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] -pub enum LicenseReply { - /// The license is denied - Denied, - /// The license is valid - Valid { - /// When does the license expire? - expiry: u64, - /// Address to which statistics should be submitted - stats_host: String, - }, - /// Key Exchange - MyPublicKey { - /// The server's public key - public_key: PublicKey, - }, -} - -/// Errors that can occur when checking licenses -#[derive(Debug, Error)] -pub enum LicenseCheckError { - /// Serialization error - #[error("Unable to serialize license check")] - SerializeFail, - /// Network error - #[error("Unable to send license check")] - SendFail, - /// Network error - #[error("Unable to receive license result")] - ReceiveFail, - /// Deserialization error - #[error("Unable to deserialize license result")] - DeserializeFail, -} - -/// Stores a license id and node id for transport -#[derive(Debug, Serialize, Deserialize)] -pub struct NodeIdAndLicense { - /// The node id - pub node_id: String, - /// The license key - pub license_key: String, - /// The Sodium Nonce - pub nonce: [u8; 24], -} +use tokio::{net::TcpStream, io::{AsyncReadExt, AsyncWriteExt}}; fn build_license_request(key: String) -> Result, LicenseCheckError> { let mut result = Vec::new(); @@ -222,7 +54,6 @@ fn build_key_exchange_request( Ok(result) } -const LICENSE_SERVER: &str = "license.libreqos.io:9126"; /// Ask the license server if the license is valid /// diff --git a/src/rust/lqos_bus/src/long_term_stats/mod.rs b/src/rust/lqos_bus/src/long_term_stats/mod.rs new file mode 100644 index 00000000..1261d374 --- /dev/null +++ b/src/rust/lqos_bus/src/long_term_stats/mod.rs @@ -0,0 +1,15 @@ +//! Holds data-types and utility functions for the long-term +//! statistics retention system. +//! +//! This is in the bus so that it can be readily shared between +//! server and client code. + +mod submissions; +mod license_types; +mod license_utils; + +pub use submissions::*; +pub use license_types::*; +pub use license_utils::*; + +pub(crate) const LICENSE_SERVER: &str = "license.libreqos.io:9126"; diff --git a/src/rust/lqos_bus/src/long_term_stats/submissions.rs b/src/rust/lqos_bus/src/long_term_stats/submissions.rs new file mode 100644 index 00000000..e7d4a78f --- /dev/null +++ b/src/rust/lqos_bus/src/long_term_stats/submissions.rs @@ -0,0 +1,101 @@ +//! Holds data-types to be submitted as part of long-term stats +//! collection. + +use serde::{Serialize, Deserialize}; + +/// Type that provides a minimum, maximum and average value +/// for a given statistic within the associated time period. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct StatsSummary { + /// Minimum value + pub min: (u64, u64), + /// Maximum value + pub max: (u64, u64), + /// Average value + pub avg: (u64, u64), +} + +/// Type that provides a minimum, maximum and average value +/// for a given RTT value within the associated time period. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct StatsRttSummary { + /// Minimum value + pub min: u32, + /// Maximum value + pub max: u32, + /// Average value + pub avg: u32, +} + +/// Type that holds total traffic statistics for a given time period +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct StatsTotals { + /// Total number of packets + pub packets: StatsSummary, + /// Total number of bits + pub bits: StatsSummary, + /// Total number of shaped bits + pub shaped_bits: StatsSummary, +} + +/// Type that holds per-host statistics for a given stats collation +/// period. +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct StatsHost { + /// Host circuit_id as it appears in ShapedDevices.csv + pub circuit_id: String, + /// Device id as it appears in ShapedDevices.csv + pub device_id: String, + /// Parent node (hopefully in network.json!) + pub parent_node: String, + /// Device name as it appears in ShapedDevices.csv + pub device_name: String, + /// Circuit name as it appears in ShapedDevices.csv + pub circuit_name: String, + /// Host's IP address + pub ip_address: String, + /// Host's MAC address + pub mac: String, + /// Host's traffic statistics + pub bits: StatsSummary, + /// Host's RTT statistics + pub rtt: StatsRttSummary, + /// Positional arguments indicating which tree entries apply + pub tree_indices: Vec, +} + +/// Node inside a traffic summary tree +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct StatsTreeNode { + /// Name (from network.json) + pub name: String, + /// Maximum allowed throughput (from network.json) + pub max_throughput: (u32, u32), + /// Current throughput (from network.json) + pub current_throughput: (u32, u32), + /// RTT summaries + pub rtt: (u16, u16, u16), + /// Indices of parents in the tree + pub parents: Vec, + /// Index of immediate parent in the tree + pub immediate_parent: Option, + /// Node Type + pub node_type: Option, +} + +/// Collation of all stats for a given time period +#[derive(Serialize, Deserialize, Clone, Debug, PartialEq)] +pub struct StatsSubmission { + /// Timestamp of the collation (UNIX time) + pub timestamp: u64, + /// Total traffic statistics + pub totals: Option, + /// Per-host statistics + pub hosts: Option>, + /// Tree of traffic summaries + pub tree: Option>, + /// CPU utiliation on the shaper + pub cpu_usage: Vec, + /// RAM utilization on the shaper + pub ram_percent: u32, +}