Add handling for unaccounted for bridges

This commit is contained in:
onyinyang 2023-10-02 13:51:19 -04:00
parent b6ff0c60e2
commit 89fb0fbf4b
No known key found for this signature in database
GPG Key ID: 156A6435430C2036
6 changed files with 60 additions and 24 deletions

View File

@ -74,7 +74,6 @@ impl LoxServerContext {
pub fn sync_with_bridgetable(&self, resources: ResourceState) { pub fn sync_with_bridgetable(&self, resources: ResourceState) {
// Check if the resource is already in the Lox bridgetable. If it is, it's probably fine // Check if the resource is already in the Lox bridgetable. If it is, it's probably fine
// to replace the existing resource with the incoming one to account for changes // to replace the existing resource with the incoming one to account for changes
let mut unaccounted_for_bridges: Vec<u64> = Vec::new();
let mut accounted_for_bridges: Vec<u64> = Vec::new(); let mut accounted_for_bridges: Vec<u64> = Vec::new();
if let Some(working_resources) = resources.working { if let Some(working_resources) = resources.working {
// ensure all working resources are updated and accounted for // ensure all working resources are updated and accounted for
@ -140,10 +139,39 @@ impl LoxServerContext {
} }
} }
// Make sure that all bridges are accounted for // Make sure that all bridges are accounted for
let ba_clone = self.ba.lock().unwrap(); let mut ba_clone = self.ba.lock().unwrap();
let total_reachable = ba_clone.bridge_table.reachable.len(); let total_reachable = ba_clone.bridge_table.reachable.len();
if total_reachable > accounted_for_bridges.len() { if total_reachable > accounted_for_bridges.len() {
// Search for extra fingerprints, assume those bridges are gone and remove? let unaccounted_for =
ba_clone.find_and_remove_unaccounted_for_bridges(accounted_for_bridges);
for bridgeline in unaccounted_for {
let res = self.replace_with_new(bridgeline);
if res == lox_library::ReplaceSuccess::Replaced {
println!(
"BridgeLine {:?} not found in rdsys update was successfully replaced.",
bridgeline.uid_fingerprint
);
} else if res == lox_library::ReplaceSuccess::NotReplaced {
// Add the bridge to the list of to_be_replaced bridges in the Lox context and try
// again to replace at the next update (nothing changes in the Lox Authority)
println!(
"BridgeLine {:?} not found in rdsys update NOT replaced, saved for next update!",
bridgeline.uid_fingerprint
);
self.new_to_be_replaced_bridge(bridgeline);
} else {
// NotFound
assert!(
res == lox_library::ReplaceSuccess::NotFound,
"ReplaceSuccess incorrectly set"
);
println!(
"BridgeLine {:?} no longer in reachable bridges.",
bridgeline.uid_fingerprint
);
}
}
// Search for extra fingerprints, assume those bridges are gone and remove
} else if total_reachable < accounted_for_bridges.len() { } else if total_reachable < accounted_for_bridges.len() {
println!("Something unexpected occurred: The number of reachable bridges should not be less than those updated from rdsys"); println!("Something unexpected occurred: The number of reachable bridges should not be less than those updated from rdsys");
} }

View File

@ -11,7 +11,7 @@ use super::cred;
use super::IssuerPrivKey; use super::IssuerPrivKey;
use super::CMZ_B_TABLE; use super::CMZ_B_TABLE;
use aes_gcm::aead; use aes_gcm::aead;
use aes_gcm::aead::{Aead, generic_array::GenericArray}; use aes_gcm::aead::{generic_array::GenericArray, Aead};
use aes_gcm::{Aes128Gcm, KeyInit}; use aes_gcm::{Aes128Gcm, KeyInit};
use base64::{engine::general_purpose, Engine as _}; use base64::{engine::general_purpose, Engine as _};
use curve25519_dalek::ristretto::CompressedRistretto; use curve25519_dalek::ristretto::CompressedRistretto;

View File

@ -381,16 +381,19 @@ impl BridgeAuth {
} }
// TODO Ensure synchronization of Lox bridge_table with rdsys // TODO Ensure synchronization of Lox bridge_table with rdsys
pub fn sync_table(&mut self) { pub fn find_and_remove_unaccounted_for_bridges(
// Create a hashtable (?) of bridges in the lox distributor from new resources &mut self,
// accept the hashtable and recreate the bridge table from the hash table here accounted_for_bridges: Vec<u64>,
// using existing reachable bridges, other table checks and placements from existing bridge table ) -> Vec<BridgeLine> {
// If bridges are in reachable bridges, put them in the table with their Vec // If there are expired blockages, separate them from the fresh blockages
// How to check for bridges that aren't there/are extra? let mut unaccounted_for: Vec<BridgeLine> = Vec::new();
// After going through the update, make sure bridges in the table are the same and deal with discrepencies for (k, _v) in self.bridge_table.reachable.clone() {
// This will be the bad/annoying part if !accounted_for_bridges.contains(&k.uid_fingerprint) {
unaccounted_for.push(k);
//also use open_inv_keys and blocked_keys from bridge_table to remove expired keys from table. }
}
unaccounted_for
//use open_inv_keys and blocked_keys from bridge_table to remove expired keys from table.
// make sure this happens before they are removed from the structures in the bridge table // make sure this happens before they are removed from the structures in the bridge table
} }

