Add functions to recycle and allocate extra bridges

This commit is contained in:
onyinyang 2023-05-08 19:44:36 -04:00
parent 83c7916805
commit 508eaf3bdd
No known key found for this signature in database
GPG Key ID: 156A6435430C2036
3 changed files with 69 additions and 2 deletions

View File

@ -249,6 +249,25 @@ impl BridgeTable {
self.buckets.len()
}
pub fn recycle_bucket(&mut self, bucket: &[BridgeLine; MAX_BRIDGES_PER_BUCKET], index: u32) {
// Pick a random key to encrypt this bucket
let mut rng = rand::thread_rng();
let mut key: [u8; 16] = [0; 16];
rng.fill_bytes(&mut key);
self.keys[index as usize] = key;
self.buckets[index as usize] = *bucket;
for (i, b) in bucket.iter().enumerate() {
if b.port > 0 {
if let Some(v) = self.reachable.get_mut(b) {
v.push((index, i));
} else {
let v = vec![(index, i)];
self.reachable.insert(*b, v);
}
}
}
}
/// Append a new bucket to the bridge table, returning its index
pub fn new_bucket(&mut self, bucket: &[BridgeLine; MAX_BRIDGES_PER_BUCKET]) -> u32 {
// Pick a random key to encrypt this bucket

View File

@ -293,7 +293,14 @@ impl BridgeAuth {
bridges: [BridgeLine; MAX_BRIDGES_PER_BUCKET],
bdb: &mut BridgeDb,
) {
let bnum = self.bridge_table.new_bucket(&bridges);
let bnum: u32;
if self.bridge_table.recyclable.is_empty() {
bnum = self.bridge_table.new_bucket(&bridges);
} else {
bnum = *self.bridge_table.recyclable.iter().next().unwrap();
self.bridge_table.recyclable.remove(&bnum);
self.bridge_table.recycle_bucket(&bridges, bnum)
}
let mut single = [BridgeLine::default(); MAX_BRIDGES_PER_BUCKET];
for b in bridges.iter() {
single[0] = *b;
@ -305,7 +312,14 @@ impl BridgeAuth {
/// Insert a hot spare bucket of bridges
pub fn add_spare_bucket(&mut self, bucket: [BridgeLine; MAX_BRIDGES_PER_BUCKET]) {
let bnum = self.bridge_table.new_bucket(&bucket);
let bnum: u32;
if self.bridge_table.recyclable.is_empty() {
bnum = self.bridge_table.new_bucket(&bucket);
} else {
bnum = *self.bridge_table.recyclable.iter().next().unwrap();
self.bridge_table.recyclable.remove(&bnum);
self.bridge_table.recycle_bucket(&bucket, bnum)
}
self.bridge_table.spares.insert(bnum);
}
@ -320,6 +334,19 @@ impl BridgeAuth {
// This will be the bad/annoying part
}
pub fn allocate_bridges(&mut self, distributor_bridges: &mut Vec<BridgeLine>, bdb: &mut BridgeDb) {
while let Some(bridge) = distributor_bridges.iter().next_back() {
self.bridge_table.unallocated_bridges.push(*bridge)
}
while self.bridge_table.unallocated_bridges.len() >= MAX_BRIDGES_PER_BUCKET {
let mut bucket = [BridgeLine::default(); MAX_BRIDGES_PER_BUCKET];
for i in 0..MAX_BRIDGES_PER_BUCKET {
bucket[i] = self.bridge_table.unallocated_bridges.pop().unwrap();
}
self.add_openinv_bridges(bucket, bdb);
}
}
// 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

View File

@ -682,6 +682,27 @@ fn test_update_bridge() {
println!("After update openinv = {:?}\n", th.bdb.openinv_buckets);
}
#[test]
fn test_bridge_replace() {
// TODO
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(),
];
}
#[test]
fn test_allocate_bridges() {
// TODO
}
#[test]
fn test_mark_unreachable() {
let mut th = TestHarness::new();