From f16014efbc6f57eca9fc039b275b75fc0743a7df Mon Sep 17 00:00:00 2001 From: Evan Cameron Date: Fri, 26 Jul 2024 00:38:13 -0400 Subject: [PATCH 1/2] experiment with jiff library for time --- Cargo.lock | 84 +++++++++++---------------------- Cargo.toml | 1 + dora-core/Cargo.toml | 3 +- dora-core/src/lib.rs | 3 +- dora-core/src/server/context.rs | 14 +++--- external-api/src/lib.rs | 2 +- libs/ip-manager/Cargo.toml | 2 +- libs/ip-manager/src/lib.rs | 18 ++++--- plugins/leases/src/lib.rs | 17 ++++--- 9 files changed, 59 insertions(+), 85 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index c09009a..4e217b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -434,34 +434,10 @@ checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", - "js-sys", "num-traits", - "wasm-bindgen", "windows-targets 0.52.5", ] -[[package]] -name = "chrono-tz" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "29c39203181991a7dd4343b8005bd804e7a9a37afb8ac070e43771e8c820bbde" -dependencies = [ - "chrono", - "chrono-tz-build", - "phf", -] - -[[package]] -name = "chrono-tz-build" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f509c3a87b33437b05e2458750a0700e5bdd6956176773e6c7d6dd15a283a0c" -dependencies = [ - "parse-zoneinfo", - "phf", - "phf_codegen", -] - [[package]] name = "ciborium" version = "0.2.2" @@ -942,12 +918,11 @@ dependencies = [ "anyhow", "async-trait", "bytes", - "chrono", - "chrono-tz", "clap 4.5.4", "dhcproto", "env-parser", "futures", + "jiff", "lazy_static", "libc", "pin-project", @@ -1685,11 +1660,11 @@ name = "ip-manager" version = "0.1.0" dependencies = [ "async-trait", - "chrono", "client-protection", "config", "icmp-ping", "ipnet", + "jiff", "moka", "rand", "sqlx", @@ -1774,6 +1749,32 @@ dependencies = [ "libc", ] +[[package]] +name = "jiff" +version = "0.1.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "52113e019082508e868f92202f6e55c690c69990b17c350db01813cdf1dc1b19" +dependencies = [ + "jiff-tzdb-platform", + "log", + "windows-sys 0.52.0", +] + +[[package]] +name = "jiff-tzdb" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "05fac328b3df1c0f18a3c2ab6cb7e06e4e549f366017d796e3e66b6d6889abe6" + +[[package]] +name = "jiff-tzdb-platform" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f8da387d5feaf355954c2c122c194d6df9c57d865125a67984bb453db5336940" +dependencies = [ + "jiff-tzdb", +] + [[package]] name = "js-sys" version = "0.3.69" @@ -2279,15 +2280,6 @@ dependencies = [ "windows-targets 0.48.5", ] -[[package]] -name = "parse-zoneinfo" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c705f256449c60da65e11ff6626e0c16a0a0b96aaa348de61376b249bc340f41" -dependencies = [ - "regex", -] - [[package]] name = "paste" version = "1.0.14" @@ -2355,16 +2347,6 @@ dependencies = [ "phf_shared", ] -[[package]] -name = "phf_codegen" -version = "0.11.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8d39688d359e6b34654d328e262234662d16cc0f60ec8dcbe5e718709342a5a" -dependencies = [ - "phf_generator", - "phf_shared", -] - [[package]] name = "phf_generator" version = "0.11.2" @@ -2395,7 +2377,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "90fcb95eef784c2ac79119d1dd819e162b5da872ce6f3c3abe1e8ca1c082f72b" dependencies = [ "siphasher", - "uncased", ] [[package]] @@ -3935,15 +3916,6 @@ version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ed646292ffc8188ef8ea4d1e0e0150fb15a5c2e12ad9b8fc191ae7a8a7f3c4b9" -[[package]] -name = "uncased" -version = "0.9.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1b88fcfe09e89d3866a5c11019378088af2d24c3fbd4f0543f96b479ec90697" -dependencies = [ - "version_check", -] - [[package]] name = "unicase" version = "2.7.0" diff --git a/Cargo.toml b/Cargo.toml index 610ef1d..522c4fb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -29,6 +29,7 @@ bytes = "1.1" clap = { version = "4.5.4", features = ["derive", "env"] } dhcproto = "0.11.0" futures = { version = "0.3", default-features = false, features = ["std"] } +jiff = { version = "0.1.1" } ipnet = { features = ["serde"], version = "2.4.0" } pnet = { features = ["serde", "std"], version = "0.34.0" } prometheus = "0.13.0" diff --git a/dora-core/Cargo.toml b/dora-core/Cargo.toml index ab47074..676d3ec 100644 --- a/dora-core/Cargo.toml +++ b/dora-core/Cargo.toml @@ -16,8 +16,7 @@ topo_sort = { path = "../libs/topo_sort" } async-trait = { workspace = true } anyhow = { workspace = true } bytes = { workspace = true } -chrono = "0.4" -chrono-tz = "0.6" +jiff = { workspace = true, features = ["logging"] } dhcproto = { workspace = true } futures = { workspace = true } lazy_static = "1.4" diff --git a/dora-core/src/lib.rs b/dora-core/src/lib.rs index ec219fc..2e59b4f 100644 --- a/dora-core/src/lib.rs +++ b/dora-core/src/lib.rs @@ -17,9 +17,8 @@ ))] pub use anyhow; pub use async_trait::async_trait; -pub use chrono; -pub use chrono_tz; pub use dhcproto; +pub use jiff; pub use pnet; pub use tokio; pub use tokio_stream; diff --git a/dora-core/src/server/context.rs b/dora-core/src/server/context.rs index cefa246..717b8b8 100644 --- a/dora-core/src/server/context.rs +++ b/dora-core/src/server/context.rs @@ -1,6 +1,6 @@ //! context of current server message -use chrono::{DateTime, Utc}; use dhcproto::{v4, v6, Decodable, Decoder, Encodable}; +use jiff::Zoned; use pnet::ipnetwork::{IpNetwork, Ipv4Network, Ipv6Network}; use tracing::{error, trace}; use unix_udp_sock::RecvMeta; @@ -32,7 +32,7 @@ pub struct MsgContext { /// address response sent to dst_addr: Option, /// time this context was created - time: DateTime, + time: Zoned, /// decoded from msg msg: T, /// decoded response msg -- **CAREFUL** do not call `take()` on this before @@ -108,11 +108,11 @@ impl MsgContext { self.msg_buf = msg; } - /// Get the `DateTime` that we first created this `MsgContext` + /// Get the date & time that we first created this `MsgContext` /// - /// [`DateTime`]: chrono::DateTime - pub fn time(&self) -> DateTime { - self.time + /// [`Zoned`]: jiff::zoned + pub fn time(&self) -> &Zoned { + &self.time } /// Store a value in the current `MsgContext` based on a type. @@ -206,7 +206,7 @@ impl MsgContext { src_addr: meta.addr, meta, dst_addr: None, - time: Utc::now(), + time: Zoned::now(), msg, type_map: TypeMap::new(), resp_msg: None, diff --git a/external-api/src/lib.rs b/external-api/src/lib.rs index ea2a65e..320e4ff 100644 --- a/external-api/src/lib.rs +++ b/external-api/src/lib.rs @@ -255,7 +255,7 @@ mod tests { let r = reqwest::get("http://0.0.0.0:8889/health") .await? .error_for_status(); - // initial health state will be BAD i.e. 500 + // initial health; state will be BAD i.e. 500 match r { Ok(_) => {} Err(err) => { diff --git a/libs/ip-manager/Cargo.toml b/libs/ip-manager/Cargo.toml index 32d1e7e..7d6427e 100644 --- a/libs/ip-manager/Cargo.toml +++ b/libs/ip-manager/Cargo.toml @@ -17,7 +17,7 @@ thiserror = { workspace = true } tracing = { workspace = true, features = [ "log", ] } # TODO: do we need the log feature? -chrono = "0.4.19" +jiff = { workspace = true } moka = { version = "0.10.0", features = ["future"] } # TODO: hopefully the rustls feature can go away, the lib requires it sqlx = { version = "0.5.13", features = [ diff --git a/libs/ip-manager/src/lib.rs b/libs/ip-manager/src/lib.rs index d7d6fa5..e6987f5 100644 --- a/libs/ip-manager/src/lib.rs +++ b/libs/ip-manager/src/lib.rs @@ -16,8 +16,6 @@ use config::v4::{NetRange, Network}; use icmp_ping::{Icmpv4, Listener, PingReply}; use async_trait::async_trait; -use chrono::DateTime; -use chrono::{offset::Utc, SecondsFormat}; use thiserror::Error; use tracing::{debug, error, info, trace, warn}; @@ -328,11 +326,17 @@ where // ping success so insert probated IP Err(err) => { let probation_time = SystemTime::now() + network.probation_period(); - info!( - ?err, - probation_time = %DateTime::::from(probation_time).to_rfc3339_opts(SecondsFormat::Secs, true), - "ping succeeded. address is in use. marking IP on probation" - ); + + if let Ok(probation_time) = + jiff::Timestamp::try_from(probation_time) + { + info!( + ?err, + probation_time = %probation_time.to_string(), + "ping succeeded. address is in use. marking IP on probation" + ); + } + // update regardless of expiry/id because something is using the IP if let Err(err) = self .store diff --git a/plugins/leases/src/lib.rs b/plugins/leases/src/lib.rs index 4140454..9866e9e 100644 --- a/plugins/leases/src/lib.rs +++ b/plugins/leases/src/lib.rs @@ -21,9 +21,8 @@ use client_protection::RenewThreshold; use ddns::{dhcid::DhcId, DdnsUpdate}; use dora_core::{ anyhow::anyhow, - chrono::{DateTime, SecondsFormat, Utc}, dhcproto::v4::{DhcpOption, Message, MessageType, OptionCode}, - metrics, + jiff, metrics, prelude::*, tracing::warn, }; @@ -217,7 +216,7 @@ where debug!( ?ip, ?client_id, - expires_at = %print_time(expires_at), + expires_at = ?print_time(expires_at), range = ?range.addrs(), subnet = ?network.subnet(), "reserved IP for client-- sending offer" @@ -248,7 +247,7 @@ where debug!( ?ip, ?client_id, - expires_at = %print_time(expires_at), + expires_at = ?print_time(expires_at), range = ?range.addrs(), subnet = ?network.subnet(), "reserved IP for client-- sending offer" @@ -350,7 +349,7 @@ where debug!( ?ip, ?client_id, - expires_at = %print_time(expires_at), + expires_at = ?print_time(expires_at), range = ?range.addrs(), subnet = ?network.subnet(), "sending LEASE" @@ -421,7 +420,7 @@ where self.cache_remove(ctx.msg().chaddr()); debug!( ?declined_ip, - expires_at = %print_time(expires_at), + expires_at = ?print_time(expires_at), "added declined IP with probation set" ); Ok(Action::Continue) @@ -432,8 +431,8 @@ where #[derive(Debug, Copy, Clone, PartialEq, Eq, Ord, PartialOrd, Hash)] pub struct ExpiresAt(pub SystemTime); -fn print_time(expires_at: SystemTime) -> String { - DateTime::::from(expires_at).to_rfc3339_opts(SecondsFormat::Secs, true) +fn print_time(expires_at: SystemTime) -> Result { + Ok(jiff::Timestamp::try_from(expires_at)?.to_string()) } /// If opt 61 (client id) exists return that, otherwise return `chaddr` from the message @@ -461,7 +460,7 @@ mod tests { #[test] fn test_time_print() { assert_eq!( - print_time(SystemTime::UNIX_EPOCH), + print_time(SystemTime::UNIX_EPOCH).unwrap(), "1970-01-01T00:00:00Z".to_owned() ); } From de8273726204602ba50a816685eae53dcb8e0819 Mon Sep 17 00:00:00 2001 From: Evan Cameron Date: Fri, 26 Jul 2024 00:56:11 -0400 Subject: [PATCH 2/2] add fields to v4 --- dora-core/src/server/context.rs | 4 ++-- dora-core/src/server/mod.rs | 10 ++++++++-- dora-core/src/server/state.rs | 8 ++++---- 3 files changed, 14 insertions(+), 8 deletions(-) diff --git a/dora-core/src/server/context.rs b/dora-core/src/server/context.rs index 717b8b8..71df220 100644 --- a/dora-core/src/server/context.rs +++ b/dora-core/src/server/context.rs @@ -41,7 +41,7 @@ pub struct MsgContext { /// a type map for use by plugins to store values type_map: TypeMap, /// unique id we assign to each `MsgContext` - id: usize, + id: u64, /// reference to `State` state: Arc, /// whether the `MsgContext` counts towards `state.live_msgs` @@ -79,7 +79,7 @@ impl Drop for MsgContext { impl MsgContext { /// Get the id - pub fn id(&self) -> usize { + pub fn id(&self) -> u64 { self.id } diff --git a/dora-core/src/server/mod.rs b/dora-core/src/server/mod.rs index ad6917c..6c3b7f5 100644 --- a/dora-core/src/server/mod.rs +++ b/dora-core/src/server/mod.rs @@ -220,7 +220,10 @@ struct RunInner { impl RunInner { /// Process handlers - #[instrument(name = "v4", level = "debug", skip_all)] + #[instrument(name = "v4", level = "debug", fields( + id = self.ctx.id(), + ifindex = self.ctx.meta().ifindex + ), skip_all)] async fn run(mut self) -> Result<()> { let start = Instant::now(); if let Err(err) = self.ctx.recv_metrics() { @@ -328,7 +331,10 @@ impl RunTask { impl RunInner { /// Process handlers - #[instrument(name = "v6", level = "debug", skip_all)] + #[instrument(name = "v6", level = "debug", fields( + id = self.ctx.id(), + ifindex = self.ctx.meta().ifindex + ), skip_all)] async fn run(mut self) -> Result<()> { let start = Instant::now(); if let Err(err) = self.ctx.recv_metrics() { diff --git a/dora-core/src/server/state.rs b/dora-core/src/server/state.rs index 9ec956e..4f69a44 100644 --- a/dora-core/src/server/state.rs +++ b/dora-core/src/server/state.rs @@ -3,7 +3,7 @@ use tokio::sync::Semaphore; use std::sync::{ - atomic::{AtomicUsize, Ordering}, + atomic::{AtomicU64, Ordering}, Arc, }; @@ -17,7 +17,7 @@ pub struct State { /// max live message count live_limit: usize, /// id to assign incoming messages - next_id: AtomicUsize, + next_id: AtomicU64, } impl State { @@ -26,7 +26,7 @@ impl State { State { live_msgs: Arc::new(Semaphore::new(max_live)), live_limit: max_live, - next_id: AtomicUsize::new(0), + next_id: AtomicU64::new(0), } } @@ -58,7 +58,7 @@ impl State { /// Increment the context id #[inline] - pub fn inc_id(&self) -> usize { + pub fn inc_id(&self) -> u64 { self.next_id.fetch_add(1, Ordering::Acquire) }