3 Commits
Author SHA1 Message Date
renovate Bot 305a182001 chore(deps): update rust crate config to v0.15.27
Rust CI / cargo fmt (pull_request) Successful in 11s
Rust CI / cargo clippy (pull_request) Failing after 26s
Rust CI / cargo check (x86_64-unknown-linux-gnu) (pull_request) Failing after 27s
Rust CI / cargo check (x86_64-unknown-linux-musl) (pull_request) Failing after 8s
Rust CI / cargo test (x86_64-unknown-linux-gnu) (pull_request) Failing after 33s
Rust CI / cargo test (x86_64-unknown-linux-musl) (pull_request) Failing after 7s
Supply chain / actionlint (pull_request) Successful in 17s
Rust CI / cargo doc (pull_request) Successful in 40s
Supply chain / cargo-deny advisories (pull_request) Failing after 1m49s
Supply chain / cargo-deny bans licenses sources (pull_request) Failing after 1m49s
Rust CI / cargo fmt (push) Successful in 18s
Rust CI / cargo check (x86_64-unknown-linux-gnu) (push) Failing after 38s
Rust CI / cargo clippy (push) Failing after 38s
Rust CI / cargo check (x86_64-unknown-linux-musl) (push) Failing after 8s
Rust CI / cargo test (x86_64-unknown-linux-gnu) (push) Failing after 42s
Rust CI / cargo test (x86_64-unknown-linux-musl) (push) Failing after 8s
Supply chain / actionlint (push) Successful in 8s
Rust CI / cargo doc (push) Successful in 40s
Supply chain / cargo-deny bans licenses sources (push) Failing after 1m52s
Supply chain / cargo-deny advisories (push) Failing after 1m54s
2026-09-30 08:33:02 +00:00
Nils Andreas Svee 64e002c0d0 chore(deps): update rust crate icmp-socket2 to v0.6.4
Rust CI / cargo fmt (push) Successful in 17s
Rust CI / cargo check (x86_64-unknown-linux-gnu) (push) Failing after 40s
Rust CI / cargo clippy (push) Failing after 40s
Rust CI / cargo test (x86_64-unknown-linux-gnu) (push) Failing after 45s
Rust CI / cargo check (x86_64-unknown-linux-musl) (push) Failing after 7s
Rust CI / cargo test (x86_64-unknown-linux-musl) (push) Failing after 8s
Rust CI / cargo doc (push) Successful in 33s
Supply chain / actionlint (push) Successful in 11s
Supply chain / cargo-deny advisories (push) Failing after 1m51s
Supply chain / cargo-deny bans licenses sources (push) Failing after 1m44s
2026-09-30 15:32:22 +07:00
Nils Andreas Svee 817cc304e6 refactor(time): Introduce typed clock sources for compile-time safety
This change replaces runtime `ClockId` parameters with distinct types to ensure correct clock usage at compile time.
2026-09-30 12:05:42 +07:00
8 changed files with 86 additions and 31 deletions

No files matched your search

