tor_netdoc/doc/netstatus/rs/
each_flavor.rs1use super::*;
14
15impl RouterStatus {
18 pub fn orport_addrs(&self) -> impl Iterator<Item = &net::SocketAddr> {
20 self.addrs().iter()
21 }
22 pub fn weight(&self) -> &RelayWeight {
24 &self.weight
25 }
26 pub fn addrs(&self) -> &[net::SocketAddr] {
28 &self.addrs[..]
29 }
30 pub fn protovers(&self) -> &Protocols {
32 &self.protos
33 }
34 pub fn nickname(&self) -> &str {
36 self.nickname.as_str()
37 }
38 pub fn flags(&self) -> &RelayFlags {
40 &self.flags
41 }
42 pub fn version(&self) -> Option<&crate::doc::netstatus::rs::Version> {
44 self.version.as_ref()
45 }
46 pub fn ed25519_id_is_usable(&self) -> bool {
49 !self.flags.contains(RelayFlags::NO_ED_CONSENSUS)
50 }
51 pub fn is_flagged_bad_exit(&self) -> bool {
53 self.flags.contains(RelayFlags::BAD_EXIT)
54 }
55 pub fn is_flagged_v2dir(&self) -> bool {
57 self.flags.contains(RelayFlags::V2DIR)
58 }
59 pub fn is_flagged_exit(&self) -> bool {
61 self.flags.contains(RelayFlags::EXIT)
62 }
63 pub fn is_flagged_guard(&self) -> bool {
65 self.flags.contains(RelayFlags::GUARD)
66 }
67 pub fn is_flagged_hsdir(&self) -> bool {
69 self.flags.contains(RelayFlags::HSDIR)
70 }
71 pub fn is_flagged_stable(&self) -> bool {
73 self.flags.contains(RelayFlags::STABLE)
74 }
75 pub fn is_flagged_fast(&self) -> bool {
77 self.flags.contains(RelayFlags::FAST)
78 }
79 pub fn is_flagged_middle_only(&self) -> bool {
81 self.flags.contains(RelayFlags::MIDDLE_ONLY)
82 }
83}
84
85impl RouterStatus {
86 pub fn rsa_identity(&self) -> &RsaIdentity {
88 &self.identity
89 }
90
91 pub fn doc_digest(&self) -> &DocDigest {
94 &self.doc_digest
95 }
96
97 pub(crate) fn flavor() -> ConsensusFlavor {
100 FLAVOR
101 }
102
103 pub(crate) fn from_section(
108 sec: &Section<'_, NetstatusKwd>,
109 ) -> Result<RouterStatus> {
110 use NetstatusKwd::*;
111 let r_item = sec.required(RS_R)?;
113 let nickname = r_item.required_arg(0)?.parse()?;
114 let ident = r_item.required_arg(1)?.parse::<B64>()?;
115 let identity = RsaIdentity::from_bytes(ident.as_bytes()).ok_or_else(|| {
116 EK::BadArgument
117 .at_pos(r_item.pos())
118 .with_msg("Wrong identity length")
119 })?;
120 let n_skip = match FLAVOR {
122 ConsensusFlavor::Microdesc => 0,
123 ConsensusFlavor::Plain => 1,
124 };
125 let _ignore_published: time::SystemTime = {
128 let mut p = r_item.required_arg(2 + n_skip)?.to_string();
133 p.push(' ');
134 p.push_str(r_item.required_arg(3 + n_skip)?);
135 p.parse::<Iso8601TimeSp>()?.into()
136 };
137 let ipv4addr = r_item.required_arg(4 + n_skip)?.parse::<net::Ipv4Addr>()?;
138 let or_port = r_item.required_arg(5 + n_skip)?.parse::<u16>()?;
139 let _ = r_item.required_arg(6 + n_skip)?.parse::<u16>()?;
140
141 let a_items = sec.slice(RS_A);
143 let mut addrs = Vec::with_capacity(1 + a_items.len());
144 addrs.push(net::SocketAddr::V4(net::SocketAddrV4::new(
145 ipv4addr, or_port,
146 )));
147 for a_item in a_items {
148 addrs.push(a_item.required_arg(0)?.parse::<net::SocketAddr>()?);
149 }
150
151 let flags = RelayFlags::from_item(sec.required(RS_S)?)?;
153
154 let version = sec.maybe(RS_V).args_as_str().map(str::parse).transpose()?;
156
157 let protos = {
159 let tok = sec.required(RS_PR)?;
160 doc::PROTOVERS_CACHE.intern(
161 tok.args_as_str()
162 .parse::<Protocols>()
163 .map_err(|e| EK::BadArgument.at_pos(tok.pos()).with_source(e))?,
164 )
165 };
166
167 let weight = sec
169 .get(RS_W)
170 .map(RelayWeight::from_item)
171 .transpose()?
172 .unwrap_or_default();
173
174 let doc_digest: DocDigest = match FLAVOR {
180 ConsensusFlavor::Microdesc => {
181 let m_item = sec.required(RS_M)?;
183 DocDigest::decode(m_item.required_arg(0)?)?
184 }
185 ConsensusFlavor::Plain => DocDigest::decode(r_item.required_arg(2)?)?,
186 };
187
188 Ok(RouterStatus {
189 nickname,
190 identity,
191 addrs,
192 doc_digest,
193 flags,
194 version,
195 protos,
196 weight,
197 })
198 }
199}
200
201impl FromRsString for DocDigest {
202 fn decode(s: &str) -> Result<DocDigest> {
203 s.parse::<B64>()?
204 .check_len(DOC_DIGEST_LEN..=DOC_DIGEST_LEN)?
205 .as_bytes()
206 .try_into()
207 .map_err(|_| Error::from(internal!("correct length on digest, but unable to convert")))
208 }
209}