Allow one-way delay samples to represent negative values caused by wall-clock skew between client and server. Update CLI output and statistics collection to correctly handle and report these signed durations.
128 lines
3.6 KiB
Rust
128 lines
3.6 KiB
Rust
use std::time::{Duration, Instant, UNIX_EPOCH};
|
|
|
|
use irtt_client::{
|
|
ClientEvent, ClientTimestamp, OneWayDelaySample, PacketMeta, ReceivedStatsSample, RttSample,
|
|
ServerTiming, SignedDuration,
|
|
};
|
|
|
|
pub fn ts(ms: u64) -> ClientTimestamp {
|
|
ClientTimestamp {
|
|
mono: Instant::now() + Duration::from_millis(ms),
|
|
wall: UNIX_EPOCH + Duration::from_millis(ms),
|
|
}
|
|
}
|
|
|
|
pub fn adjusted_rtt(raw_ms: u64, adjusted_ms: i128) -> RttSample {
|
|
let adjusted = SignedDuration::from_nanos(adjusted_ms * 1_000_000);
|
|
RttSample {
|
|
raw: Duration::from_millis(raw_ms),
|
|
adjusted: Some(adjusted),
|
|
effective: adjusted,
|
|
}
|
|
}
|
|
|
|
pub fn unadjusted_rtt(raw_ms: u64) -> RttSample {
|
|
let raw = Duration::from_millis(raw_ms);
|
|
RttSample {
|
|
raw,
|
|
adjusted: None,
|
|
effective: SignedDuration::from_duration(raw),
|
|
}
|
|
}
|
|
|
|
pub fn sent(seq: u32, sent_at: ClientTimestamp) -> ClientEvent {
|
|
ClientEvent::EchoSent {
|
|
seq,
|
|
remote: "127.0.0.1:2112".parse().unwrap(),
|
|
scheduled_at: sent_at.mono,
|
|
sent_at,
|
|
bytes: 32,
|
|
send_call: Duration::from_micros(10),
|
|
timer_error: Duration::from_micros(2),
|
|
}
|
|
}
|
|
|
|
pub fn adjusted_reply(seq: u32, raw_ms: u64, adjusted_ms: i128) -> ClientEvent {
|
|
reply_with_rtt(seq, raw_ms, adjusted_rtt(raw_ms, adjusted_ms))
|
|
}
|
|
|
|
pub fn unadjusted_reply(seq: u32, raw_ms: u64) -> ClientEvent {
|
|
reply_with_rtt(seq, raw_ms, unadjusted_rtt(raw_ms))
|
|
}
|
|
|
|
fn reply_with_rtt(seq: u32, raw_ms: u64, rtt: RttSample) -> ClientEvent {
|
|
let sent_at = ts(seq as u64 * 10);
|
|
let received_at = ClientTimestamp {
|
|
mono: sent_at.mono + Duration::from_millis(raw_ms),
|
|
wall: sent_at.wall + Duration::from_millis(raw_ms),
|
|
};
|
|
ClientEvent::EchoReply {
|
|
seq,
|
|
remote: "127.0.0.1:2112".parse().unwrap(),
|
|
sent_at,
|
|
received_at,
|
|
rtt,
|
|
server_timing: Some(ServerTiming {
|
|
receive_wall_ns: Some(unix_time_ns_after_epoch(sent_at.wall) as i64 + 1_000_000),
|
|
receive_mono_ns: Some(seq as i64 * 10_000_000 + 1_000_000),
|
|
send_wall_ns: Some(unix_time_ns_after_epoch(sent_at.wall) as i64 + 2_000_000),
|
|
send_mono_ns: Some(seq as i64 * 10_000_000 + 2_000_000),
|
|
midpoint_wall_ns: None,
|
|
midpoint_mono_ns: None,
|
|
processing: Some(Duration::from_millis(1)),
|
|
}),
|
|
one_way: Some(OneWayDelaySample {
|
|
client_to_server: Some(SignedDuration::from_nanos(1_000_000)),
|
|
server_to_client: Some(SignedDuration::from_nanos(2_000_000)),
|
|
}),
|
|
received_stats: Some(ReceivedStatsSample {
|
|
count: Some(seq + 1),
|
|
window: Some(0xff),
|
|
}),
|
|
bytes: 64,
|
|
packet_meta: PacketMeta::default(),
|
|
}
|
|
}
|
|
|
|
pub fn unadjusted_late_reply(seq: u32, raw_ms: u64) -> ClientEvent {
|
|
late_reply_from(unadjusted_reply(seq, raw_ms))
|
|
}
|
|
|
|
fn late_reply_from(reply: ClientEvent) -> ClientEvent {
|
|
let ClientEvent::EchoReply {
|
|
seq,
|
|
remote,
|
|
sent_at,
|
|
received_at,
|
|
rtt,
|
|
server_timing,
|
|
one_way,
|
|
received_stats,
|
|
bytes,
|
|
packet_meta,
|
|
..
|
|
} = reply
|
|
else {
|
|
unreachable!();
|
|
};
|
|
ClientEvent::LateReply {
|
|
seq,
|
|
highest_seen: seq + 1,
|
|
remote,
|
|
sent_at: Some(sent_at),
|
|
received_at,
|
|
rtt: Some(rtt),
|
|
server_timing,
|
|
one_way,
|
|
received_stats,
|
|
bytes,
|
|
packet_meta,
|
|
}
|
|
}
|
|
|
|
fn unix_time_ns_after_epoch(time: std::time::SystemTime) -> i128 {
|
|
time.duration_since(UNIX_EPOCH)
|
|
.map(|duration| duration.as_nanos() as i128)
|
|
.unwrap()
|
|
}
|