diff --git a/crates/lox-distributor/src/lox_context.rs b/crates/lox-distributor/src/lox_context.rs index 9858c01..a8ce538 100644 --- a/crates/lox-distributor/src/lox_context.rs +++ b/crates/lox-distributor/src/lox_context.rs @@ -60,19 +60,14 @@ impl LoxServerContext { pub fn handle_working_resources(&self, working_resources: Vec) -> Vec { let mut accounted_for_bridges: Vec = Vec::new(); let (bridgelines, blocked_bridgelines) = parse_into_bridgelines(working_resources); - /* TODO: Functionality for marking bridges as unreachable/blocked should eventually happen here. - It is currently not enabled as there is not yet a reliable way to determine that a bridge is blocked. - This means that migrations to unblocked bridges do not currently work but can be easily enabled by parsing the - list of `blocked resources` from rdsys or another source with something like the following: - let res = context.add_unreachable(bridgeline); - */ for bridge in blocked_bridgelines { let res = self.add_unreachable(bridge); if res { println!("BridgeLine {:?} successfully marked unreachable", bridge); + self.metrics.blocked_bridges.inc(); } else { println!( - "BridgeLine {:?} NOT marked unreachable, saved for next update!", + "BridgeLine {:?} NOT marked unreachable, not found in bridgetable!", bridge.uid_fingerprint ); } @@ -105,7 +100,19 @@ impl LoxServerContext { not_working_resources: Vec, mut accounted_for_bridges: Vec, ) -> Vec { - let (grace_period, failing) = sort_for_parsing(not_working_resources); + let (grace_period, failing, blocked) = sort_for_parsing(not_working_resources); + for bridge in blocked { + let res = self.add_unreachable(bridge); + if res { + println!("BridgeLine {:?} successfully marked unreachable", bridge); + self.metrics.blocked_bridges.inc(); + } else { + println!( + "BridgeLine {:?} NOT marked unreachable, not found in bridgetable!", + bridge.uid_fingerprint + ); + } + } // Update bridges in the bridge table that are failing but within the grace period for bridge in grace_period { let res = self.update_bridge(bridge); diff --git a/crates/lox-distributor/src/main.rs b/crates/lox-distributor/src/main.rs index c6a79df..abb099e 100644 --- a/crates/lox-distributor/src/main.rs +++ b/crates/lox-distributor/src/main.rs @@ -207,7 +207,7 @@ async fn context_manager( // bridgetable with all of the working bridges received from rdsys. if context.bridgetable_is_empty() { if let Some(working_resources) = resources.working { - let bridgelines = parse_into_bridgelines(working_resources); + let (bridgelines, _) = parse_into_bridgelines(working_resources); context.metrics.new_bridges.inc_by(bridgelines.len() as u64); let (buckets, leftovers) = parse_into_buckets(bridgelines); for leftover in leftovers { diff --git a/crates/lox-distributor/src/resource_parser.rs b/crates/lox-distributor/src/resource_parser.rs index 8843d90..208aa57 100644 --- a/crates/lox-distributor/src/resource_parser.rs +++ b/crates/lox-distributor/src/resource_parser.rs @@ -1,5 +1,4 @@ use chrono::{Duration, Utc}; -use futures::executor::block_on; use lox_library::bridge_table::{BridgeLine, BRIDGE_BYTES, MAX_BRIDGES_PER_BUCKET}; use rdsys_backend::proto::Resource; @@ -16,9 +15,8 @@ pub fn parse_into_bridgelines(resources: Vec) -> (Vec, Vec .get_uid() .expect("Unable to get Fingerprint UID of resource"); let infostr: String = format!( - "type={} blocked_in={:?} protocol={} fingerprint={:?} or_addresses={:?} distribution={} flags={:?} params={:?}", + "type={} protocol={} fingerprint={:?} or_addresses={:?} distribution={} flags={:?} params={:?}", resource.r#type, - resource.blocked_in, resource.protocol, resource.fingerprint, resource.or_addresses, @@ -29,15 +27,24 @@ pub fn parse_into_bridgelines(resources: Vec) -> (Vec, Vec let mut info_bytes: [u8; BRIDGE_BYTES - 26] = [0; BRIDGE_BYTES - 26]; info_bytes[..infostr.len()].copy_from_slice(infostr.as_bytes()); - if !resource.blocked_in.get("RU").unwrap() { - bridgelines.push(BridgeLine { - addr: ip_bytes, - port: resource.port, - uid_fingerprint: resource_uid, - info: info_bytes, - }); + if let Some(blockage) = resource.blocked_in.get("RU") { + if *blockage { + blocked_bridgelines.push(BridgeLine { + addr: ip_bytes, + port: resource.port, + uid_fingerprint: resource_uid, + info: info_bytes, + }); + } else { + bridgelines.push(BridgeLine { + addr: ip_bytes, + port: resource.port, + uid_fingerprint: resource_uid, + info: info_bytes, + }); + } } else { - blocked_bridgelines.push(BridgeLine { + bridgelines.push(BridgeLine { addr: ip_bytes, port: resource.port, uid_fingerprint: resource_uid, @@ -87,9 +94,12 @@ pub fn parse_into_buckets( // Sort Resources into those that are functional and those that are failing based on the last time // they were passing tests. Before passing them back to the calling function, they are parsed into // BridgeLines -pub fn sort_for_parsing(resources: Vec) -> (Vec, Vec) { +pub fn sort_for_parsing( + resources: Vec, +) -> (Vec, Vec, Vec) { let mut grace_period: Vec = Vec::new(); let mut failing: Vec = Vec::new(); + let mut blocked: Vec = Vec::new(); for resource in resources { // TODO: Maybe filter for untested resources first if last_passed alone would skew // the filter in an unintended direction @@ -101,10 +111,12 @@ pub fn sort_for_parsing(resources: Vec) -> (Vec, Vec, address: String, port: u16, fingerprint: String, @@ -133,7 +146,7 @@ mod tests { ); Resource { r#type: String::from(rtype), - blocked_in: HashMap::new(), + blocked_in: blocked_in, test_result: TestResults { last_passed: Utc::now() - Duration::hours(last_passed), }, @@ -152,6 +165,13 @@ mod tests { fn test_sort_for_parsing() { let resource_one = make_resource( "scramblesuit".to_owned(), + HashMap::from([ + ("AS".to_owned(), false), + ("IR".to_owned(), false), + ("PS".to_owned(), false), + ("CN".to_owned(), false), + ("RU".to_owned(), false), + ]), "123.456.789.100".to_owned(), 3002, "BE84A97D02130470A1C77839954392BA979F7EE1".to_owned(), @@ -159,6 +179,13 @@ mod tests { ); let resource_two = make_resource( "https".to_owned(), + HashMap::from([ + ("AI".to_owned(), false), + ("AG".to_owned(), false), + ("BD".to_owned(), false), + ("BB".to_owned(), false), + ("RU".to_owned(), false), + ]), "123.222.333.444".to_owned(), 6002, "C56B9EF202130470A1C77839954392BA979F7FF9".to_owned(), @@ -166,13 +193,27 @@ mod tests { ); let resource_three = make_resource( "scramblesuit".to_owned(), - "444.888.222.100".to_owned(), + HashMap::from([ + ("SZ".to_owned(), true), + ("DO".to_owned(), false), + ("GN".to_owned(), false), + ("KR".to_owned(), false), + ("RU".to_owned(), false), + ]), + "443.288.222.100".to_owned(), 3042, - "1A4C8BD902130470A1C77839954392BA979F7B46".to_owned(), + "5E3A8BD902130470A1C77839954392BA979F7B46".to_owned(), 4, ); let resource_four = make_resource( "https".to_owned(), + HashMap::from([ + ("SH".to_owned(), true), + ("ZA".to_owned(), true), + ("UM".to_owned(), true), + ("ZW".to_owned(), true), + ("SK".to_owned(), true), + ]), "555.444.212.100".to_owned(), 8022, "FF024DC302130470A1C77839954392BA979F7AE2".to_owned(), @@ -180,22 +221,61 @@ mod tests { ); let resource_five = make_resource( "https".to_owned(), + HashMap::from([ + ("CA".to_owned(), false), + ("UK".to_owned(), true), + ("SR".to_owned(), false), + ("RW".to_owned(), true), + ("RU".to_owned(), false), + ]), "234.111.212.100".to_owned(), 10432, "7B4DE14CB2130470A1C77839954392BA979F7AE2".to_owned(), 1, ); + let resource_six = make_resource( + "https".to_owned(), + HashMap::from([ + ("CA".to_owned(), false), + ("UK".to_owned(), false), + ("SR".to_owned(), false), + ("RW".to_owned(), false), + ("RU".to_owned(), true), + ]), + "434.777.212.100".to_owned(), + 10112, + "7B4DE04A22130470A1C77839954392BA979F7AE2".to_owned(), + 1, + ); + let resource_seven = make_resource( + "https".to_owned(), + HashMap::from([ + ("CA".to_owned(), true), + ("UK".to_owned(), false), + ("SR".to_owned(), false), + ("RW".to_owned(), false), + ("RU".to_owned(), true), + ]), + "434.777.212.211".to_owned(), + 8112, + "01E6FA4A22130470A1C77839954392BA979F7AE2".to_owned(), + 5, + ); let mut test_vec: Vec = Vec::new(); test_vec.push(resource_one); test_vec.push(resource_two); test_vec.push(resource_three); test_vec.push(resource_four); test_vec.push(resource_five); - let (functional, failing) = sort_for_parsing(test_vec); + test_vec.push(resource_six); + test_vec.push(resource_seven); + println!("How many in test? {:?}", test_vec.len()); + let (functional, failing, blocked) = sort_for_parsing(test_vec); assert!( functional.len() == 2, "There should be 2 functional bridges" ); assert!(failing.len() == 3, "There should be 3 failing bridges"); + assert!(blocked.len() == 2, "There should be 2 blocked bridges"); } }