1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
use once_cell::sync::Lazy;
static LOC_EPOCH: Lazy<std::time::Instant> = Lazy::new(std::time::Instant::now);
const LAT_TAG: &[u8; 8] = &[0xff, 0xff, 0xff, 0xfe, 0xfe, 0xff, 0xff, 0xff];
pub fn fill_with_latency_info(buf: &mut [u8]) {
if buf.is_empty() {
return;
}
let epoch = *LOC_EPOCH;
let now = std::time::Instant::now();
let now = now.duration_since(epoch).as_secs_f64();
let mut pat = [0_u8; 16];
pat[0..8].copy_from_slice(LAT_TAG);
pat[8..16].copy_from_slice(&now.to_le_bytes());
let mut offset = 0;
while offset < buf.len() {
let len = std::cmp::min(pat.len(), buf.len() - offset);
buf[offset..offset + len].copy_from_slice(&pat[..len]);
offset += len;
}
}
#[allow(clippy::result_unit_err)]
pub fn parse_latency_info(buf: &[u8]) -> Result<std::time::Duration, ()> {
if buf.len() < 16 {
return Err(());
}
for i in 0..buf.len() - 15 {
if &buf[i..i + 8] == LAT_TAG {
let mut time = [0; 8];
time.copy_from_slice(&buf[i + 8..i + 16]);
let time = f64::from_le_bytes(time);
let now = std::time::Instant::now();
let now = now.duration_since(*LOC_EPOCH).as_secs_f64();
let time = std::time::Duration::from_secs_f64(now - time);
return Ok(time);
}
}
Err(())
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bad_latency_buffer_sizes() {
for i in 0..16 {
let mut buf = vec![0; i];
fill_with_latency_info(&mut buf);
assert!(parse_latency_info(&buf).is_err());
}
}
#[test]
fn test_bad_latency_buffer_data() {
assert!(parse_latency_info(&[0; 64]).is_err());
}
#[test]
fn test_good_latency_buffers() {
for i in 16..64 {
let mut buf = vec![0; i];
fill_with_latency_info(&mut buf);
let val = parse_latency_info(&buf).unwrap();
assert!(val.as_micros() < 10_000);
}
}
}