Reduce number of unnecessary censor users for efficiency
This commit is contained in:
parent
d03f86d4f6
commit
642827e228
|
@ -10,6 +10,7 @@ anyhow = "1.0"
|
||||||
array-bytes = "6.2.0"
|
array-bytes = "6.2.0"
|
||||||
bincode = "1"
|
bincode = "1"
|
||||||
clap = { version = "4.4.14", features = ["derive"] }
|
clap = { version = "4.4.14", features = ["derive"] }
|
||||||
|
curve25519-dalek = { version = "4", default-features = false }
|
||||||
hyper = { version = "0.14.28", features = ["full"] }
|
hyper = { version = "0.14.28", features = ["full"] }
|
||||||
lox_cli = { git = "https://git-crysp.uwaterloo.ca/vvecna/lox_cli.git", version = "0.1" }
|
lox_cli = { git = "https://git-crysp.uwaterloo.ca/vvecna/lox_cli.git", version = "0.1" }
|
||||||
lox-library = { git = "https://gitlab.torproject.org/vecna/lox.git", version = "0.1.0" }
|
lox-library = { git = "https://gitlab.torproject.org/vecna/lox.git", version = "0.1.0" }
|
||||||
|
|
|
@ -86,4 +86,14 @@ impl Bridge {
|
||||||
self.real_connections = 0;
|
self.real_connections = 0;
|
||||||
self.total_connections = 0;
|
self.total_connections = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Has this bridge been distributed to a non-censor user?
|
||||||
|
pub fn has_been_distributed(&self) -> bool {
|
||||||
|
self.first_real_user > 0
|
||||||
|
}
|
||||||
|
|
||||||
|
// Does Troll Patrol think this bridge is blocked?
|
||||||
|
pub fn troll_patrol_blocked(&self) -> bool {
|
||||||
|
self.first_detected_blocked > 0
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
use crate::{bridge::Bridge, config::Config};
|
use crate::{bridge::Bridge, config::Config};
|
||||||
|
|
||||||
|
use curve25519_dalek::scalar::Scalar;
|
||||||
use lox_cli::{get_lox_pub, networking::Networking};
|
use lox_cli::{get_lox_pub, networking::Networking};
|
||||||
use lox_library::{cred::Lox, scalar_u32};
|
use lox_library::{cred::Lox, scalar_u32};
|
||||||
use rand::Rng;
|
use rand::Rng;
|
||||||
|
@ -24,6 +25,12 @@ pub struct Censor {
|
||||||
// credentials we have for this bridge).
|
// credentials we have for this bridge).
|
||||||
pub lox_credentials: HashMap<[u8; 20], (Lox, u32)>,
|
pub lox_credentials: HashMap<[u8; 20], (Lox, u32)>,
|
||||||
|
|
||||||
|
// Map of buckets to count of censor users with that bucket. Note
|
||||||
|
// that this is the count of users that have *ever* had that bucket,
|
||||||
|
// so this variable should NOT be used to count the overall number
|
||||||
|
// of censor agents.
|
||||||
|
pub agents: HashMap<Scalar, u32>,
|
||||||
|
|
||||||
// If censor implements random blocking, this is the date when it
|
// If censor implements random blocking, this is the date when it
|
||||||
// will start blocking all the bridges it knows.
|
// will start blocking all the bridges it knows.
|
||||||
pub delay_date: u32,
|
pub delay_date: u32,
|
||||||
|
@ -52,6 +59,7 @@ impl Censor {
|
||||||
start_date,
|
start_date,
|
||||||
known_bridges: HashSet::<[u8; 20]>::new(),
|
known_bridges: HashSet::<[u8; 20]>::new(),
|
||||||
lox_credentials: HashMap::<[u8; 20], (Lox, u32)>::new(),
|
lox_credentials: HashMap::<[u8; 20], (Lox, u32)>::new(),
|
||||||
|
agents: HashMap::<Scalar, u32>::new(),
|
||||||
delay_date: delay_date,
|
delay_date: delay_date,
|
||||||
partial_blocking_percent: partial_blocking_percent,
|
partial_blocking_percent: partial_blocking_percent,
|
||||||
}
|
}
|
||||||
|
@ -116,6 +124,25 @@ impl Censor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Get the number of agents the censor has with a given bucket
|
||||||
|
pub fn num_agents(&self, bucket: &Scalar) -> u32 {
|
||||||
|
match self.agents.get(bucket) {
|
||||||
|
Some(v) => *v,
|
||||||
|
None => 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add to the number of agents a censor has for a given bucket
|
||||||
|
pub fn add_agent(&mut self, bucket: &Scalar) {
|
||||||
|
self.agents.insert(
|
||||||
|
*bucket,
|
||||||
|
match self.agents.get(bucket) {
|
||||||
|
Some(v) => *v + 1,
|
||||||
|
None => 1,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// Censor sends a positive report for the given bridge. Returns true
|
// Censor sends a positive report for the given bridge. Returns true
|
||||||
// if successful, false otherwise.
|
// if successful, false otherwise.
|
||||||
pub async fn send_positive_report(&self, config: &Config, fingerprint: &[u8; 20]) -> bool {
|
pub async fn send_positive_report(&self, config: &Config, fingerprint: &[u8; 20]) -> bool {
|
||||||
|
@ -158,11 +185,8 @@ impl Censor {
|
||||||
{
|
{
|
||||||
let bridge = bridges.get_mut(fingerprint).unwrap();
|
let bridge = bridges.get_mut(fingerprint).unwrap();
|
||||||
|
|
||||||
// A large number
|
|
||||||
let num_connections = 30000;
|
|
||||||
|
|
||||||
// Make a bunch of connections to the bridge
|
// Make a bunch of connections to the bridge
|
||||||
bridge.censor_flood(num_connections);
|
bridge.censor_flood(config.censor_max_connections);
|
||||||
|
|
||||||
// If we have a lv3+ credential, submit a bunch of
|
// If we have a lv3+ credential, submit a bunch of
|
||||||
// positive reports
|
// positive reports
|
||||||
|
@ -176,11 +200,9 @@ impl Censor {
|
||||||
// detection algorithm. In practice, the censor
|
// detection algorithm. In practice, the censor
|
||||||
// should submit as many reports as possible.
|
// should submit as many reports as possible.
|
||||||
let num_prs = if config.one_positive_report_per_cred {
|
let num_prs = if config.one_positive_report_per_cred {
|
||||||
// *cred_count
|
min(*cred_count, config.censor_max_pr)
|
||||||
min(*cred_count, 25)
|
|
||||||
} else {
|
} else {
|
||||||
//30000
|
config.censor_max_pr
|
||||||
25
|
|
||||||
};
|
};
|
||||||
for _ in 0..num_prs {
|
for _ in 0..num_prs {
|
||||||
self.send_positive_report(config, &bridge.fingerprint).await;
|
self.send_positive_report(config, &bridge.fingerprint).await;
|
||||||
|
|
|
@ -10,6 +10,11 @@ pub struct Config {
|
||||||
pub bootstrapping_period_duration: u32,
|
pub bootstrapping_period_duration: u32,
|
||||||
// Define censor behavior
|
// Define censor behavior
|
||||||
pub censor_secrecy: censor::Secrecy,
|
pub censor_secrecy: censor::Secrecy,
|
||||||
|
// The maximum number of connections for the censor to make to each
|
||||||
|
// bridge
|
||||||
|
pub censor_max_connections: u32,
|
||||||
|
// The maximum number of positive reports for the censor to submit
|
||||||
|
pub censor_max_pr: u32,
|
||||||
pub censor_speed: censor::Speed,
|
pub censor_speed: censor::Speed,
|
||||||
pub censor_event_duration: u32,
|
pub censor_event_duration: u32,
|
||||||
pub censor_totality: censor::Totality,
|
pub censor_totality: censor::Totality,
|
||||||
|
|
29
src/main.rs
29
src/main.rs
|
@ -43,6 +43,8 @@ pub struct Config {
|
||||||
pub tp_test_port: u16,
|
pub tp_test_port: u16,
|
||||||
pub bootstrapping_period_duration: u32,
|
pub bootstrapping_period_duration: u32,
|
||||||
pub censor_secrecy: censor::Secrecy,
|
pub censor_secrecy: censor::Secrecy,
|
||||||
|
pub censor_max_connections: u32,
|
||||||
|
pub censor_max_pr: u32,
|
||||||
pub censor_speed: censor::Speed,
|
pub censor_speed: censor::Speed,
|
||||||
pub censor_event_duration: u32,
|
pub censor_event_duration: u32,
|
||||||
pub censor_totality: censor::Totality,
|
pub censor_totality: censor::Totality,
|
||||||
|
@ -95,6 +97,8 @@ pub async fn main() {
|
||||||
tp_net,
|
tp_net,
|
||||||
bootstrapping_period_duration: config.bootstrapping_period_duration,
|
bootstrapping_period_duration: config.bootstrapping_period_duration,
|
||||||
censor_secrecy: config.censor_secrecy,
|
censor_secrecy: config.censor_secrecy,
|
||||||
|
censor_max_connections: config.censor_max_connections,
|
||||||
|
censor_max_pr: config.censor_max_pr,
|
||||||
censor_speed: config.censor_speed,
|
censor_speed: config.censor_speed,
|
||||||
censor_event_duration: config.censor_event_duration,
|
censor_event_duration: config.censor_event_duration,
|
||||||
censor_totality: config.censor_totality,
|
censor_totality: config.censor_totality,
|
||||||
|
@ -207,13 +211,23 @@ pub async fn main() {
|
||||||
users.shuffle(&mut rng);
|
users.shuffle(&mut rng);
|
||||||
|
|
||||||
// Users do daily actions
|
// Users do daily actions
|
||||||
for user in &mut users {
|
let mut i = 0;
|
||||||
let invited_friends = user
|
while i < users.len() {
|
||||||
|
let user = users.get_mut(i).unwrap();
|
||||||
|
if let Ok((mut invited_friends, remove_user)) = user
|
||||||
.daily_tasks(&sconfig, &mut bridges, &mut censor, &mut invites)
|
.daily_tasks(&sconfig, &mut bridges, &mut censor, &mut invites)
|
||||||
.await;
|
.await
|
||||||
|
{
|
||||||
|
// We remove censor users once they stop serving a purpose
|
||||||
|
if remove_user {
|
||||||
|
// This removes the user and replaces them with the
|
||||||
|
// last element of the vector, for efficiency. This
|
||||||
|
// is fine to do because the users act in a random
|
||||||
|
// order anyway.
|
||||||
|
users.swap_remove(i);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
if invited_friends.is_ok() {
|
|
||||||
let mut invited_friends = invited_friends.unwrap();
|
|
||||||
if invited_friends.len() > 0 {
|
if invited_friends.len() > 0 {
|
||||||
new_users.append(&mut invited_friends);
|
new_users.append(&mut invited_friends);
|
||||||
}
|
}
|
||||||
|
@ -228,6 +242,11 @@ pub async fn main() {
|
||||||
count_users_cannot_connect += 1;
|
count_users_cannot_connect += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Iterate loop (note that we do not reach this if we remove
|
||||||
|
// a user, so we'll get the replacement user at that same
|
||||||
|
// index)
|
||||||
|
i += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Also count number of new users with/without connections
|
// Also count number of new users with/without connections
|
||||||
|
|
267
src/user.rs
267
src/user.rs
|
@ -46,6 +46,64 @@ pub fn give_bucket_to_censor(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if bucket is blocked, according to the LA (regardless of
|
||||||
|
// whether the censor actually blocks the bridges)
|
||||||
|
pub fn bucket_blocked_lox(bucket: &[BridgeLine], bridges: &HashMap<[u8; 20], Bridge>) -> bool {
|
||||||
|
// Count number of non-default bridges (either 1 or 3)
|
||||||
|
let mut num_real_bridges = 0;
|
||||||
|
let mut num_blocked_bridges = 0;
|
||||||
|
|
||||||
|
for bridge in bucket {
|
||||||
|
if *bridge != BridgeLine::default() {
|
||||||
|
match bridges.get(&bridge.get_hashed_fingerprint()) {
|
||||||
|
Some(b) => {
|
||||||
|
num_real_bridges += 1;
|
||||||
|
if b.troll_patrol_blocked() {
|
||||||
|
num_blocked_bridges += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// Something went wrong, I guess
|
||||||
|
println!(
|
||||||
|
"Tried to check if bridge was blocked before it was added to simulation"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Return true if open-entry bucket with a blocked bridge or
|
||||||
|
// invite-only bucket with 2+ blocked bridges
|
||||||
|
num_real_bridges == 1 && num_blocked_bridges == 1
|
||||||
|
|| num_real_bridges == 3 && num_blocked_bridges >= 2
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check if bucket contains a bridge that has ever been distributed to a
|
||||||
|
// real user
|
||||||
|
pub fn bucket_has_been_distributed(
|
||||||
|
bucket: &[BridgeLine],
|
||||||
|
bridges: &HashMap<[u8; 20], Bridge>,
|
||||||
|
) -> bool {
|
||||||
|
for bridge in bucket {
|
||||||
|
if *bridge != BridgeLine::default() {
|
||||||
|
match bridges.get(&bridge.get_hashed_fingerprint()) {
|
||||||
|
Some(b) => {
|
||||||
|
if b.has_been_distributed() {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
// Something went wrong, I guess
|
||||||
|
println!(
|
||||||
|
"Tried to check if bridge had been distributed before it was added to simulation"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
pub struct User {
|
pub struct User {
|
||||||
// Does this user cooperate with a censor?
|
// Does this user cooperate with a censor?
|
||||||
pub is_censor: bool,
|
pub is_censor: bool,
|
||||||
|
@ -123,6 +181,30 @@ impl User {
|
||||||
if is_censor {
|
if is_censor {
|
||||||
// Give bridges to censor
|
// Give bridges to censor
|
||||||
give_bucket_to_censor(&bucket, bridges, censor);
|
give_bucket_to_censor(&bucket, bridges, censor);
|
||||||
|
|
||||||
|
// Various conditions to avoid creating censor users if we don't need to
|
||||||
|
|
||||||
|
// If the bucket is already marked blocked, don't create this user
|
||||||
|
if bucket_blocked_lox(&bucket, bridges) {
|
||||||
|
return Err(anyhow!("Bucket blocked, don't create new censor user"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the bucket has never been distributed to a real user, don't create this user
|
||||||
|
if !bucket_has_been_distributed(&bucket, bridges) {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"Bucket never distributed to a real user, don't create new censor user"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we already have enough agents with this bucket, don't create this user
|
||||||
|
if censor.num_agents(&result.primary_cred.bucket) > config.censor_max_pr {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"We already have enough censor users with this bucket"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we haven't returned yet, add this user to censor's list
|
||||||
|
censor.add_agent(&result.primary_cred.bucket);
|
||||||
} else {
|
} else {
|
||||||
// Test bridges to see if they work
|
// Test bridges to see if they work
|
||||||
let (s, f) = result.test_bridges(&bucket, config, bridges, censor);
|
let (s, f) = result.test_bridges(&bucket, config, bridges, censor);
|
||||||
|
@ -229,6 +311,23 @@ impl User {
|
||||||
|
|
||||||
if is_censor {
|
if is_censor {
|
||||||
give_bucket_to_censor(&bucket, bridges, censor);
|
give_bucket_to_censor(&bucket, bridges, censor);
|
||||||
|
|
||||||
|
// Various conditions to avoid creating censor users unnecessarily
|
||||||
|
|
||||||
|
// If the bucket is already marked blocked, don't create this user
|
||||||
|
if bucket_blocked_lox(&bucket, bridges) {
|
||||||
|
return Err(anyhow!("Bucket blocked, don't create new censor user"));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we already have enough agents with this bucket, don't create this user
|
||||||
|
if censor.num_agents(&result.primary_cred.bucket) > config.censor_max_pr {
|
||||||
|
return Err(anyhow!(
|
||||||
|
"We already have enough censor users with this bucket"
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
// If we haven't returned yet, add this user to censor's list
|
||||||
|
censor.add_agent(&result.primary_cred.bucket);
|
||||||
} else {
|
} else {
|
||||||
let (s, f) = result.test_bridges(&bucket, config, bridges, censor);
|
let (s, f) = result.test_bridges(&bucket, config, bridges, censor);
|
||||||
|
|
||||||
|
@ -411,12 +510,17 @@ impl User {
|
||||||
bridges: &mut HashMap<[u8; 20], Bridge>,
|
bridges: &mut HashMap<[u8; 20], Bridge>,
|
||||||
censor: &mut Censor,
|
censor: &mut Censor,
|
||||||
invites: &mut Vec<Invitation>,
|
invites: &mut Vec<Invitation>,
|
||||||
) -> Result<Vec<User>> {
|
) -> Result<(Vec<User>, bool)> {
|
||||||
if self.is_censor {
|
if self.is_censor {
|
||||||
self.daily_tasks_censor(config, bridges, censor).await
|
self.daily_tasks_censor(config, bridges, censor).await
|
||||||
} else {
|
} else {
|
||||||
self.daily_tasks_non_censor(config, bridges, censor, invites)
|
match self
|
||||||
|
.daily_tasks_non_censor(config, bridges, censor, invites)
|
||||||
.await
|
.await
|
||||||
|
{
|
||||||
|
Ok(users) => Ok((users, false)),
|
||||||
|
Err(e) => Err(e),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -756,13 +860,15 @@ impl User {
|
||||||
}
|
}
|
||||||
|
|
||||||
// User cooperates with censor and performs daily tasks to try to
|
// User cooperates with censor and performs daily tasks to try to
|
||||||
// learn more bridges.
|
// learn more bridges. Returns a vector of newly invited users
|
||||||
|
// and a boolean indicating whether this censor user should be
|
||||||
|
// removed from the global user set (for efficiency).
|
||||||
pub async fn daily_tasks_censor(
|
pub async fn daily_tasks_censor(
|
||||||
&mut self,
|
&mut self,
|
||||||
config: &Config,
|
config: &Config,
|
||||||
bridges: &mut HashMap<[u8; 20], Bridge>,
|
bridges: &mut HashMap<[u8; 20], Bridge>,
|
||||||
censor: &mut Censor,
|
censor: &mut Censor,
|
||||||
) -> Result<Vec<User>> {
|
) -> Result<(Vec<User>, bool)> {
|
||||||
// Download bucket to see if bridge is still reachable and if we
|
// Download bucket to see if bridge is still reachable and if we
|
||||||
// have any new bridges
|
// have any new bridges
|
||||||
let (bucket, reachcred) = get_bucket(&config.la_net, &self.primary_cred).await?;
|
let (bucket, reachcred) = get_bucket(&config.la_net, &self.primary_cred).await?;
|
||||||
|
@ -770,14 +876,52 @@ impl User {
|
||||||
|
|
||||||
// Make sure each bridge is in global bridges set and known by
|
// Make sure each bridge is in global bridges set and known by
|
||||||
// censor
|
// censor
|
||||||
for bridgeline in bucket {
|
give_bucket_to_censor(&bucket, bridges, censor);
|
||||||
if bridgeline != BridgeLine::default() {
|
|
||||||
let fingerprint = bridgeline.get_hashed_fingerprint();
|
// If Lox has marked the bridge blocked, migrate if possible
|
||||||
if !bridges.contains_key(&fingerprint) {
|
if bucket_blocked_lox(&bucket, bridges) {
|
||||||
let bridge = Bridge::from_bridge_line(&bridgeline);
|
// If we can migrate, migrate
|
||||||
bridges.insert(fingerprint, bridge);
|
if level >= MIN_TRUST_LEVEL {
|
||||||
|
if let Ok(migcred) = check_blockage(
|
||||||
|
&config.la_net,
|
||||||
|
&self.primary_cred,
|
||||||
|
get_lox_pub(&config.la_pubkeys),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
if let Ok(cred) = blockage_migration(
|
||||||
|
&config.la_net,
|
||||||
|
&self.primary_cred,
|
||||||
|
&migcred,
|
||||||
|
get_lox_pub(&config.la_pubkeys),
|
||||||
|
get_migration_pub(&config.la_pubkeys),
|
||||||
|
)
|
||||||
|
.await
|
||||||
|
{
|
||||||
|
// Successfully migrated!
|
||||||
|
|
||||||
|
// Update credential
|
||||||
|
self.primary_cred = cred;
|
||||||
|
|
||||||
|
// You can't migrate to level 3 or 4, so the
|
||||||
|
// censor doesn't want this new credential
|
||||||
|
|
||||||
|
// Download bucket to see if bridge is still
|
||||||
|
// reachable and if we have any new bridges
|
||||||
|
let (bucket, _reachcred) =
|
||||||
|
get_bucket(&config.la_net, &self.primary_cred).await?;
|
||||||
|
|
||||||
|
// Give new bucket to censor
|
||||||
|
give_bucket_to_censor(&bucket, bridges, censor);
|
||||||
|
|
||||||
|
// Add this user to censor's list
|
||||||
|
censor.add_agent(&self.primary_cred.bucket);
|
||||||
}
|
}
|
||||||
censor.learn_bridge(&fingerprint);
|
}
|
||||||
|
} else {
|
||||||
|
// We can't migrate, and we can't level up or anything.
|
||||||
|
// Mark this user for deletion.
|
||||||
|
return Ok((Vec::<User>::new(), true));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -788,7 +932,7 @@ impl User {
|
||||||
&& eligible_for_level_up(&config.la_net, &self.primary_cred).await
|
&& eligible_for_level_up(&config.la_net, &self.primary_cred).await
|
||||||
{
|
{
|
||||||
let new_cred = if level == 0 {
|
let new_cred = if level == 0 {
|
||||||
trust_migration(
|
let nc = trust_migration(
|
||||||
&config.la_net,
|
&config.la_net,
|
||||||
&self.primary_cred,
|
&self.primary_cred,
|
||||||
&trust_promotion(
|
&trust_promotion(
|
||||||
|
@ -800,7 +944,13 @@ impl User {
|
||||||
get_lox_pub(&config.la_pubkeys),
|
get_lox_pub(&config.la_pubkeys),
|
||||||
get_migration_pub(&config.la_pubkeys),
|
get_migration_pub(&config.la_pubkeys),
|
||||||
)
|
)
|
||||||
.await?
|
.await?;
|
||||||
|
|
||||||
|
// We now have a new bucket value, so add the user to censor's list
|
||||||
|
censor.add_agent(&nc.bucket);
|
||||||
|
|
||||||
|
// New credential as new_cred
|
||||||
|
nc
|
||||||
} else {
|
} else {
|
||||||
level_up(
|
level_up(
|
||||||
&config.la_net,
|
&config.la_net,
|
||||||
|
@ -834,96 +984,7 @@ impl User {
|
||||||
censor.give_lox_cred(&fingerprint, &self.primary_cred, false);
|
censor.give_lox_cred(&fingerprint, &self.primary_cred, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
// LA has identified this bucket as blocked. This change
|
|
||||||
// will not be reverted, so either migrate or replace the
|
|
||||||
// primary credential with a new level 0 credential and work
|
|
||||||
// on gaining trust for that one.
|
|
||||||
|
|
||||||
// Migrate if able
|
|
||||||
if level >= MIN_TRUST_LEVEL {
|
|
||||||
if let Ok(migcred) = check_blockage(
|
|
||||||
&config.la_net,
|
|
||||||
&self.primary_cred,
|
|
||||||
get_lox_pub(&config.la_pubkeys),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
if let Ok(cred) = blockage_migration(
|
|
||||||
&config.la_net,
|
|
||||||
&self.primary_cred,
|
|
||||||
&migcred,
|
|
||||||
get_lox_pub(&config.la_pubkeys),
|
|
||||||
get_migration_pub(&config.la_pubkeys),
|
|
||||||
)
|
|
||||||
.await
|
|
||||||
{
|
|
||||||
self.primary_cred = cred;
|
|
||||||
|
|
||||||
// You can't migrate to level 3 or 4, so the
|
|
||||||
// censor doesn't want this new credential
|
|
||||||
|
|
||||||
// Download bucket to see if bridge is still
|
|
||||||
// reachable and if we have any new bridges
|
|
||||||
let (bucket, _reachcred) =
|
|
||||||
get_bucket(&config.la_net, &self.primary_cred).await?;
|
|
||||||
|
|
||||||
// Make sure each bridge is in global bridges
|
|
||||||
// set and known by censor
|
|
||||||
for bridgeline in bucket {
|
|
||||||
if bridgeline != BridgeLine::default() {
|
|
||||||
let fingerprint = bridgeline.get_hashed_fingerprint();
|
|
||||||
if !bridges.contains_key(&fingerprint) {
|
|
||||||
let bridge = Bridge::from_bridge_line(&bridgeline);
|
|
||||||
bridges.insert(fingerprint, bridge);
|
|
||||||
}
|
}
|
||||||
censor.learn_bridge(&fingerprint);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Removing this case for efficiency. If the censor is in
|
|
||||||
// play, we just assume it wins the open-entry game and stop
|
|
||||||
// distributing open-entry invites altogether.
|
|
||||||
/*
|
|
||||||
} else {
|
|
||||||
// If unable to migrate, try to get a new open-entry
|
|
||||||
// credential and start over
|
|
||||||
let res = Self::get_new_credential(&config).await;
|
|
||||||
if res.is_ok() {
|
|
||||||
let (new_cred, bl) = res.unwrap();
|
|
||||||
let fingerprint = bl.get_hashed_fingerprint();
|
|
||||||
if !bridges.contains_key(&fingerprint) {
|
|
||||||
let bridge = Bridge::from_bridge_line(&bl);
|
|
||||||
bridges.insert(fingerprint, bridge);
|
|
||||||
}
|
|
||||||
censor.learn_bridge(&fingerprint);
|
|
||||||
// Censor doesn't want new_cred yet
|
|
||||||
self.primary_cred = new_cred;
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Also removing this case for efficiency.
|
|
||||||
/*
|
|
||||||
// Separately from primary credential, censor user requests a
|
|
||||||
// new secondary credential each day just to block the
|
|
||||||
// open-entry bridges. This is stored but not reused.
|
|
||||||
let res = Self::get_new_credential(&config).await;
|
|
||||||
if res.is_ok() {
|
|
||||||
let (_new_cred, bl) = res.unwrap();
|
|
||||||
let fingerprint = bl.get_hashed_fingerprint();
|
|
||||||
if !bridges.contains_key(&fingerprint) {
|
|
||||||
let bridge = Bridge::from_bridge_line(&bl);
|
|
||||||
bridges.insert(fingerprint, bridge);
|
|
||||||
}
|
|
||||||
censor.learn_bridge(&fingerprint);
|
|
||||||
// Censor doesn't want new_cred. User doesn't actually use
|
|
||||||
// secondary_cred, so don't store it.
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// Censor user invites as many censor friends as possible
|
// Censor user invites as many censor friends as possible
|
||||||
let invitations = scalar_u32(&self.primary_cred.invites_remaining).unwrap();
|
let invitations = scalar_u32(&self.primary_cred.invites_remaining).unwrap();
|
||||||
|
@ -945,6 +1006,6 @@ impl User {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(new_friends)
|
Ok((new_friends, false))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue