From 362996c4f7cfed64a149a3846319b1b95b0d5f24 Mon Sep 17 00:00:00 2001 From: onyinyang Date: Mon, 3 Apr 2023 11:47:11 -0400 Subject: [PATCH] Add fingerprint field to Bridgeline --- crates/lox-library/src/bridge_table.rs | 25 ++++++++++++++++--------- crates/lox-library/src/lib.rs | 20 +++++++++++++++++--- crates/lox-library/src/tests.rs | 13 ++++++------- 3 files changed, 39 insertions(+), 19 deletions(-) diff --git a/crates/lox-library/src/bridge_table.rs b/crates/lox-library/src/bridge_table.rs index d13accc..6a22cf3 100644 --- a/crates/lox-library/src/bridge_table.rs +++ b/crates/lox-library/src/bridge_table.rs @@ -25,7 +25,7 @@ use std::convert::TryInto; use subtle::ConstantTimeEq; /// Each bridge information line is serialized into this many bytes -pub const BRIDGE_BYTES: usize = 300; +pub const BRIDGE_BYTES: usize = 260; /// The max number of bridges per bucket pub const MAX_BRIDGES_PER_BUCKET: usize = 3; @@ -44,10 +44,13 @@ pub struct BridgeLine { pub addr: [u8; 16], /// port pub port: u16, + /// fingerprint + #[serde_as(as = "[_; 40]")] + pub fingerprint: [u8; 40], /// other protocol information, including pluggable transport, /// public key, etc. - #[serde_as(as = "[_; BRIDGE_BYTES - 18]")] - pub info: [u8; BRIDGE_BYTES - 18], + #[serde_as(as = "[_; BRIDGE_BYTES - 58]")] + pub info: [u8; BRIDGE_BYTES - 58], } /// A bucket contains MAX_BRIDGES_PER_BUCKET bridges plus the @@ -70,7 +73,8 @@ impl Default for BridgeLine { Self { addr: [0; 16], port: 0, - info: [0; BRIDGE_BYTES - 18], + fingerprint: [0; 40], + info: [0; BRIDGE_BYTES - 58], } } } @@ -81,7 +85,8 @@ impl BridgeLine { let mut res: [u8; BRIDGE_BYTES] = [0; BRIDGE_BYTES]; res[0..16].copy_from_slice(&self.addr); res[16..18].copy_from_slice(&self.port.to_be_bytes()); - res[18..].copy_from_slice(&self.info); + res[18..58].copy_from_slice(&self.fingerprint); + res[58..].copy_from_slice(&self.info); res } /// Decode a BridgeLine from a byte array @@ -89,7 +94,8 @@ impl BridgeLine { let mut res: Self = Default::default(); res.addr.copy_from_slice(&data[0..16]); res.port = u16::from_be_bytes(data[16..18].try_into().unwrap()); - res.info.copy_from_slice(&data[18..]); + res.fingerprint.copy_from_slice(&data[18..58]); + res.info.copy_from_slice(&data[58..]); res } /// Encode a bucket to a byte array, including a Bucket Reachability @@ -188,13 +194,14 @@ impl BridgeLine { let ports: [u16; 4] = [443, 4433, 8080, 43079]; let portidx = (rng.next_u32() % 4) as usize; res.port = ports[portidx]; - let mut fingerprint: [u8; 20] = [0; 20]; + let mut fingerprint: [u8; 40] = [0; 40]; + rng.fill_bytes(&mut fingerprint); let mut cert: [u8; 52] = [0; 52]; rng.fill_bytes(&mut fingerprint); + res.fingerprint[0..40].copy_from_slice(&fingerprint); rng.fill_bytes(&mut cert); let infostr: String = format!( - "obfs4 {} cert={} iat-mode=0", - hex_fmt::HexFmt(fingerprint), + "obfs4 cert={}, iat-mode=0", base64::encode_config(cert, base64::STANDARD_NO_PAD) ); res.info[..infostr.len()].copy_from_slice(infostr.as_bytes()); diff --git a/crates/lox-library/src/lib.rs b/crates/lox-library/src/lib.rs index 3f42317..5c78e30 100644 --- a/crates/lox-library/src/lib.rs +++ b/crates/lox-library/src/lib.rs @@ -309,6 +309,17 @@ impl BridgeAuth { self.bridge_table.spares.insert(bnum); } + pub fn sync_table(&mut self) { + + // Create a hashtable (?) of bridges in the lox distributor from new resources + // accept the hashtable and recreate the bridge table from the hash table here + // using existing reachable bridges, other table checks and placements from existing bridge table + // If bridges are in reachable bridges, put them in the table with their Vec + // How to check for bridges that aren't there/are extra? + // After going through the update, make sure bridges in the table are the same and deal with discrepencies + // This will be the bad/annoying part + } + // 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 @@ -316,11 +327,11 @@ impl BridgeAuth { // 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.fingerprint == bridge.fingerprint { println!( "Bridge from table: {:?} has same IP and Port as bridge {:?}!", reachable_bridge.0, bridge @@ -342,6 +353,9 @@ impl BridgeAuth { != reachable_bridge.0 ); } + res = true; + } else { + return res; } // We must also remove the old bridge from the reachable bridges table // and add the new bridge @@ -349,7 +363,7 @@ impl BridgeAuth { self.bridge_table .reachable .insert(*bridge, reachable_bridge.1); - res = true; + return res; } } diff --git a/crates/lox-library/src/tests.rs b/crates/lox-library/src/tests.rs index cedadff..5ca62d9 100644 --- a/crates/lox-library/src/tests.rs +++ b/crates/lox-library/src/tests.rs @@ -615,30 +615,29 @@ fn test_update_bridge() { // Created changed info for bridgeline to be updated to let updated_info = bucket[0]; let infostr: String = format!( - "type={} blocked_in={:?} protocol={} fingerprint={} distribution={}", + "type={} blocked_in={:?} protocol={} 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]; + let mut updated_info_bytes: [u8; BRIDGE_BYTES - 58] = [0; BRIDGE_BYTES - 58]; 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, + fingerprint: bridgeline_to_update.fingerprint, 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 {:?}", + updated_bridgeline.fingerprint == bridgeline_to_update.fingerprint, + "Bridge entering the bridgepool {:?} did not have the same fingerprint as the updating bridge {:?}", bridgeline_to_update, - updated_bridgeline.addr + updated_bridgeline.fingerprint ); - 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 {:?}",