Generated
+39 -4
View File
@@ -17,6 +17,12 @@ version = "1.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470" checksum = "330a5ed07fa54e4702c9d6c4174f74427fc0ef6e214bbd677ae50a5099946470"
[[package]]
name = "autocfg"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f2032f911046de80f0a198e0901378627c33f59ea0ac00e363d481118bd70a53"
[[package]] [[package]]
name = "bindgen" name = "bindgen"
version = "0.72.1" version = "0.72.1"
@@ -74,6 +80,12 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
[[package]]
name = "cfg_aliases"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f079e83a288787bcd14a6aea84cee5c87a67c5a3e660c30f557a3d24761b3527"
[[package]] [[package]]
name = "clang-sys" name = "clang-sys"
version = "1.8.1" version = "1.8.1"
@@ -96,9 +108,9 @@ dependencies = [
[[package]] [[package]]
name = "config" name = "config"
version = "0.15.26" version = "0.15.27"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "790374c727a4cb20877dd2cc99ce7011cbe03b0b8df083acccd37df0d161304d" checksum = "38e9fbc53afcec54441422f1c596cd054655b32e70e1cbac956651b7b175a404"
dependencies = [ dependencies = [
"pathdiff", "pathdiff",
"serde_core", "serde_core",
@@ -201,10 +213,11 @@ checksum = "ed5909b6e89a2db4456e54cd5f673791d7eca6732202bbf2a9cc504fe2f9b84a"
[[package]] [[package]]
name = "icmp-socket2" name = "icmp-socket2"
version = "0.6.2" version = "0.6.4"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40c33803cfc44be36d1ce109e43f847063c35bdd11657c913c85536cb88c1e8c" checksum = "816dc56a4f7f76e42b0616818600b05528cd346cb3843276e82df982d5c3ee26"
dependencies = [ dependencies = [
"nix",
"socket2", "socket2",
"thiserror", "thiserror",
] ]
@@ -297,6 +310,15 @@ version = "2.8.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98" checksum = "cf8baf1c55e62ffcace7a9f06f4bd9cd3f0c4beb022d3b367256b91b87513d98"
[[package]]
name = "memoffset"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a"
dependencies = [
"autocfg",
]
[[package]] [[package]]
name = "minimal-lexical" name = "minimal-lexical"
version = "0.2.1" version = "0.2.1"
@@ -320,6 +342,19 @@ dependencies = [
"strip-async", "strip-async",
] ]
[[package]]
name = "nix"
version = "0.31.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf20d2fde8ff38632c426f1165ed7436270b44f199fc55284c38276f9db47c3d"
dependencies = [
"bitflags",
"cfg-if",
"cfg_aliases",
"libc",
"memoffset",
]
[[package]] [[package]]
name = "nom" name = "nom"
version = "7.1.3" version = "7.1.3"
+1 -1
View File
@@ -20,7 +20,7 @@ strip = "symbols"
[dependencies] [dependencies]
anyhow = "1.0" anyhow = "1.0"
icmp-socket2 = "0.6.2" icmp-socket2 = "0.6.4"
fastrand = "2" fastrand = "2"
rustix = { version = "1.1", features = ["fs", "system", "thread", "time"] } rustix = { version = "1.1", features = ["fs", "system", "thread", "time"] }
thiserror = "2.0" thiserror = "2.0"
+2 -3
View File
@@ -3,9 +3,8 @@
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use log::{Level, Metadata, Record, SetLoggerError}; use log::{Level, Metadata, Record, SetLoggerError};
use rustix::time::ClockId;
use crate::time::Time; use crate::time::{ClockSample, Realtime};
#[derive(Clone, Copy)] #[derive(Clone, Copy)]
pub struct SimpleLogger { pub struct SimpleLogger {
@@ -19,7 +18,7 @@ impl log::Log for SimpleLogger {
fn log(&self, record: &Record) { fn log(&self, record: &Record) {
if self.enabled(record.metadata()) { if self.enabled(record.metadata()) {
let now = Time::new(ClockId::Realtime); let now = ClockSample::<Realtime>::now();
println!( println!(
"{} {:5} {}:{}: {}", "{} {:5} {}:{}: {}",
now.as_secs_f64(), now.as_secs_f64(),
+3 -3
View File
@@ -4,7 +4,7 @@
use crate::settings::Settings; use crate::settings::Settings;
use crate::settings::{MeasurementType, ObservabilityProtocol}; use crate::settings::{MeasurementType, ObservabilityProtocol};
use crate::time::Time; use crate::time::{ClockSample, Realtime};
use flume::{Receiver, RecvTimeoutError, Sender}; use flume::{Receiver, RecvTimeoutError, Sender};
use log::{error, info, warn}; use log::{error, info, warn};
use rustix::time::ClockId; use rustix::time::ClockId;
@@ -148,7 +148,7 @@ impl MetricsSender {
pub fn send(&self, metric: Metric) { pub fn send(&self, metric: Metric) {
if let Some(ref tx) = self.tx { if let Some(ref tx) = self.tx {
let ts = Time::new(ClockId::Realtime).as_nanos(); let ts = ClockSample::<Realtime>::now().as_nanos();
if tx.try_send((metric, ts)).is_err() { if tx.try_send((metric, ts)).is_err() {
self.dropped.fetch_add(1, Ordering::Relaxed); self.dropped.fetch_add(1, Ordering::Relaxed);
} }
@@ -197,7 +197,7 @@ impl Metrics {
Err(RecvTimeoutError::Timeout) => { Err(RecvTimeoutError::Timeout) => {
let dropped = self.metrics_dropped.swap(0, Ordering::Relaxed); let dropped = self.metrics_dropped.swap(0, Ordering::Relaxed);
if dropped > 0 { if dropped > 0 {
let ts = Time::new(ClockId::Realtime).as_nanos(); let ts = ClockSample::<Realtime>::now().as_nanos();
batch.push((Metric::Dropped { count: dropped }, ts)); batch.push((Metric::Dropped { count: dropped }, ts));
} }
if !batch.is_empty() { if !batch.is_empty() {
+3 -3
View File
@@ -10,7 +10,7 @@ use std::time::Instant;
use crate::pinger::{PingError, PingListener, PingReply, PingSender}; use crate::pinger::{PingError, PingListener, PingReply, PingSender};
use crate::settings::MeasurementType; use crate::settings::MeasurementType;
use crate::time::Time; use crate::time::{ClockSample, Monotonic};
use icmp_socket2::Icmpv4Message; use icmp_socket2::Icmpv4Message;
use icmp_socket2::Icmpv4Packet; use icmp_socket2::Icmpv4Packet;
use icmp_socket2::packet::WithEchoRequest; use icmp_socket2::packet::WithEchoRequest;
@@ -54,7 +54,7 @@ impl PingListener for PingerICMPEchoListener {
} }
}; };
let clock = Time::new(ClockId::Monotonic); let clock = ClockSample::<Monotonic>::now();
let time_ms = clock.to_milliseconds() as i64; let time_ms = clock.to_milliseconds() as i64;
let rtt = (time_ms - time_sent) as f64; let rtt = (time_ms - time_sent) as f64;
@@ -85,7 +85,7 @@ impl PingListener for PingerICMPEchoListener {
impl PingSender for PingerICMPEchoSender { impl PingSender for PingerICMPEchoSender {
fn craft_packet(&self, id: u16, seq: u16) -> (Icmpv4Packet, i64) { fn craft_packet(&self, id: u16, seq: u16) -> (Icmpv4Packet, i64) {
let clock = Time::new(ClockId::Monotonic); let clock = ClockSample::<Monotonic>::now();
let time_ms = clock.to_milliseconds(); let time_ms = clock.to_milliseconds();
let payload = time_ms.to_be_bytes().to_vec(); let payload = time_ms.to_be_bytes().to_vec();
+3 -3
View File
@@ -7,7 +7,7 @@
use crate::pinger::{PingError, PingListener, PingReply, PingSender}; use crate::pinger::{PingError, PingListener, PingReply, PingSender};
use crate::settings::MeasurementType; use crate::settings::MeasurementType;
use crate::time::Time; use crate::time::{ClockSample, Realtime};
use icmp_socket2::Icmpv4Message; use icmp_socket2::Icmpv4Message;
use icmp_socket2::Icmpv4Packet; use icmp_socket2::Icmpv4Packet;
use icmp_socket2::packet::WithTimestampRequest; use icmp_socket2::packet::WithTimestampRequest;
@@ -66,7 +66,7 @@ impl PingListener for PingerICMPTimestampListener {
} }
let time_since_midnight = let time_since_midnight =
Time::new(ClockId::Realtime).get_time_since_midnight(); ClockSample::<Realtime>::now().as_time_since_midnight();
let rtt = timestamp_delta(time_since_midnight, originate as i64) as f64; let rtt = timestamp_delta(time_since_midnight, originate as i64) as f64;
let dl_time = timestamp_delta(time_since_midnight, transmit as i64) as f64; let dl_time = timestamp_delta(time_since_midnight, transmit as i64) as f64;
@@ -99,7 +99,7 @@ impl PingListener for PingerICMPTimestampListener {
impl PingSender for PingerICMPTimestampSender { impl PingSender for PingerICMPTimestampSender {
fn craft_packet(&self, id: u16, seq: u16) -> (Icmpv4Packet, i64) { fn craft_packet(&self, id: u16, seq: u16) -> (Icmpv4Packet, i64) {
let time_since_midnight = Time::new(ClockId::Realtime).get_time_since_midnight(); let time_since_midnight = ClockSample::<Realtime>::now().as_time_since_midnight();
( (
Icmpv4Packet::with_timestamp_request(id, seq, time_since_midnight as u32, 0, 0) Icmpv4Packet::with_timestamp_request(id, seq, time_since_midnight as u32, 0, 0)
.unwrap(), .unwrap(),
+3 -3
View File
@@ -13,7 +13,7 @@ use crate::platform::{
interface_stats_provider, traffic_control_backend, interface_stats_provider, traffic_control_backend,
}; };
use crate::settings::Settings; use crate::settings::Settings;
use crate::time::Time; use crate::time::{ClockSample, Realtime};
use crate::util::{ArcRwLock, RwLockExt}; use crate::util::{ArcRwLock, RwLockExt};
use flume::{Receiver, Sender}; use flume::{Receiver, Sender};
use log::{debug, info, warn}; use log::{debug, info, warn};
@@ -409,7 +409,7 @@ impl<S: InterfaceStatsProvider, T: TrafficControlBackend> Ratecontroller<S, T> {
self.state_dl.current_rate = self.state_dl.next_rate; self.state_dl.current_rate = self.state_dl.next_rate;
self.state_ul.current_rate = self.state_ul.next_rate; self.state_ul.current_rate = self.state_ul.next_rate;
let stats_time = Time::new(ClockId::Realtime); let stats_time = ClockSample::<Realtime>::now();
debug!( debug!(
"{},{},{},{},{},{},{},{}", "{},{},{},{},{},{},{},{}",
stats_time.secs(), stats_time.secs(),
@@ -459,7 +459,7 @@ impl<S: InterfaceStatsProvider, T: TrafficControlBackend> Ratecontroller<S, T> {
&& now_t.duration_since(lastdump_t).as_secs_f64() > 300.0 && now_t.duration_since(lastdump_t).as_secs_f64() > 300.0
{ {
for i in 0..self.settings.advanced_settings.speed_hist_size as usize { for i in 0..self.settings.advanced_settings.speed_hist_size as usize {
let hist_time = Time::new(ClockId::Realtime); let hist_time = ClockSample::<Realtime>::now();
if let Err(e) = fd.write_all( if let Err(e) = fd.write_all(
format!( format!(
"{},{},{},{}\n", "{},{},{},{}\n",
+32 -11
View File
@@ -2,27 +2,42 @@
// //
// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: MPL-2.0
use rustix::fs::Timespec; use std::marker::PhantomData;
use rustix::time::{ClockId, clock_gettime}; use rustix::time::{ClockId, clock_gettime};
pub struct Time { trait Clock {
time_s: u64, const ID: ClockId;
time_ns: u64,
} }
impl Time { pub enum Realtime {}
pub fn new(id: ClockId) -> Self { pub enum Monotonic {}
let time: Timespec = clock_gettime(id);
impl Clock for Realtime {
const ID: ClockId = ClockId::Realtime;
}
impl Clock for Monotonic {
const ID: ClockId = ClockId::Monotonic;
}
pub struct ClockSample<C> {
time_s: u64,
time_ns: u64,
_clock: PhantomData<C>,
}
impl<C: Clock> ClockSample<C> {
pub fn now() -> Self {
let time = clock_gettime(C::ID);
Self { Self {
time_s: time.tv_sec as u64, time_s: time.tv_sec as u64,
time_ns: time.tv_nsec as u64, time_ns: time.tv_nsec as u64,
_clock: PhantomData,
} }
} }
pub fn get_time_since_midnight(&self) -> i64 {
(self.time_s as i64 % 86400 * 1000) + (self.time_ns as i64 / 1000000)
}
pub fn secs(&self) -> u64 { pub fn secs(&self) -> u64 {
self.time_s self.time_s
} }
@@ -43,3 +58,9 @@ impl Time {
(self.time_s * 1000) + (self.time_ns / 1000000) (self.time_s * 1000) + (self.time_ns / 1000000)
} }
} }
impl ClockSample<Realtime> {
pub fn as_time_since_midnight(&self) -> i64 {
(self.time_s as i64 % 86_400 * 1000) + self.time_ns as i64 / 1_000_000
}
}