123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251 |
- use crate::{
- get_date,
- simulation::{bridge::Bridge, config::Config},
- PositiveReport,
- };
- use lox_cli::{get_lox_pub, networking::Networking};
- use lox_library::{cred::Lox, scalar_u32};
- use rand::Rng;
- use serde::Deserialize;
- use std::{
- cmp::min,
- collections::{HashMap, HashSet},
- };
- pub struct Censor {
- pub known_bridges: HashSet<[u8; 20]>,
-
-
-
-
-
- pub lox_credentials: HashMap<[u8; 20], (Lox, u32)>,
-
-
- pub delay_date: u32,
-
-
- pub partial_blocking_percent: f64,
- }
- impl Censor {
- pub fn new(config: &Config) -> Self {
- let mut rng = rand::thread_rng();
- let delay_date = if config.censor_speed == Speed::Random {
- let num: u32 = rng.gen_range(1..365);
- get_date() + num
- } else {
- 0
- };
- let partial_blocking_percent = if config.censor_totality == Totality::Partial {
- config.censor_partial_blocking_percent
- } else {
- 1.0
- };
- Censor {
- known_bridges: HashSet::<[u8; 20]>::new(),
- lox_credentials: HashMap::<[u8; 20], (Lox, u32)>::new(),
- delay_date: delay_date,
- partial_blocking_percent: partial_blocking_percent,
- }
- }
- pub fn knows_bridge(&self, fingerprint: &[u8; 20]) -> bool {
- self.known_bridges.contains(fingerprint)
- }
- pub fn blocks_bridge(&self, config: &Config, fingerprint: &[u8; 20]) -> bool {
- self.knows_bridge(fingerprint)
- && (config.censor_speed == Speed::Fast
- || config.censor_speed == Speed::Lox && self.has_lox_cred(fingerprint)
- || config.censor_speed == Speed::Random && self.delay_date <= get_date())
- }
- 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)
- && self.lox_credentials.get(fingerprint).unwrap().1 > 0
- }
- pub fn give_lox_cred(&mut self, fingerprint: &[u8; 20], cred: &Lox) {
-
-
-
- if scalar_u32(&cred.trust_level).unwrap() >= 3 {
-
-
- let cloned_cred = bincode::deserialize(&bincode::serialize(&cred).unwrap()).unwrap();
-
-
-
-
-
- let count = match self.lox_credentials.get(fingerprint) {
- Some((_cred, count)) => *count,
- None => 0,
- };
- self.lox_credentials
- .insert(*fingerprint, (cloned_cred, count + 1));
- }
- }
-
-
- pub async fn send_positive_report(&self, config: &Config, fingerprint: &[u8; 20]) -> bool {
-
-
- if !self.has_lox_cred(fingerprint) {
- return false;
- }
- let (cred, _) = &self.lox_credentials.get(fingerprint).unwrap();
- let pr = PositiveReport::from_lox_credential(
- *fingerprint,
- None,
- cred,
- get_lox_pub(&config.la_pubkeys),
- config.country.clone(),
- )
- .unwrap();
- if config
- .tp_net
- .request("/positivereport".to_string(), pr.to_json().into_bytes())
- .await
- .is_err()
- {
-
- return false;
- }
- true
- }
-
- async fn flood(&self, config: &Config, bridges: &mut HashMap<[u8; 20], Bridge>) {
-
- if config.censor_secrecy == Secrecy::Flooding {
- for fingerprint in &self.known_bridges {
-
- if config.censor_speed == Speed::Fast
- || config.censor_speed == Speed::Lox && self.has_lox_cred(fingerprint)
- || config.censor_speed == Speed::Random && self.delay_date <= get_date()
- {
- let bridge = bridges.get_mut(fingerprint).unwrap();
-
- let num_connections = 30000;
-
- bridge.censor_flood(num_connections);
-
-
- if self.has_lox_cred(fingerprint) {
- let (_cred, cred_count) =
- &self.lox_credentials.get(&bridge.fingerprint).unwrap();
- let num_prs = if config.one_positive_report_per_cred {
- *cred_count
- } else {
- 30000
- };
- for _ in 0..num_prs {
- self.send_positive_report(config, &bridge.fingerprint).await;
- }
- }
- }
- }
- }
- }
-
- async fn send_positive_reports(
- &self,
- config: &Config,
- bridges: &mut HashMap<[u8; 20], Bridge>,
- ) {
-
-
- if config.censor_secrecy == Secrecy::Hiding {
- for fingerprint in &self.known_bridges {
-
- if self.blocks_bridge(config, fingerprint) && self.has_lox_cred(fingerprint) {
- let bridge = bridges.get_mut(fingerprint).unwrap();
-
-
- let num_reports_to_send = if config.one_positive_report_per_cred {
- min(
- bridge.total_connections - bridge.real_connections,
- self.lox_credentials.get(fingerprint).unwrap().1,
- )
- } else {
- bridge.total_connections - bridge.real_connections
- };
- for _ in 0..num_reports_to_send {
- self.send_positive_report(config, fingerprint).await;
- }
- }
- }
- }
- }
- fn recompute_delay(&mut self, config: &Config) {
-
- if config.censor_speed == Speed::Random
- && self.delay_date + config.censor_event_duration <= get_date()
- {
-
- self.delay_date = {
- let mut rng = rand::thread_rng();
- let num: u32 = rng.gen_range(1..365);
- get_date() + num
- }
- }
- }
- pub async fn end_of_day_tasks(
- &mut self,
- config: &Config,
- bridges: &mut HashMap<[u8; 20], Bridge>,
- ) {
- if config.censor_secrecy == Secrecy::Flooding
- && !(config.censor_speed == Speed::Random && self.delay_date <= get_date())
- {
- self.flood(config, bridges).await;
- } else if config.censor_secrecy == Secrecy::Hiding
- && !(config.censor_speed == Speed::Random && self.delay_date <= get_date())
- {
- self.send_positive_reports(config, bridges).await;
- }
- self.recompute_delay(config);
- }
- }
- #[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
- pub enum Speed {
- Fast,
- Lox,
- Random,
- }
- #[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
- pub enum Secrecy {
- Overt,
- Hiding,
- Flooding,
- }
- #[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
- pub enum Totality {
- Full,
- Partial,
- Throttling,
- }
|