Add support for verifying Troll Patrol's inferences
This commit is contained in:
parent
1e3cb62822
commit
ff3aa2d718
65
src/lib.rs
65
src/lib.rs
|
@ -837,6 +837,71 @@ pub fn guess_blockages(
|
|||
blockages
|
||||
}
|
||||
|
||||
/// Verify bridges suspected of being blocked, return only the ones that are
|
||||
/// actually blocked
|
||||
pub async fn verify_blockages(
|
||||
verify_blockages_url: &str,
|
||||
suspected_blockages: HashMap<[u8; 20], HashSet<String>>,
|
||||
) -> HashMap<[u8; 20], HashSet<String>> {
|
||||
// If we don't have a resource for checking if bridges are blocked, assume
|
||||
// that Troll Patrol guessed correctly
|
||||
if verify_blockages_url.is_empty() {
|
||||
return suspected_blockages;
|
||||
}
|
||||
|
||||
// Convert map keys from [u8; 20] to 40-character hex strings
|
||||
let mut suspected_blockages_str = HashMap::<String, HashSet<String>>::new();
|
||||
for (fingerprint, countries) in &suspected_blockages {
|
||||
let fpr_string = array_bytes::bytes2hex("", fingerprint);
|
||||
if !countries.is_empty() {
|
||||
suspected_blockages_str.insert(fpr_string, countries.clone());
|
||||
}
|
||||
}
|
||||
|
||||
if !suspected_blockages_str.is_empty() {
|
||||
// Send suspected blockages to verification endpoint for verification
|
||||
let client = Client::new();
|
||||
let req = Request::builder()
|
||||
.method(Method::POST)
|
||||
.uri(verify_blockages_url)
|
||||
.body(Body::from(
|
||||
serde_json::to_string(&suspected_blockages_str).unwrap(),
|
||||
))
|
||||
.unwrap();
|
||||
let resp = client.request(req).await.unwrap();
|
||||
let buf = hyper::body::to_bytes(resp).await.unwrap();
|
||||
let resp_str = String::from_utf8(buf.to_vec()).unwrap();
|
||||
|
||||
// Deserialize map
|
||||
let blockages_str: HashMap<String, HashSet<String>> = match serde_json::from_str(&resp_str)
|
||||
{
|
||||
Ok(v) => v,
|
||||
Err(e) => {
|
||||
eprintln!(
|
||||
"Failed to deserialize response from verification endpoint: {:?}",
|
||||
e
|
||||
);
|
||||
HashMap::<String, HashSet<String>>::new()
|
||||
}
|
||||
};
|
||||
|
||||
// Convert map so it uses [u8; 20]s as keys again
|
||||
let mut blockages = HashMap::<[u8; 20], HashSet<String>>::new();
|
||||
for (fingerprint, countries) in blockages_str {
|
||||
if let Ok(fpr) = array_bytes::hex2array(fingerprint) {
|
||||
if !countries.is_empty() {
|
||||
blockages.insert(fpr, countries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Return map of confirmed blockages
|
||||
blockages
|
||||
} else {
|
||||
suspected_blockages
|
||||
}
|
||||
}
|
||||
|
||||
/// Commit blocked bridges to database
|
||||
pub fn commit_blockages(db: &Db, blockages: &HashMap<[u8; 20], HashSet<String>>) {
|
||||
// For each bridge:<set of countries>, mark the bridge as blocked in each country
|
||||
|
|
13
src/main.rs
13
src/main.rs
|
@ -51,6 +51,7 @@ pub struct Config {
|
|||
// map of distributor name to IP:port to contact it
|
||||
pub distributors: BTreeMap<BridgeDistributor, String>,
|
||||
extra_infos_base_url: String,
|
||||
verify_blockages_url: String,
|
||||
|
||||
// confidence required to consider a bridge blocked
|
||||
confidence: f64,
|
||||
|
@ -92,6 +93,7 @@ async fn update_daily_info(
|
|||
db: &Db,
|
||||
distributors: &BTreeMap<BridgeDistributor, String>,
|
||||
extra_infos_base_url: &str,
|
||||
verify_blockages_url: &str,
|
||||
confidence: f64,
|
||||
max_threshold: u32,
|
||||
scaling_factor: f64,
|
||||
|
@ -109,7 +111,10 @@ async fn update_daily_info(
|
|||
min_historical_days,
|
||||
max_historical_days,
|
||||
);
|
||||
// TODO: Verify the new blockages
|
||||
|
||||
// This implementation will vary based on scanning infrastructure
|
||||
let new_blockages = verify_blockages(verify_blockages_url, new_blockages).await;
|
||||
|
||||
commit_blockages(db, &new_blockages);
|
||||
report_blockages(distributors, new_blockages.clone()).await;
|
||||
|
||||
|
@ -132,6 +137,7 @@ async fn create_context_manager(
|
|||
db_config: DbConfig,
|
||||
distributors: BTreeMap<BridgeDistributor, String>,
|
||||
extra_infos_base_url: &str,
|
||||
verify_blockages_url: &str,
|
||||
confidence: f64,
|
||||
max_threshold: u32,
|
||||
scaling_factor: f64,
|
||||
|
@ -141,7 +147,7 @@ async fn create_context_manager(
|
|||
mut kill: broadcast::Receiver<()>,
|
||||
) {
|
||||
tokio::select! {
|
||||
create_context = context_manager(db_config, distributors, extra_infos_base_url, confidence, max_threshold, scaling_factor, min_historical_days, max_historical_days, context_rx) => create_context,
|
||||
create_context = context_manager(db_config, distributors, extra_infos_base_url, verify_blockages_url, confidence, max_threshold, scaling_factor, min_historical_days, max_historical_days, context_rx) => create_context,
|
||||
_ = kill.recv() => {println!("Shut down manager");},
|
||||
}
|
||||
}
|
||||
|
@ -150,6 +156,7 @@ async fn context_manager(
|
|||
db_config: DbConfig,
|
||||
distributors: BTreeMap<BridgeDistributor, String>,
|
||||
extra_infos_base_url: &str,
|
||||
verify_blockages_url: &str,
|
||||
confidence: f64,
|
||||
max_threshold: u32,
|
||||
scaling_factor: f64,
|
||||
|
@ -202,6 +209,7 @@ async fn context_manager(
|
|||
&db,
|
||||
&distributors,
|
||||
extra_infos_base_url,
|
||||
verify_blockages_url,
|
||||
confidence,
|
||||
max_threshold,
|
||||
scaling_factor,
|
||||
|
@ -296,6 +304,7 @@ async fn main() {
|
|||
config.db,
|
||||
config.distributors,
|
||||
&config.extra_infos_base_url,
|
||||
&config.verify_blockages_url,
|
||||
config.confidence,
|
||||
config.max_threshold,
|
||||
config.scaling_factor,
|
||||
|
|
Loading…
Reference in New Issue