rns_core/transport/
queries.rs1use super::*;
2
3impl TransportEngine {
4 pub fn path_table_entries(&self) -> impl Iterator<Item = (&[u8; 16], &PathEntry)> {
5 self.path_table
6 .iter()
7 .filter_map(|(k, ps)| ps.primary().map(|e| (k, e)))
8 }
9
10 pub fn path_table_sets(&self) -> impl Iterator<Item = (&[u8; 16], &PathSet)> {
11 self.path_table.iter()
12 }
13
14 pub fn interface_count(&self) -> usize {
15 self.interfaces.len()
16 }
17
18 pub fn link_table_count(&self) -> usize {
19 self.link_table.len()
20 }
21
22 pub fn path_table_count(&self) -> usize {
23 self.path_table.len()
24 }
25
26 pub fn announce_table_count(&self) -> usize {
27 self.announce_table.len()
28 }
29
30 pub fn reverse_table_count(&self) -> usize {
31 self.reverse_table.len()
32 }
33
34 pub fn held_announces_count(&self) -> usize {
35 self.held_announces.len()
36 }
37
38 pub fn packet_hashlist_len(&self) -> usize {
39 self.packet_hashlist.len()
40 }
41
42 pub fn announce_sig_cache_len(&self) -> usize {
43 self.announce_sig_cache.len()
44 }
45
46 pub fn rate_limiter_count(&self) -> usize {
47 self.rate_limiter.len()
48 }
49
50 pub fn blackholed_count(&self) -> usize {
51 self.blackholed_identities.len()
52 }
53
54 pub fn tunnel_count(&self) -> usize {
55 self.tunnel_table.len()
56 }
57
58 pub fn discovery_pr_tags_count(&self) -> usize {
59 self.discovery_pr_tags.len()
60 }
61
62 #[cfg(test)]
63 pub(crate) fn has_discovery_pr_tag(&self, unique_tag: &[u8; 32]) -> bool {
64 self.discovery_pr_tag_set.contains(unique_tag)
65 }
66
67 pub fn discovery_path_requests_count(&self) -> usize {
68 self.discovery_path_requests.len()
69 }
70
71 pub fn announce_queue_count(&self) -> usize {
72 self.announce_queues.queue_count()
73 }
74
75 pub fn nonempty_announce_queue_count(&self) -> usize {
76 self.announce_queues.nonempty_queue_count()
77 }
78
79 pub fn queued_announce_count(&self) -> usize {
80 self.announce_queues.total_queued_announces()
81 }
82
83 pub fn queued_announce_bytes(&self) -> usize {
84 self.announce_queues.total_queued_bytes()
85 }
86
87 pub fn announce_queue_interface_cap_drop_count(&self) -> u64 {
88 self.announce_queues.interface_cap_drop_count()
89 }
90
91 pub fn local_destinations_count(&self) -> usize {
92 self.local_destinations.len()
93 }
94
95 pub fn rate_limiter(&self) -> &AnnounceRateLimiter {
96 &self.rate_limiter
97 }
98
99 pub fn interface_info(&self, id: &InterfaceId) -> Option<&InterfaceInfo> {
100 self.interfaces.get(id)
101 }
102
103 pub fn redirect_path(&mut self, dest_hash: &[u8; 16], interface: InterfaceId, now: f64) {
104 if let Some(entry) = self
105 .path_table
106 .get_mut(dest_hash)
107 .and_then(|ps| ps.primary_mut())
108 {
109 entry.receiving_interface = interface;
110 entry.hops = 1;
111 } else {
112 self.upsert_path_destination(
113 *dest_hash,
114 PathEntry {
115 timestamp: now,
116 next_hop: [0u8; 16],
117 hops: 1,
118 expires: now + 3600.0,
119 random_blobs: Vec::new(),
120 receiving_interface: interface,
121 packet_hash: [0u8; 32],
122 announce_raw: None,
123 },
124 now,
125 );
126 }
127 }
128
129 pub fn inject_path(&mut self, dest_hash: [u8; 16], entry: PathEntry) {
130 self.upsert_path_destination(dest_hash, entry.clone(), entry.timestamp);
131 }
132
133 pub fn drop_path(&mut self, dest_hash: &[u8; 16]) -> bool {
134 self.path_table.remove(dest_hash).is_some()
135 }
136
137 pub fn drop_all_via(&mut self, transport_hash: &[u8; 16]) -> usize {
138 let mut removed = 0usize;
139 for ps in self.path_table.values_mut() {
140 let before = ps.len();
141 ps.retain(|entry| &entry.next_hop != transport_hash);
142 removed += before - ps.len();
143 }
144 self.path_table.retain(|_, ps| !ps.is_empty());
145 removed
146 }
147
148 pub fn drop_paths_for_interface(&mut self, interface: InterfaceId) -> usize {
149 let mut removed = 0usize;
150 let mut cleared_destinations = Vec::new();
151 for (dest_hash, ps) in self.path_table.iter_mut() {
152 let before = ps.len();
153 ps.retain(|entry| entry.receiving_interface != interface);
154 if ps.is_empty() {
155 cleared_destinations.push(*dest_hash);
156 }
157 removed += before - ps.len();
158 }
159 self.path_table.retain(|_, ps| !ps.is_empty());
160 for dest_hash in cleared_destinations {
161 self.path_states.remove(&dest_hash);
162 }
163 removed
164 }
165
166 pub fn drop_reverse_for_interface(&mut self, interface: InterfaceId) -> usize {
167 let before = self.reverse_table.len();
168 self.reverse_table.retain(|_, entry| {
169 entry.receiving_interface != interface && entry.outbound_interface != interface
170 });
171 before - self.reverse_table.len()
172 }
173
174 pub fn drop_links_for_interface(&mut self, interface: InterfaceId) -> usize {
175 let before = self.link_table.len();
176 self.link_table.retain(|_, entry| {
177 entry.next_hop_interface != interface && entry.received_interface != interface
178 });
179 before - self.link_table.len()
180 }
181
182 pub fn drop_announce_queues(&mut self) {
183 self.announce_table.clear();
184 self.held_announces.clear();
185 self.announce_queues = AnnounceQueues::new(self.config.announce_queue_max_interfaces);
186 self.ingress_control.clear();
187 }
188
189 pub fn void_queues(&mut self) {
190 self.drop_announce_queues();
191 self.reverse_table.clear();
192 }
193
194 pub fn identity_hash(&self) -> Option<&[u8; 16]> {
195 self.config.identity_hash.as_ref()
196 }
197
198 pub fn transport_enabled(&self) -> bool {
199 self.config.transport_enabled
200 }
201
202 pub fn config(&self) -> &TransportConfig {
203 &self.config
204 }
205
206 pub fn set_packet_hashlist_max_entries(&mut self, max_entries: usize) {
207 self.config.packet_hashlist_max_entries = max_entries;
208 self.packet_hashlist =
209 PacketHashlist::with_allocation(max_entries, self.config.packet_hashlist_allocation);
210 }
211
212 pub fn get_path_table(&self, max_hops: Option<u8>) -> Vec<PathTableRow> {
213 let mut result = Vec::new();
214 for (dest_hash, ps) in self.path_table.iter() {
215 if let Some(entry) = ps.primary() {
216 if let Some(max) = max_hops {
217 if entry.hops > max {
218 continue;
219 }
220 }
221 let iface_name = self
222 .interfaces
223 .get(&entry.receiving_interface)
224 .map(|i| i.name.clone())
225 .unwrap_or_else(|| {
226 alloc::format!("Interface({})", entry.receiving_interface.0)
227 });
228 result.push((
229 *dest_hash,
230 entry.timestamp,
231 entry.next_hop,
232 entry.hops,
233 entry.expires,
234 iface_name,
235 ));
236 }
237 }
238 result
239 }
240
241 pub fn get_rate_table(&self) -> Vec<RateTableRow> {
242 self.rate_limiter
243 .entries()
244 .map(|(hash, entry)| {
245 (
246 *hash,
247 entry.last,
248 entry.rate_violations,
249 entry.blocked_until,
250 entry.timestamps.clone(),
251 )
252 })
253 .collect()
254 }
255
256 pub fn get_blackholed(&self) -> Vec<([u8; 16], f64, f64, Option<alloc::string::String>)> {
257 self.blackholed_entries()
258 .map(|(hash, entry)| (*hash, entry.created, entry.expires, entry.reason.clone()))
259 .collect()
260 }
261
262 pub fn active_destination_hashes(&self) -> alloc::collections::BTreeSet<[u8; 16]> {
263 self.path_table.keys().copied().collect()
264 }
265
266 pub fn path_destination_cap_evict_count(&self) -> usize {
267 self.path_destination_cap_evict_count
268 }
269
270 pub fn active_packet_hashes(&self) -> Vec<[u8; 32]> {
271 let mut hashes: Vec<[u8; 32]> = self
272 .path_table
273 .values()
274 .flat_map(|ps| ps.iter().map(|p| p.packet_hash))
275 .collect();
276
277 hashes.extend(
278 self.tunnel_table
279 .iter()
280 .flat_map(|(_, tunnel)| tunnel.paths.values().map(|p| p.packet_hash)),
281 );
282 hashes.sort_unstable();
283 hashes.dedup();
284 hashes
285 }
286
287 pub fn cull_rate_limiter(
288 &mut self,
289 active: &alloc::collections::BTreeSet<[u8; 16]>,
290 now: f64,
291 ttl_secs: f64,
292 ) -> usize {
293 self.rate_limiter.cull_stale(active, now, ttl_secs)
294 }
295
296 pub fn update_interface_freq(&mut self, id: InterfaceId, ia_freq: f64) {
297 if let Some(info) = self.interfaces.get_mut(&id) {
298 info.ia_freq = ia_freq;
299 }
300 }
301
302 pub fn update_interface_freqs(
303 &mut self,
304 id: InterfaceId,
305 ia_freq: f64,
306 ip_freq: f64,
307 op_freq: f64,
308 op_samples: usize,
309 ) {
310 if let Some(info) = self.interfaces.get_mut(&id) {
311 info.ia_freq = ia_freq;
312 info.ip_freq = ip_freq;
313 info.op_freq = op_freq;
314 info.op_samples = op_samples;
315 }
316 }
317
318 pub fn held_announce_count(&self, interface: &InterfaceId) -> usize {
319 self.ingress_control.held_count(interface)
320 }
321
322 pub fn burst_active(&self, interface: &InterfaceId) -> bool {
323 self.ingress_control.burst_active(interface)
324 }
325
326 pub fn burst_activated(&self, interface: &InterfaceId) -> f64 {
327 self.ingress_control.burst_activated(interface)
328 }
329
330 pub fn pr_burst_active(&self, interface: &InterfaceId) -> bool {
331 self.ingress_control.pr_burst_active(interface)
332 }
333
334 pub fn pr_burst_activated(&self, interface: &InterfaceId) -> f64 {
335 self.ingress_control.pr_burst_activated(interface)
336 }
337
338 #[cfg(test)]
339 #[allow(dead_code)]
340 pub(crate) fn path_table(&self) -> &BTreeMap<[u8; 16], PathSet> {
341 &self.path_table
342 }
343
344 #[cfg(test)]
345 #[allow(dead_code)]
346 pub(crate) fn announce_table(&self) -> &BTreeMap<[u8; 16], AnnounceEntry> {
347 &self.announce_table
348 }
349
350 #[cfg(test)]
351 #[allow(dead_code)]
352 pub(crate) fn held_announces(&self) -> &BTreeMap<[u8; 16], AnnounceEntry> {
353 &self.held_announces
354 }
355
356 #[cfg(test)]
357 #[allow(dead_code)]
358 pub(crate) fn announce_retained_bytes(&self) -> usize {
359 self.announce_retained_bytes_total()
360 }
361
362 #[cfg(test)]
363 #[allow(dead_code)]
364 pub(crate) fn reverse_table(&self) -> &BTreeMap<[u8; 16], tables::ReverseEntry> {
365 &self.reverse_table
366 }
367}