Start on accessors for relay weight.

This commit is contained in:
Nick Mathewson 2020-09-08 17:20:46 -04:00
parent fc5a1b7908
commit 8768222acb
2 changed files with 70 additions and 2 deletions

View File

@ -1,3 +1,5 @@
#![allow(unused)]
mod err;
use tor_checkable::{ExternallySigned, SelfSigned, Timebound};
@ -8,6 +10,7 @@ use tor_netdoc::AllowAnnotations;
use ll::pk::rsa::RSAIdentity;
use log::{info, warn};
use std::cell::Cell;
use std::collections::HashMap;
use std::fs;
use std::path::{Path, PathBuf};
@ -28,10 +31,18 @@ pub struct NetDirConfig {
cache_path: Option<PathBuf>,
}
#[derive(Copy, Clone)]
enum WeightFn {
NoBandwidths,
NoMeasuredBandwidths,
MeasuredBandwidths,
}
#[allow(unused)]
pub struct NetDir {
consensus: MDConsensus,
mds: HashMap<MDDigest, Microdesc>,
weight_fn: Cell<Option<WeightFn>>,
}
// TODO: This should probably be a more specific struct, with a trait
@ -195,7 +206,11 @@ impl NetDirConfig {
}
info!("Loaded {} microdescriptors", mds.len());
Ok(NetDir { consensus, mds })
Ok(NetDir {
consensus,
mds,
weight_fn: Cell::new(None),
})
}
}
@ -219,6 +234,23 @@ impl NetDir {
pub fn relays(&self) -> impl Iterator<Item = Relay<'_>> {
self.all_relays().filter(Relay::is_usable)
}
fn pick_weight_fn(&self) {
let has_measured = self.relays().any(|r| r.rs.get_weight().is_measured());
let has_nonzero = self.relays().any(|r| r.rs.get_weight().is_nonzero());
if !has_nonzero {
self.weight_fn.set(Some(WeightFn::NoBandwidths));
} else if !has_measured {
self.weight_fn.set(Some(WeightFn::NoMeasuredBandwidths));
} else {
self.weight_fn.set(Some(WeightFn::MeasuredBandwidths));
}
}
fn get_weight_fn(&self) -> WeightFn {
if self.weight_fn.get().is_none() {
self.pick_weight_fn();
}
self.weight_fn.get().unwrap()
}
}
impl<'a> Relay<'a> {
@ -231,4 +263,16 @@ impl<'a> Relay<'a> {
pub fn get_rsa_id(&self) -> &RSAIdentity {
self.rs.get_rsa_identity()
}
fn get_weight(&self, wf: WeightFn) -> u32 {
use netstatus::RouterWeight::*;
use WeightFn::*;
match (wf, self.rs.get_weight()) {
(NoBandwidths, _) => 1,
(NoMeasuredBandwidths, Unmeasured(u)) => *u,
(NoMeasuredBandwidths, Measured(u)) => *u,
(MeasuredBandwidths, Unmeasured(_)) => 0,
(MeasuredBandwidths, Measured(u)) => *u,
}
}
}

View File

@ -170,12 +170,32 @@ struct RouterFlags {
/// Recognized weight fields on a single relay in a consensus
#[allow(dead_code)]
enum RouterWeight {
pub enum RouterWeight {
// TODO SPEC: Document that these are u32 in dir-spec.txt
/// An unmeasured weight for a router.
Unmeasured(u32),
/// An measured weight for a router.
Measured(u32),
}
impl RouterWeight {
/// Return true if this weight is the result of a successful measurement
pub fn is_measured(&self) -> bool {
match self {
RouterWeight::Measured(x) if x > &0 => true,
_ => false,
}
}
/// Return true if this weight is nonzero
pub fn is_nonzero(&self) -> bool {
match self {
RouterWeight::Unmeasured(0) => false,
RouterWeight::Measured(0) => false,
_ => true,
}
}
}
/// A single relay's status as represented in a microdesc consensus.
#[allow(dead_code)]
pub struct MDConsensusRouterStatus {
@ -207,6 +227,10 @@ impl MDConsensusRouterStatus {
pub fn orport_addrs(&self) -> impl Iterator<Item = &net::SocketAddr> {
self.addrs.iter()
}
/// Return the declared weight of this routerstatus in the directory.
pub fn get_weight(&self) -> &RouterWeight {
&self.weight
}
}
/// All information about a single authority, as represented in a consensus