1use std::sync::atomic::{AtomicUsize, Ordering};
6
7use diagnostics_traits::{InspectableValue, Inspector};
8
9use crate::parse::{
10 IncomingResponseToRequestErrorCounters, SelectingIncomingMessageErrorCounters, SoftParseErrors,
11};
12
13#[derive(Default, Debug)]
15pub(crate) struct Counter(AtomicUsize);
16
17impl Counter {
18 pub(crate) fn increment(&self) {
19 let _: usize = self.0.fetch_add(1, Ordering::Relaxed);
20 }
21
22 pub(crate) fn load(&self) -> usize {
23 self.0.load(Ordering::Relaxed)
24 }
25}
26
27impl InspectableValue for Counter {
28 fn record<I: diagnostics_traits::Inspector>(&self, name: &str, inspector: &mut I) {
29 inspector.record_uint(name, u64::try_from(self.load()).unwrap_or(u64::MAX));
30 }
31}
32
33#[derive(Debug, Default)]
35pub(crate) struct MessagingRelatedCounters {
36 pub(crate) send_message: Counter,
38 pub(crate) recv_message: Counter,
40 pub(crate) recv_message_fatal_socket_error: Counter,
43 pub(crate) recv_message_non_fatal_socket_error: Counter,
46 pub(crate) recv_time_out: Counter,
49 pub(crate) recv_wrong_xid: Counter,
52 pub(crate) recv_wrong_chaddr: Counter,
55 pub(crate) recv_failed_dhcp_parse: Counter,
58 pub(crate) recv_ack_no_addr_lease_time: Counter,
61 pub(crate) recv_ack_renewal_time_after_rebinding_time: Counter,
63 pub(crate) recv_ack_rebinding_time_outlives_lease: Counter,
65 pub(crate) recv_illegal_option: Counter,
68}
69
70impl MessagingRelatedCounters {
71 fn record(&self, inspector: &mut impl Inspector) {
72 let Self {
73 send_message,
74 recv_message,
75 recv_message_fatal_socket_error,
76 recv_message_non_fatal_socket_error,
77 recv_time_out,
78 recv_wrong_xid,
79 recv_wrong_chaddr,
80 recv_failed_dhcp_parse,
81 recv_ack_no_addr_lease_time,
82 recv_ack_renewal_time_after_rebinding_time,
83 recv_ack_rebinding_time_outlives_lease,
84 recv_illegal_option,
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 inspector.record_inspectable_value(
102 "RenewalTimeAfterRebindingTime",
103 recv_ack_renewal_time_after_rebinding_time,
104 );
105 inspector.record_inspectable_value(
106 "RebindingTimeOutlivesLease",
107 recv_ack_rebinding_time_outlives_lease,
108 );
109 inspector.record_inspectable_value("IllegallyIncludedOption", recv_illegal_option);
110 }
111
112 pub(crate) fn increment_soft_errors(&self, soft_errors: SoftParseErrors) {
113 let SoftParseErrors { illegal_option } = soft_errors;
114 if illegal_option {
115 self.recv_illegal_option.increment()
116 }
117 }
118}
119
120#[derive(Debug, Default)]
122pub(crate) struct InitCounters {
123 pub(crate) entered: Counter,
125}
126
127impl InitCounters {
128 fn record(&self, inspector: &mut impl Inspector) {
129 let Self { entered } = self;
130 inspector.record_inspectable_value("Entered", entered);
131 }
132}
133
134#[derive(Debug, Default)]
136pub(crate) struct SelectingCounters {
137 pub(crate) entered: Counter,
139 pub(crate) messaging: MessagingRelatedCounters,
141 pub(crate) recv_error: SelectingIncomingMessageErrorCounters,
144}
145
146impl SelectingCounters {
147 fn record(&self, inspector: &mut impl Inspector) {
148 let Self { entered, messaging, recv_error } = self;
149 inspector.record_inspectable_value("Entered", entered);
150 messaging.record(inspector);
151 recv_error.record(inspector);
152 }
153}
154
155#[derive(Debug, Default)]
157pub(crate) struct RequestingCounters {
158 pub(crate) entered: Counter,
160 pub(crate) messaging: MessagingRelatedCounters,
162 pub(crate) recv_error: IncomingResponseToRequestErrorCounters,
165 pub(crate) recv_nak: Counter,
168}
169
170impl RequestingCounters {
171 fn record(&self, inspector: &mut impl Inspector) {
172 let Self { entered, messaging, recv_error, recv_nak } = self;
173 inspector.record_inspectable_value("Entered", entered);
174 messaging.record(inspector);
175 recv_error.record(inspector);
176 inspector.record_inspectable_value("RecvNak", recv_nak);
177 }
178}
179
180#[derive(Debug, Default)]
182pub(crate) struct BoundCounters {
183 pub(crate) entered: Counter,
185 pub(crate) assigned: Counter,
187}
188
189impl BoundCounters {
190 fn record(&self, inspector: &mut impl Inspector) {
191 let Self { entered, assigned } = self;
192 inspector.record_inspectable_value("Entered", entered);
193 inspector.record_inspectable_value("Assigned", assigned);
194 }
195}
196
197#[derive(Debug, Default)]
199pub(crate) struct RenewingCounters {
200 pub(crate) entered: Counter,
202 pub(crate) messaging: MessagingRelatedCounters,
204 pub(crate) recv_error: IncomingResponseToRequestErrorCounters,
207 pub(crate) recv_nak: Counter,
210}
211
212impl RenewingCounters {
213 fn record(&self, inspector: &mut impl Inspector) {
214 let Self { entered, messaging, recv_error, recv_nak } = self;
215 inspector.record_inspectable_value("Entered", entered);
216 messaging.record(inspector);
217 recv_error.record(inspector);
218 inspector.record_inspectable_value("RecvNak", recv_nak);
219 }
220}
221
222#[derive(Debug, Default)]
224pub(crate) struct RebindingCounters {
225 pub(crate) entered: Counter,
227 pub(crate) messaging: MessagingRelatedCounters,
229 pub(crate) recv_error: IncomingResponseToRequestErrorCounters,
232 pub(crate) recv_nak: Counter,
235}
236
237impl RebindingCounters {
238 fn record(&self, inspector: &mut impl Inspector) {
239 let Self { entered, messaging, recv_error, recv_nak } = self;
240 inspector.record_inspectable_value("Entered", entered);
241 messaging.record(inspector);
242 recv_error.record(inspector);
243 inspector.record_inspectable_value("RecvNak", recv_nak);
244 }
245}
246
247#[derive(Debug, Default)]
249pub(crate) struct WaitingToRestartCounters {
250 pub(crate) entered: Counter,
252}
253
254impl WaitingToRestartCounters {
255 fn record(&self, inspector: &mut impl Inspector) {
256 let Self { entered } = self;
257 inspector.record_inspectable_value("Entered", entered);
258 }
259}
260
261#[derive(Default, Debug)]
263pub struct Counters {
264 pub(crate) init: InitCounters,
265 pub(crate) selecting: SelectingCounters,
266 pub(crate) requesting: RequestingCounters,
267 pub(crate) bound: BoundCounters,
268 pub(crate) renewing: RenewingCounters,
269 pub(crate) rebinding: RebindingCounters,
270 pub(crate) waiting_to_restart: WaitingToRestartCounters,
271}
272
273impl Counters {
274 pub fn record(&self, inspector: &mut impl Inspector) {
276 let Self { init, selecting, requesting, bound, renewing, rebinding, waiting_to_restart } =
277 self;
278 inspector.record_child("Init", |inspector| {
279 init.record(inspector);
280 });
281 inspector.record_child("Selecting", |inspector| {
282 selecting.record(inspector);
283 });
284 inspector.record_child("Requesting", |inspector| {
285 requesting.record(inspector);
286 });
287 inspector.record_child("Bound", |inspector| {
288 bound.record(inspector);
289 });
290 inspector.record_child("Renewing", |inspector| {
291 renewing.record(inspector);
292 });
293 inspector.record_child("Rebinding", |inspector| {
294 rebinding.record(inspector);
295 });
296 inspector.record_child("WaitingToRestart", |inspector| {
297 waiting_to_restart.record(inspector);
298 });
299 }
300}