troll-patrol/src/simulation/censor.rs

101 lines
3.0 KiB
Rust
Raw Normal View History

use crate::get_date;
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, fingerprint: &[u8; 20]) -> bool {
self.known_bridges.contains(fingerprint)
}
pub fn learn_bridge(&mut self, fingerprint: &[u8; 20]) {
self.known_bridges.insert(*fingerprint);
}
pub fn has_lox_cred(&self, fingerprint: &[u8; 20]) -> bool {
self.lox_credentials.contains_key(fingerprint)
}
pub fn give_lox_cred(&mut self, fingerprint: &[u8; 20], 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.has_lox_cred(fingerprint) && scalar_u32(&cred.trust_level).unwrap() >= 3 {
// We want to clone the credential, but that's not allowed,
// so we're going to serialize it and then deserialize it.
let cloned_cred = bincode::deserialize(&bincode::serialize(&cred).unwrap()).unwrap();
self.lox_credentials.insert(*fingerprint, cloned_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,
}