1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
|
//! Code for working with bridge descriptors.
//!
//! Here we need to keep track of which bridge descriptors we need, and inform
//! the directory manager of them.
// TODO pt-client: remove these "allow"s.
#![allow(clippy::missing_panics_doc)]
#![allow(dead_code, unused_variables, clippy::needless_pass_by_value)]
use std::sync::Arc;
use futures::stream::BoxStream;
use tor_linkspec::{OwnedChanTarget, RelayId, RelayIds};
// TODO pt-client: I think we may want another layer of abstraction between
// RouterDesc and BridgeDesc, to implement e.g. CircTarget for RouterDesc.
// Likely it should contain an Arc<RouterDesc>.
use tor_netdoc::doc::routerdesc::RouterDesc as BridgeDesc;
/// This is analogous to NetDirProvider.
///
/// TODO pt-client: improve documentation.
pub trait BridgeDescProvider {
/// Return the current set of bridge descriptors.
fn bridges(&self) -> Arc<BridgeDescList>;
/// Return a stream that gets a notification when the set of bridge
/// descriptors has changed.
fn events(&self) -> BoxStream<'static, BridgeDescEvent>;
/// Change the set of bridges that we want to download descriptors for.
///
/// Bridges outside of this set will not have their descriptors updated,
/// and will not be revealed in the BridgeDescList.
fn set_bridges(&self, bridges: &[OwnedChanTarget]);
}
/// An event describing a change in a `BridgeDescList`.
#[derive(Debug, Clone)]
#[non_exhaustive]
pub enum BridgeDescEvent {
/// A new descriptor has arrived
//
// TODO: (Should we do anything to indicate which one? If so, we
// won't be able to use a flag-based publisher.)
NewDesc,
}
/// A set of bridge descriptors, managed and modified by a BridgeDescProvider.
#[derive(Clone, Debug)]
pub struct BridgeDescList {
/// The known bridges.
///
/// TODO pt-client: This is almost certainly the wrong data structure; some
/// kind of ID-based hashmap is likelier to be right.
///
/// TODO pt-client: Maybe we should have an intermediary struct between
/// RouterDescriptors and "usable bridge", as we have for `Relay`.
bridges: Vec<BridgeDesc>,
}
impl BridgeDescList {
/// Return the bridge descriptor, if any, for the given `RelayId`.
pub fn by_id(&self, id: &RelayId) -> Option<&BridgeDesc> {
todo!() // TODO pt-client: implement.
}
/// Return the bridge descriptor, if any, that has all of the given `RelayIds`.
pub fn by_ids(&self, id: &RelayIds) -> Option<&BridgeDesc> {
todo!() // TODO pt-client: implement.
}
/// Return an iterator over every bridge descriptor in this list.
///
/// No bridge descriptors will be returned more than once, and no more than
/// one descriptor will be returned for any given `RelayId`.
pub fn bridges(&self) -> impl Iterator<Item = &BridgeDesc> {
todo!(); // TODO pt-client: implement.
#[allow(unreachable_code)]
[].iter()
}
/// Insert `desc` into this list of bridges.
///
/// Replace every already-existing descriptor that shares any identity with
/// `desc`.
pub fn insert(&mut self, desc: BridgeDesc) {
todo!() // TODO pt-client: implement.
}
/// Drop every member of this list for which `func` returns false.
pub fn retain<F>(&mut self, func: F)
where
F: FnMut(&BridgeDesc) -> bool,
{
todo!() // TODO pt-client: implement.
}
}
|