ant_quic/tracing/
macros.rs

1// Copyright 2024 Saorsa Labs Ltd.
2//
3// This Saorsa Network Software is licensed under the General Public License (GPL), version 3.
4// Please see the file LICENSE-GPL, or visit <http://www.gnu.org/licenses/> for the full text.
5//
6// Full details available at https://saorsalabs.com/licenses
7
8//! Zero-cost macros for tracing
9//!
10//! These macros compile to nothing when the trace feature is disabled.
11
12/// Primary trace event macro - compiles to nothing when disabled
13#[macro_export]
14macro_rules! trace_event {
15    ($log:expr_2021, $event:expr_2021) => {
16        #[cfg(feature = "trace")]
17        $log.log($event)
18    };
19}
20
21/// Trace a packet sent event
22#[macro_export]
23macro_rules! trace_packet_sent {
24    ($log:expr_2021, $trace_id:expr_2021, $size:expr_2021, $num:expr_2021) => {
25        $crate::trace_event!(
26            $log,
27            $crate::tracing::Event {
28                timestamp: $crate::tracing::timestamp_now(),
29                trace_id: $trace_id,
30                event_data: $crate::tracing::EventData::PacketSent {
31                    size: $size as u32,
32                    packet_num: $num,
33                    _padding: [0u8; 56],
34                },
35                ..Default::default()
36            }
37        )
38    };
39}
40
41/// Trace a packet received event
42#[macro_export]
43macro_rules! trace_packet_received {
44    ($log:expr_2021, $trace_id:expr_2021, $size:expr_2021, $num:expr_2021) => {
45        $crate::trace_event!(
46            $log,
47            $crate::tracing::Event {
48                timestamp: $crate::tracing::timestamp_now(),
49                trace_id: $trace_id,
50                event_data: $crate::tracing::EventData::PacketReceived {
51                    size: $size as u32,
52                    packet_num: $num,
53                    _padding: [0u8; 56],
54                },
55                ..Default::default()
56            }
57        )
58    };
59}
60
61/// Trace a stream opened event
62#[macro_export]
63macro_rules! trace_stream_opened {
64    ($log:expr_2021, $trace_id:expr_2021, $stream_id:expr_2021) => {
65        $crate::trace_event!(
66            $log,
67            $crate::tracing::Event {
68                timestamp: $crate::tracing::timestamp_now(),
69                trace_id: $trace_id,
70                event_data: $crate::tracing::EventData::StreamOpened {
71                    stream_id: $stream_id,
72                    _padding: [0u8; 56],
73                },
74                ..Default::default()
75            }
76        )
77    };
78}
79
80/// Trace a connection established event
81#[macro_export]
82macro_rules! trace_conn_established {
83    ($log:expr_2021, $trace_id:expr_2021, $rtt:expr_2021) => {
84        $crate::trace_event!(
85            $log,
86            $crate::tracing::Event {
87                timestamp: $crate::tracing::timestamp_now(),
88                trace_id: $trace_id,
89                event_data: $crate::tracing::EventData::ConnEstablished {
90                    rtt: $rtt as u32,
91                    _padding: [0u8; 60],
92                },
93                ..Default::default()
94            }
95        )
96    };
97}
98
99/// Conditional code block that only compiles with trace feature
100#[macro_export]
101macro_rules! if_trace {
102    ($($body:tt)*) => {
103        #[cfg(feature = "trace")]
104        {
105            $($body)*
106        }
107    };
108}
109
110/// Trace an observed address event
111#[macro_export]
112macro_rules! trace_observed_address_sent {
113    ($log:expr_2021, $trace_id:expr_2021, $addr:expr_2021, $path_id:expr_2021) => {
114        $crate::trace_event!($log, {
115            let (addr_bytes, addr_type) = $crate::tracing::socket_addr_to_bytes($addr);
116            $crate::tracing::Event {
117                timestamp: $crate::tracing::timestamp_now(),
118                trace_id: $trace_id,
119                event_data: $crate::tracing::EventData::ObservedAddressSent {
120                    addr_bytes,
121                    addr_type,
122                    path_id: $path_id as u32,
123                    _padding: [0u8; 41],
124                },
125                ..Default::default()
126            }
127        })
128    };
129}
130
131/// Trace an observed address received
132#[macro_export]
133macro_rules! trace_observed_address_received {
134    ($log:expr_2021, $trace_id:expr_2021, $addr:expr_2021, $path_id:expr_2021) => {
135        $crate::trace_event!($log, {
136            let (addr_bytes, addr_type) = $crate::tracing::socket_addr_to_bytes($addr);
137            $crate::tracing::Event {
138                timestamp: $crate::tracing::timestamp_now(),
139                trace_id: $trace_id,
140                event_data: $crate::tracing::EventData::ObservedAddressReceived {
141                    addr_bytes,
142                    addr_type,
143                    from_peer: [0u8; 32], // TODO: Get actual peer ID
144                    _padding: [0u8; 13],
145                },
146                ..Default::default()
147            }
148        })
149    };
150}
151
152/// Trace a NAT traversal candidate discovered
153#[macro_export]
154macro_rules! trace_candidate_discovered {
155    ($log:expr_2021, $trace_id:expr_2021, $addr:expr_2021, $priority:expr_2021) => {
156        $crate::trace_event!($log, {
157            let (addr_bytes, addr_type) = $crate::tracing::socket_addr_to_bytes($addr);
158            $crate::tracing::Event {
159                timestamp: $crate::tracing::timestamp_now(),
160                trace_id: $trace_id,
161                event_data: $crate::tracing::EventData::CandidateDiscovered {
162                    addr_bytes,
163                    addr_type,
164                    priority: $priority as u32,
165                    _padding: [0u8; 41],
166                },
167                ..Default::default()
168            }
169        })
170    };
171}
172
173/// Trace hole punching started
174#[macro_export]
175macro_rules! trace_hole_punching_started {
176    ($log:expr_2021, $trace_id:expr_2021, $peer:expr_2021) => {
177        $crate::trace_event!(
178            $log,
179            $crate::tracing::Event {
180                timestamp: $crate::tracing::timestamp_now(),
181                trace_id: $trace_id,
182                event_data: $crate::tracing::EventData::HolePunchingStarted {
183                    peer: $peer,
184                    _padding: [0u8; 32],
185                },
186                ..Default::default()
187            }
188        )
189    };
190}
191
192#[cfg(test)]
193mod tests {
194    use crate::tracing::{EventLog, TraceId};
195
196    #[test]
197    fn test_trace_macros() {
198        let _log = EventLog::new();
199        let _trace_id = TraceId::new();
200
201        // These should compile whether trace is enabled or not
202        trace_packet_sent!(&_log, _trace_id, 1200, 42);
203        trace_packet_received!(&_log, _trace_id, 1200, 43);
204        trace_stream_opened!(&_log, _trace_id, 1);
205        trace_conn_established!(&_log, _trace_id, 25);
206
207        if_trace! {
208            // This code only exists when trace is enabled
209            #[cfg(feature = "trace")]
210            let _count = _log.event_count();
211        }
212    }
213}