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
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
mod set;
use crate::ids::FallbackId;
use derive_builder::Builder;
use tor_config::ConfigBuildError;
use tor_config::{define_list_builder_accessors, impl_standard_builder, list_builder::VecBuilder};
use tor_llcrypto::pk::ed25519::Ed25519Identity;
use tor_llcrypto::pk::rsa::RsaIdentity;
use serde::{Deserialize, Serialize};
use std::net::SocketAddr;
use crate::dirstatus::DirStatus;
pub(crate) use set::FallbackState;
pub use set::{FallbackList, FallbackListBuilder};
#[derive(Debug, Clone, Builder, Eq, PartialEq)]
#[builder(build_fn(private, name = "build_unvalidated", error = "ConfigBuildError"))]
#[builder(derive(Debug, Serialize, Deserialize))]
pub struct FallbackDir {
rsa_identity: RsaIdentity,
ed_identity: Ed25519Identity,
#[builder(sub_builder(fn_name = "build"), setter(custom))]
orports: Vec<SocketAddr>,
}
impl_standard_builder! { FallbackDir: !Default }
define_list_builder_accessors! {
struct FallbackDirBuilder {
pub orports: [SocketAddr],
}
}
impl FallbackDir {
pub fn as_guard(&self) -> crate::FirstHop {
crate::FirstHop {
id: FallbackId::from_chan_target(self).into(),
orports: self.orports.clone(),
}
}
}
impl FallbackDirBuilder {
pub fn new() -> Self {
Self::default()
}
pub fn build(&self) -> std::result::Result<FallbackDir, ConfigBuildError> {
let built = self.build_unvalidated()?;
if built.orports.is_empty() {
return Err(ConfigBuildError::Invalid {
field: "orport".to_string(),
problem: "list was empty".to_string(),
});
}
Ok(built)
}
}
pub(crate) fn default_fallbacks() -> Vec<FallbackDirBuilder> {
fn fallback(rsa: &str, ed: &str, ports: &[&str]) -> FallbackDirBuilder {
let rsa = RsaIdentity::from_hex(rsa).expect("Bad hex in built-in fallback list");
let ed = base64::decode_config(ed, base64::STANDARD_NO_PAD)
.expect("Bad hex in built-in fallback list");
let ed = Ed25519Identity::from_bytes(&ed).expect("Wrong length in built-in fallback list");
let mut bld = FallbackDir::builder();
bld.rsa_identity(rsa).ed_identity(ed);
ports
.iter()
.map(|s| s.parse().expect("Bad socket address in fallbacklist"))
.for_each(|p| {
bld.orports().push(p);
});
bld
}
include!("fallback_dirs.inc")
}
impl tor_linkspec::ChanTarget for FallbackDir {
fn addrs(&self) -> &[SocketAddr] {
&self.orports[..]
}
fn ed_identity(&self) -> &Ed25519Identity {
&self.ed_identity
}
fn rsa_identity(&self) -> &RsaIdentity {
&self.rsa_identity
}
}