1use std::net::IpAddr;
2use std::time::{Duration, Instant};
3
4#[derive(Debug)]
5pub struct HostEntry {
6 pub display: String,
7 pub addr: IpAddr,
8 pub is_ipv6: bool,
9
10 pub num_sent: u32,
11 pub num_recv: u32,
12 pub max_reply: Option<Duration>,
13 pub min_reply: Option<Duration>,
14 pub total_time: Duration,
15
16 pub resp_times: Vec<Option<Duration>>,
17
18 pub last_send: Option<Instant>,
19 pub next_send: Instant,
20 pub retries_left: u32,
21 pub current_ping_index: u32,
22 pub done: bool,
23}
24
25impl HostEntry {
26 pub fn new(name: String, addr: IpAddr, is_ipv6: bool, count: u32) -> Self {
27 let display = name.clone();
28 HostEntry {
29 display,
30 addr,
31 is_ipv6,
32 num_sent: 0,
33 num_recv: 0,
34 max_reply: None,
35 min_reply: None,
36 total_time: Duration::ZERO,
37 resp_times: if count > 0 {
38 vec![None; count as usize]
39 } else {
40 Vec::new()
41 },
42 last_send: None,
43 next_send: Instant::now(),
44 retries_left: 0,
45 current_ping_index: 0,
46 done: false,
47 }
48 }
49
50 pub fn record_reply(&mut self, rtt: Duration, ping_index: u32) {
51 self.num_recv += 1;
52 self.total_time += rtt;
53 self.max_reply = Some(self.max_reply.map_or(rtt, |m| m.max(rtt)));
54 self.min_reply = Some(self.min_reply.map_or(rtt, |m| m.min(rtt)));
55 if let Some(slot) = self.resp_times.get_mut(ping_index as usize) {
56 *slot = Some(rtt);
57 }
58 }
59
60 pub fn avg_reply(&self) -> Option<Duration> {
61 (self.num_recv > 0).then(|| self.total_time / self.num_recv)
62 }
63
64 pub fn loss_pct(&self) -> u32 {
65 if self.num_sent == 0 {
66 0
67 } else {
68 ((self.num_sent - self.num_recv) * 100) / self.num_sent
69 }
70 }
71}
72
73pub struct PendingPing {
74 pub host_index: usize,
75 pub ping_index: u32,
76 pub sent_at: Instant,
77}