|
@@ -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,
|