View File

@ -16,7 +16,7 @@ use curve25519_dalek::scalar::Scalar;
use sha2::Digest; use sha2::Digest;
use sha2::Sha256; use sha2::Sha256;
use aes_gcm::aead::{Aead, generic_array::GenericArray}; use aes_gcm::aead::{generic_array::GenericArray, Aead};
use aes_gcm::{Aes128Gcm, KeyInit}; use aes_gcm::{Aes128Gcm, KeyInit};
use rand::RngCore; use rand::RngCore;

View File

@ -394,17 +394,21 @@ fn test_open_invite() {
assert!(bridgeline == bucket.0[0]); assert!(bridgeline == bucket.0[0]);
} }
#[test] #[test]
fn test_k_invites() { fn test_k_invites() {
let mut th = TestHarness::new(); let mut th = TestHarness::new();
for i in 0..25 { for i in 0..25 {
let _ = th.open_invite(); let _ = th.open_invite();
if (i+1) % OPENINV_K != 0 { if (i + 1) % OPENINV_K != 0 {
assert!(th.bdb.current_k == (i+1)%OPENINV_K, "the current_k should be (i+1)%OPENINV_K"); assert!(
th.bdb.current_k == (i + 1) % OPENINV_K,
"the current_k should be (i+1)%OPENINV_K"
);
} else { } else {
assert!(th.bdb.current_k == OPENINV_K, "the current_k should be OPENINV_K"); assert!(
th.bdb.current_k == OPENINV_K,
"the current_k should be OPENINV_K"
);
} }
} }
} }

View File

@ -10,10 +10,9 @@ pub struct ResourceRequest {
pub resource_types: Vec<String>, pub resource_types: Vec<String>,
} }
#[derive(Serialize, Deserialize, Debug, PartialEq, Eq)] #[derive(Serialize, Deserialize, Debug, PartialEq, Eq)]
pub struct TestResults { pub struct TestResults {
pub last_passed: DateTime<Utc> pub last_passed: DateTime<Utc>,
} }
/// Representation of a bridge resource /// Representation of a bridge resource
@ -105,7 +104,9 @@ mod tests {
let bridge = Resource { let bridge = Resource {
r#type: String::from("scramblesuit"), r#type: String::from("scramblesuit"),
blocked_in: HashMap::new(), blocked_in: HashMap::new(),
test_result: TestResults { last_passed: "2023-05-30T14:20:28Z".parse::<DateTime<Utc>>().unwrap() }, test_result: TestResults {
last_passed: "2023-05-30T14:20:28Z".parse::<DateTime<Utc>>().unwrap(),
},
protocol: String::from("tcp"), protocol: String::from("tcp"),
address: String::from("216.117.3.62"), address: String::from("216.117.3.62"),
port: 63174, port: 63174,
@ -141,7 +142,7 @@ mod tests {
assert_eq!(bridge, res); assert_eq!(bridge, res);
} }
#[test] #[test]
fn deserialize_resource_diff() { fn deserialize_resource_diff() {
let data = r#" let data = r#"
{ {