100 lines
2.8 KiB
Rust
100 lines
2.8 KiB
Rust
|
use crate::{get_date, simulation::bridge::Bridge};
|
||
|
|
||
|
use lox_library::{cred::Lox, scalar_u32};
|
||
|
use rand::Rng;
|
||
|
use std::collections::{HashMap, HashSet};
|
||
|
|
||
|
pub struct Censor {
|
||
|
pub country: String,
|
||
|
pub known_bridges: HashSet<[u8; 20]>,
|
||
|
pub lox_credentials: HashMap<[u8; 20], Lox>,
|
||
|
|
||
|
// How fast does this censor block bridges after learning about them?
|
||
|
pub speed: Speed,
|
||
|
// If censor implements random blocking, this is the date when it
|
||
|
// will start blocking all the bridges it knows.
|
||
|
pub delay_date: u32,
|
||
|
|
||
|
// Does the censor attempt to hide the fact that a bridge has been blocked?
|
||
|
pub hides: Hides,
|
||
|
|
||
|
// Does the censor block bridges uniformly across the country?
|
||
|
pub totality: Totality,
|
||
|
// If censor implements partial blocking, what percent of
|
||
|
// connections are blocked? If totality is not partial, this is set
|
||
|
// to 100%.
|
||
|
pub partial_blocking_percent: f64,
|
||
|
}
|
||
|
|
||
|
impl Censor {
|
||
|
pub fn new(country: String, speed: Speed, hides: Hides, totality: Totality) -> Self {
|
||
|
let mut rng = rand::thread_rng();
|
||
|
let delay_date = if speed == Speed::Random {
|
||
|
let num: u32 = rng.gen_range(1..365);
|
||
|
get_date() + num
|
||
|
} else {
|
||
|
0
|
||
|
};
|
||
|
let partial_blocking_percent = if totality == Totality::Partial {
|
||
|
let num: f64 = rng.gen_range(0.0..1.0);
|
||
|
num
|
||
|
} else {
|
||
|
1.0
|
||
|
};
|
||
|
Censor {
|
||
|
country: country,
|
||
|
known_bridges: HashSet::<[u8; 20]>::new(),
|
||
|
lox_credentials: HashMap::<[u8; 20], Lox>::new(),
|
||
|
speed: speed,
|
||
|
delay_date: delay_date,
|
||
|
hides: hides,
|
||
|
totality: totality,
|
||
|
partial_blocking_percent: partial_blocking_percent,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
pub fn knows_bridge(&self, bridge: &Bridge) -> bool {
|
||
|
self.known_bridges.contains(&bridge.fingerprint)
|
||
|
}
|
||
|
|
||
|
pub fn learn_bridge(&mut self, fingerprint: &[u8; 20]) {
|
||
|
self.known_bridges.insert(*fingerprint);
|
||
|
}
|
||
|
|
||
|
pub fn has_lox_cred(&self, bridge: &Bridge) -> bool {
|
||
|
self.lox_credentials.contains_key(&bridge.fingerprint)
|
||
|
}
|
||
|
|
||
|
pub fn give_lox_cred(&mut self, bridge: &Bridge, cred: Lox) {
|
||
|
// We only need one level 3+ credential per bridge. (This will
|
||
|
// change if we restrict positive reports to one per bridge per
|
||
|
// credential.)
|
||
|
if !self.lox_credentials.contains_key(&bridge.fingerprint)
|
||
|
&& scalar_u32(&cred.trust_level).unwrap() >= 3
|
||
|
{
|
||
|
self.lox_credentials.insert(bridge.fingerprint, cred);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
#[derive(PartialEq)]
|
||
|
pub enum Speed {
|
||
|
Fast,
|
||
|
Lox,
|
||
|
Random,
|
||
|
}
|
||
|
|
||
|
#[derive(PartialEq)]
|
||
|
pub enum Hides {
|
||
|
Overt,
|
||
|
Hiding,
|
||
|
Flooding,
|
||
|
}
|
||
|
|
||
|
#[derive(PartialEq)]
|
||
|
pub enum Totality {
|
||
|
Full,
|
||
|
Partial,
|
||
|
Throttling,
|
||
|
}
|