diff --git a/crates/lox-library/src/lib.rs b/crates/lox-library/src/lib.rs index 76d94b7..3f42317 100644 --- a/crates/lox-library/src/lib.rs +++ b/crates/lox-library/src/lib.rs @@ -312,37 +312,44 @@ impl BridgeAuth { // Update the details of a bridge in the bridge table. This assumes that the IP and Port // of a given bridge remains the same and thus can be updated. // First we must retrieve the list of reachable bridges, then we must search for any matching our partial key - // which will include the IP and Port. Then we can replace the original bridge with the updated bridge or else - // or else just replace the info field. + // which will include the IP and Port. Then we can replace the original bridge with the updated bridge + // Returns true if the bridge has successfully updated pub fn bridge_update(&mut self, bridge: &BridgeLine) -> bool { let mut res: bool = false; //default False to assume that update failed - //Needs to be updated since bridge will only match on some fields. + //Needs to be updated since bridge will only match on some fields. + let reachable_bridges = self.bridge_table.reachable.clone(); for reachable_bridge in reachable_bridges { - if (reachable_bridge.0.addr == bridge.addr && reachable_bridge.0.port == bridge.port) { + if reachable_bridge.0.addr == bridge.addr && reachable_bridge.0.port == bridge.port { println!( "Bridge from table: {:?} has same IP and Port as bridge {:?}!", reachable_bridge.0, bridge ); - // Search actual table for bridge - let updating_bridge = self - .bridge_table - .reachable - .get_key_value(&reachable_bridge.0); - if let Some(v) = updating_bridge { - let mut w = *v.0; - w.info = bridge.info; - println!( - "Now bridge v: {:?} matches the passed bridge {:?}?", - v.0, bridge - ); - if v.0 == bridge { - println!("Yay"); - res = true; - } else { - println!("Boo"); + // Now we must remove the old bridge from the table and insert the new bridge in its place + // i.e., in the same bucket and with the same permissions. + let positions = self.bridge_table.reachable.get(&reachable_bridge.0); + if let Some(v) = positions { + for (bucketnum, offset) in v.iter() { + println!("Bucket num: {:?} and offset: {:?}", bucketnum, offset); + assert!( + self.bridge_table.buckets[*bucketnum as usize][*offset] + == reachable_bridge.0 + ); + self.bridge_table.buckets[*bucketnum as usize][*offset] = *bridge; + assert!(self.bridge_table.buckets[*bucketnum as usize][*offset] == *bridge); + assert!( + self.bridge_table.buckets[*bucketnum as usize][*offset] + != reachable_bridge.0 + ); } } + // We must also remove the old bridge from the reachable bridges table + // and add the new bridge + self.bridge_table.reachable.remove(&reachable_bridge.0); + self.bridge_table + .reachable + .insert(*bridge, reachable_bridge.1); + res = true; } } diff --git a/crates/lox-library/src/tests.rs b/crates/lox-library/src/tests.rs index d69bc22..cedadff 100644 --- a/crates/lox-library/src/tests.rs +++ b/crates/lox-library/src/tests.rs @@ -1,7 +1,7 @@ /*! Unit tests that require access to the testing-only function BridgeLine::random() or private fields */ -use super::bridge_table::BridgeLine; +use super::bridge_table::{BridgeLine, BRIDGE_BYTES}; use super::proto::*; use super::*; use chrono::{DateTime, NaiveTime, Timelike, Utc}; @@ -598,6 +598,91 @@ fn test_redeem_invite() { println!("bob_cred = {:?}", bob_cred); } +#[test] +fn test_update_bridge() { + let mut th = TestHarness::new(); + // Add new bridge to table with known values, + // check that I can find and update the values and that everything else stays the same + + // Create 3 bridges to test harness + let bucket = [ + BridgeLine::random(), + BridgeLine::random(), + BridgeLine::random(), + ]; + // Store first bridgeline to update later + let bridgeline_to_update = bucket[0]; + // Created changed info for bridgeline to be updated to + let updated_info = bucket[0]; + let infostr: String = format!( + "type={} blocked_in={:?} protocol={} fingerprint={} distribution={}", + "obfs2 test bridge".to_string(), + {}, + "obfs2".to_string(), + "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890ABCD".to_string(), + "moat".to_string(), + ); + let mut updated_info_bytes: [u8; BRIDGE_BYTES - 18] = [0; BRIDGE_BYTES - 18]; + + updated_info_bytes[..infostr.len()].copy_from_slice(infostr.as_bytes()); + + let updated_bridgeline = BridgeLine { + addr: bridgeline_to_update.addr, + port: bridgeline_to_update.port, + info: updated_info_bytes, + }; + + assert!( + updated_bridgeline.addr == bridgeline_to_update.addr, + "Bridge entering the bridgepool {:?} did not have the same IP as the updating bridge {:?}", + bridgeline_to_update, + updated_bridgeline.addr + ); + assert!(updated_bridgeline.port == bridgeline_to_update.port, "Bridge entering the bridgepool {:?} did not have the same port as the updating bridge {:?}", bridgeline_to_update, updated_bridgeline.port); + assert!(updated_bridgeline.info != bridgeline_to_update.info); + println!( + "Bridge entering the bridgepool {:?} has different info than the updating bridge {:?}", + bridgeline_to_update.info, updated_bridgeline.info + ); + assert!(updated_bridgeline != bridgeline_to_update); + println!("The two bridgelines are not equal before the update"); + + // Add 3 bridges to test harness + th.ba.add_openinv_bridges(bucket, &mut th.bdb); + + println!("Before update spares = {:?}", th.ba.bridge_table.spares); + println!( + "Before update tmig = {:?}", + th.ba.trustup_migration_table.table + ); + println!( + "Before update bmig = {:?}", + th.ba.blockage_migration_table.table + ); + println!("Before update openinv = {:?}\n", th.bdb.openinv_buckets); + + // Update the info of a bridge with matching IP and Port to a bridge in the bridge table + let result = th.ba.bridge_update(&updated_bridgeline); + assert!(result, "Bridge failed to update successfully!!"); + let found_bridge = th + .ba + .bridge_table + .reachable + .get_key_value(&updated_bridgeline); + assert!(*found_bridge.unwrap().0 != bridgeline_to_update); + assert!(*found_bridge.unwrap().0 == updated_bridgeline); + println!("After update spares = {:?}", th.ba.bridge_table.spares); + println!( + "After update tmig = {:?}", + th.ba.trustup_migration_table.table + ); + println!( + "After update bmig = {:?}", + th.ba.blockage_migration_table.table + ); + println!("After update openinv = {:?}\n", th.bdb.openinv_buckets); +} + #[test] fn test_mark_unreachable() { let mut th = TestHarness::new();