Skip to main content

rns_core/transport/
queries.rs

1use 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}