From 498d6b4cee1a43588308aca97c2cf49a16df7394 Mon Sep 17 00:00:00 2001 From: Vecna Date: Sat, 8 Jun 2024 15:52:35 -0400 Subject: [PATCH] Change Hides to Secrecy, have censor submit all false reports at end If the censor submits a report each time it blocks a connection, this number may exceed the number of Lox credentials the censor can actually use to submit these reports. This is an issue if we restrict these reports to one per credential. --- src/bin/simulation.rs | 4 ++-- src/simulation/bridge.rs | 4 ++-- src/simulation/censor.rs | 47 ++++++++++++++++++++++++++++++++++---- src/simulation/config.rs | 2 +- src/simulation/user.rs | 49 ++++++++++++++-------------------------- 5 files changed, 65 insertions(+), 41 deletions(-) diff --git a/src/bin/simulation.rs b/src/bin/simulation.rs index 9e9d2db..1f33c12 100644 --- a/src/bin/simulation.rs +++ b/src/bin/simulation.rs @@ -44,7 +44,7 @@ pub struct Config { pub la_test_port: u16, pub tp_port: u16, pub tp_test_port: u16, - pub censor_hides: censor::Hides, + pub censor_secrecy: censor::Secrecy, pub censor_speed: censor::Speed, pub censor_event_duration: u32, pub censor_totality: censor::Totality, @@ -96,7 +96,7 @@ pub async fn main() { la_pubkeys, la_net, tp_net, - censor_hides: config.censor_hides, + censor_secrecy: config.censor_secrecy, censor_speed: config.censor_speed, censor_event_duration: config.censor_event_duration, censor_totality: config.censor_totality, diff --git a/src/simulation/bridge.rs b/src/simulation/bridge.rs index e7237ce..8b01cf3 100644 --- a/src/simulation/bridge.rs +++ b/src/simulation/bridge.rs @@ -26,8 +26,8 @@ pub struct Bridge { // bridge (for identifying stage three) pub first_positive_report: u32, - real_connections: u32, - total_connections: u32, + pub real_connections: u32, + pub total_connections: u32, } impl Bridge { diff --git a/src/simulation/censor.rs b/src/simulation/censor.rs index 5c5db59..ba8f4e8 100644 --- a/src/simulation/censor.rs +++ b/src/simulation/censor.rs @@ -8,7 +8,10 @@ use lox_cli::{get_lox_pub, networking::Networking}; use lox_library::{cred::Lox, scalar_u32}; use rand::Rng; use serde::Deserialize; -use std::collections::{HashMap, HashSet}; +use std::{ + cmp::min, + collections::{HashMap, HashSet}, +}; pub struct Censor { pub known_bridges: HashSet<[u8; 20]>, @@ -127,7 +130,7 @@ impl Censor { // Make a bunch of connections and submit positive reports if possible async fn flood(&self, config: &Config, bridges: &mut HashMap<[u8; 20], Bridge>) { // Only do this if Flooding censor - if config.censor_hides == Hides::Flooding { + if config.censor_secrecy == Secrecy::Flooding { for fingerprint in &self.known_bridges { // Only do this if we're blocking the bridge if config.censor_speed == Speed::Fast @@ -161,6 +164,38 @@ impl Censor { } } + // Send one positive report per connection we blocked + async fn send_positive_reports( + &self, + config: &Config, + bridges: &mut HashMap<[u8; 20], Bridge>, + ) { + // Only do this if Hiding censor. Flooding censors should use + // flood() instead. + if config.censor_secrecy == Secrecy::Hiding { + for fingerprint in &self.known_bridges { + // Only do this if we're blocking the bridge + if self.blocks_bridge(config, fingerprint) && self.has_lox_cred(fingerprint) { + let bridge = bridges.get_mut(fingerprint).unwrap(); + + // We may be restricted to one positive report per + // credential + 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) { // Only do this if Random censor if config.censor_speed == Speed::Random @@ -180,10 +215,14 @@ impl Censor { config: &Config, bridges: &mut HashMap<[u8; 20], Bridge>, ) { - if config.censor_hides == Hides::Flooding + 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); @@ -198,7 +237,7 @@ pub enum Speed { } #[derive(Clone, Copy, Debug, Deserialize, PartialEq)] -pub enum Hides { +pub enum Secrecy { Overt, Hiding, Flooding, diff --git a/src/simulation/config.rs b/src/simulation/config.rs index d7a3b23..a9b2ad0 100644 --- a/src/simulation/config.rs +++ b/src/simulation/config.rs @@ -8,7 +8,7 @@ pub struct Config { pub la_net: HyperNet, pub tp_net: HyperNet, // Define censor behavior - pub censor_hides: censor::Hides, + pub censor_secrecy: censor::Secrecy, pub censor_speed: censor::Speed, pub censor_event_duration: u32, pub censor_totality: censor::Totality, diff --git a/src/simulation/user.rs b/src/simulation/user.rs index 35516c9..b2ac36a 100644 --- a/src/simulation/user.rs +++ b/src/simulation/user.rs @@ -6,7 +6,7 @@ use crate::{ positive_report::PositiveReport, simulation::{ bridge::Bridge, - censor::{Censor, Hides::*, Totality::*}, + censor::{Censor, Secrecy::*, Totality::*}, config::Config, }, BridgeDistributor, @@ -157,7 +157,7 @@ impl User { // Note that this does not involve making a real connection to a // real bridge. The function is async because the *censor* might // submit a positive report during this function. - pub async fn connect(&self, config: &Config, bridge: &mut Bridge, censor: &Censor) -> bool { + pub fn connect(&self, config: &Config, bridge: &mut Bridge, censor: &Censor) -> bool { if censor.blocks_bridge(config, &bridge.fingerprint) { if config.censor_totality == Full || config.censor_totality == Partial @@ -165,7 +165,7 @@ impl User { { // If censor tries to hide its censorship, record a // false connection - if config.censor_hides == Hiding { + if config.censor_secrecy == Hiding { bridge.connect_total(); } @@ -179,15 +179,6 @@ impl User { if event_happens(config.prob_user_treats_throttling_as_blocking) { bridge.connect_total(); - // A Hiding censor does not make an additional - // connection here, but it will make a false - // positive report if possible. - if config.censor_hides == Hiding && censor.has_lox_cred(&bridge.fingerprint) { - censor - .send_positive_report(config, &bridge.fingerprint) - .await; - } - // Return false because there was interference // detected in the connection return false; @@ -328,16 +319,13 @@ impl User { for i in 0..bucket.len() { // At level 0, we only have 1 bridge if bucket[i] != BridgeLine::default() { - if self - .connect( - &config, - bridges - .get_mut(&bucket[i].get_hashed_fingerprint()) - .unwrap(), - &censor, - ) - .await - { + if self.connect( + &config, + bridges + .get_mut(&bucket[i].get_hashed_fingerprint()) + .unwrap(), + &censor, + ) { succeeded.push(bucket[i]); } else { failed.push(bucket[i]); @@ -378,16 +366,13 @@ impl User { ); } // Attempt to connect to second cred's bridge - if self - .connect( - &config, - bridges - .get_mut(&bridgeline.get_hashed_fingerprint()) - .unwrap(), - censor, - ) - .await - { + if self.connect( + &config, + bridges + .get_mut(&bridgeline.get_hashed_fingerprint()) + .unwrap(), + censor, + ) { succeeded.push(bridgeline); if second_reachcred.is_some() && eligible_for_trust_promotion(&config.la_net, &second_cred).await