1use std::sync::atomic::{AtomicUsize, Ordering};
6use std::time::Duration;
7
8use diagnostics_traits::{InspectableValue, Inspector};
9
10use crate::parse::{IncomingResponseToRequestErrorCounters, SelectingIncomingMessageErrorCounters};
11
12#[derive(Default, Debug)]
14pub(crate) struct Counter(AtomicUsize);
15
16impl Counter {
17 pub(crate) fn increment(&self) {
18 let _: usize = self.0.fetch_add(1, Ordering::Relaxed);
19 }
20
21 pub(crate) fn load(&self) -> usize {
22 self.0.load(Ordering::Relaxed)
23 }
24}
25
26impl InspectableValue for Counter {
27 fn record<I: diagnostics_traits::Inspector>(&self, name: &str, inspector: &mut I) {
28 inspector.record_uint(name, u64::try_from(self.load()).unwrap_or(u64::MAX));
29 }
30}
31
32pub(crate) fn record_optional_duration_secs(
33 inspector: &mut impl Inspector,
34 name: &str,
35 value: Option<Duration>,
36) {
37 match value {
38 Some(value) => inspector.record_uint(name, value.as_secs()),
39 None => inspector.record_display(name, "Unset"),
40 }
41}
42
43#[derive(Debug, Default)]
45pub(crate) struct MessagingRelatedCounters {
46 pub(crate) send_message: Counter,
48 pub(crate) recv_message: Counter,
50 pub(crate) recv_message_fatal_socket_error: Counter,
53 pub(crate) recv_message_non_fatal_socket_error: Counter,
56 pub(crate) recv_time_out: Counter,
59 pub(crate) recv_wrong_xid: Counter,
62 pub(crate) recv_wrong_chaddr: Counter,
65 pub(crate) recv_failed_dhcp_parse: Counter,
68 pub(crate) recv_ack_no_addr_lease_time: Counter,
71}
72
73impl MessagingRelatedCounters {
74 fn record(&self, inspector: &mut impl Inspector) {
75 let Self {
76 send_message,
77 recv_message,
78 recv_message_fatal_socket_error,
79 recv_message_non_fatal_socket_error,
80 recv_time_out,
81 recv_wrong_xid,
82 recv_wrong_chaddr,
83 recv_failed_dhcp_parse,
84 recv_ack_no_addr_lease_time,
85 } = self;
86 inspector.record_inspectable_value("SendMessage", send_message);
87 inspector.record_inspectable_value("RecvMessage", recv_message);
88 inspector.record_inspectable_value(
89 "RecvMessageFatalSocketError",
90 recv_message_fatal_socket_error,
91 );
92 inspector.record_inspectable_value(
93 "RecvMessageNonFatalSocketError",
94 recv_message_non_fatal_socket_error,
95 );
96 inspector.record_inspectable_value("RecvTimeOut", recv_time_out);
97 inspector.record_inspectable_value("RecvWrongXid", recv_wrong_xid);
98 inspector.record_inspectable_value("RecvWrongChaddr", recv_wrong_chaddr);
99 inspector.record_inspectable_value("RecvFailedDhcpParse", recv_failed_dhcp_parse);
100 inspector.record_inspectable_value("NoLeaseTime", recv_ack_no_addr_lease_time);
101 }
102}
103
104#[derive(Debug, Default)]
106pub(crate) struct InitCounters {
107 pub(crate) entered: Counter,
109}
110
111impl InitCounters {
112 fn record(&self, inspector: &mut impl Inspector) {
113 let Self { entered } = self;
114 inspector.record_inspectable_value("Entered", entered);
115 }
116}
117
118#[derive(Debug, Default)]
120pub(crate) struct SelectingCounters {
121 pub(crate) entered: Counter,
123 pub(crate) messaging: MessagingRelatedCounters,
125 pub(crate) recv_error: SelectingIncomingMessageErrorCounters,
128}
129
130impl SelectingCounters {
131 fn record(&self, inspector: &mut impl Inspector) {
132 let Self { entered, messaging, recv_error } = self;
133 inspector.record_inspectable_value("Entered", entered);
134 messaging.record(inspector);
135 recv_error.record(inspector);
136 }
137}
138
139#[derive(Debug, Default)]
141pub(crate) struct RequestingCounters {
142 pub(crate) entered: Counter,
144 pub(crate) messaging: MessagingRelatedCounters,
146 pub(crate) recv_error: IncomingResponseToRequestErrorCounters,
149 pub(crate) recv_nak: Counter,
152}
153
154impl RequestingCounters {
155 fn record(&self, inspector: &mut impl Inspector) {
156 let Self { entered, messaging, recv_error, recv_nak } = self;
157 inspector.record_inspectable_value("Entered", entered);
158 messaging.record(inspector);
159 recv_error.record(inspector);
160 inspector.record_inspectable_value("RecvNak", recv_nak);
161 }
162}
163
164#[derive(Debug, Default)]
166pub(crate) struct BoundCounters {
167 pub(crate) entered: Counter,
169 pub(crate) assigned: Counter,
171}
172
173impl BoundCounters {
174 fn record(&self, inspector: &mut impl Inspector) {
175 let Self { entered, assigned } = self;
176 inspector.record_inspectable_value("Entered", entered);
177 inspector.record_inspectable_value("Assigned", assigned);
178 }
179}
180
181#[derive(Debug, Default)]
183pub(crate) struct RenewingCounters {
184 pub(crate) entered: Counter,
186 pub(crate) messaging: MessagingRelatedCounters,
188 pub(crate) recv_error: IncomingResponseToRequestErrorCounters,
191 pub(crate) recv_nak: Counter,
194}
195
196impl RenewingCounters {
197 fn record(&self, inspector: &mut impl Inspector) {
198 let Self { entered, messaging, recv_error, recv_nak } = self;
199 inspector.record_inspectable_value("Entered", entered);
200 messaging.record(inspector);
201 recv_error.record(inspector);
202 inspector.record_inspectable_value("RecvNak", recv_nak);
203 }
204}
205
206#[derive(Debug, Default)]
208pub(crate) struct RebindingCounters {
209 pub(crate) entered: Counter,
211 pub(crate) messaging: MessagingRelatedCounters,
213 pub(crate) recv_error: IncomingResponseToRequestErrorCounters,
216 pub(crate) recv_nak: Counter,
219}
220
221impl RebindingCounters {
222 fn record(&self, inspector: &mut impl Inspector) {
223 let Self { entered, messaging, recv_error, recv_nak } = self;
224 inspector.record_inspectable_value("Entered", entered);
225 messaging.record(inspector);
226 recv_error.record(inspector);
227 inspector.record_inspectable_value("RecvNak", recv_nak);
228 }
229}
230
231#[derive(Debug, Default)]
233pub(crate) struct WaitingToRestartCounters {
234 pub(crate) entered: Counter,
236}
237
238impl WaitingToRestartCounters {
239 fn record(&self, inspector: &mut impl Inspector) {
240 let Self { entered } = self;
241 inspector.record_inspectable_value("Entered", entered);
242 }
243}
244
245#[derive(Default, Debug)]
247pub struct Counters {
248 pub(crate) init: InitCounters,
249 pub(crate) selecting: SelectingCounters,
250 pub(crate) requesting: RequestingCounters,
251 pub(crate) bound: BoundCounters,
252 pub(crate) renewing: RenewingCounters,
253 pub(crate) rebinding: RebindingCounters,
254 pub(crate) waiting_to_restart: WaitingToRestartCounters,
255}
256
257impl Counters {
258 pub fn record(&self, inspector: &mut impl Inspector) {
260 let Self { init, selecting, requesting, bound, renewing, rebinding, waiting_to_restart } =
261 self;
262 inspector.record_child("Init", |inspector| {
263 init.record(inspector);
264 });
265 inspector.record_child("Selecting", |inspector| {
266 selecting.record(inspector);
267 });
268 inspector.record_child("Requesting", |inspector| {
269 requesting.record(inspector);
270 });
271 inspector.record_child("Bound", |inspector| {
272 bound.record(inspector);
273 });
274 inspector.record_child("Renewing", |inspector| {
275 renewing.record(inspector);
276 });
277 inspector.record_child("Rebinding", |inspector| {
278 rebinding.record(inspector);
279 });
280 inspector.record_child("WaitingToRestart", |inspector| {
281 waiting_to_restart.record(inspector);
282 });
283 }
284}