|
@@ -156,23 +156,45 @@ impl User {
|
|
|
})
|
|
|
}
|
|
|
|
|
|
- // Attempt to "connect" to the bridge, returns true if successful
|
|
|
- pub fn connect(&self, config: &Config, bridge: &mut Bridge, censor: &Censor) -> bool {
|
|
|
+ // Attempt to "connect" to the bridge, returns true if successful.
|
|
|
+ // Note that this does not involve making a real connection to a
|
|
|
+ // real bridge. The function is async because the *censor* might
|
|
|
+ // submit a positive report during this function.
|
|
|
+ pub async fn connect(&self, config: &Config, bridge: &mut Bridge, censor: &Censor) -> bool {
|
|
|
if censor.blocks_bridge(config, &bridge.fingerprint) {
|
|
|
if config.censor_totality == Full
|
|
|
|| config.censor_totality == Partial
|
|
|
&& event_happens(censor.partial_blocking_percent)
|
|
|
- || config.censor_totality == Throttling
|
|
|
{
|
|
|
- // If censor tries to hide its censorship or
|
|
|
- // throttles rather than actually blocking, record a
|
|
|
+ // If censor tries to hide its censorship, record a
|
|
|
// false connection
|
|
|
- if config.censor_hides == Hiding || config.censor_totality == Throttling {
|
|
|
+ if config.censor_hides == Hiding {
|
|
|
bridge.connect_total();
|
|
|
}
|
|
|
|
|
|
// Return false because the connection failed
|
|
|
return false;
|
|
|
+ } else if config.censor_totality == Throttling {
|
|
|
+ // With some probability, the user connects but gives up
|
|
|
+ // because there is too much interference. In this case,
|
|
|
+ // a real connection occurs, but we treat it like a
|
|
|
+ // false connection from the censor.
|
|
|
+ if event_happens(config.prob_user_treats_throttling_as_blocking) {
|
|
|
+ bridge.connect_total();
|
|
|
+
|
|
|
+ // A Hiding censor does not make an additional
|
|
|
+ // connection here, but it will make a false
|
|
|
+ // positive report if possible.
|
|
|
+ if config.censor_hides == Hiding && censor.has_lox_cred(&bridge.fingerprint) {
|
|
|
+ censor
|
|
|
+ .send_positive_report(config, &bridge.fingerprint)
|
|
|
+ .await;
|
|
|
+ }
|
|
|
+
|
|
|
+ // Return false because there was interference
|
|
|
+ // detected in the connection
|
|
|
+ return false;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -291,13 +313,16 @@ impl User {
|
|
|
for i in 0..bucket.len() {
|
|
|
// At level 0, we only have 1 bridge
|
|
|
if bucket[i] != BridgeLine::default() {
|
|
|
- if self.connect(
|
|
|
- &config,
|
|
|
- bridges
|
|
|
- .get_mut(&bucket[i].get_hashed_fingerprint())
|
|
|
- .unwrap(),
|
|
|
- &censor,
|
|
|
- ) {
|
|
|
+ if self
|
|
|
+ .connect(
|
|
|
+ &config,
|
|
|
+ bridges
|
|
|
+ .get_mut(&bucket[i].get_hashed_fingerprint())
|
|
|
+ .unwrap(),
|
|
|
+ &censor,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ {
|
|
|
succeeded.push(bucket[i]);
|
|
|
} else {
|
|
|
failed.push(bucket[i]);
|
|
@@ -338,13 +363,16 @@ impl User {
|
|
|
);
|
|
|
}
|
|
|
// Attempt to connect to second cred's bridge
|
|
|
- if self.connect(
|
|
|
- &config,
|
|
|
- bridges
|
|
|
- .get_mut(&bridgeline.get_hashed_fingerprint())
|
|
|
- .unwrap(),
|
|
|
- censor,
|
|
|
- ) {
|
|
|
+ if self
|
|
|
+ .connect(
|
|
|
+ &config,
|
|
|
+ bridges
|
|
|
+ .get_mut(&bridgeline.get_hashed_fingerprint())
|
|
|
+ .unwrap(),
|
|
|
+ censor,
|
|
|
+ )
|
|
|
+ .await
|
|
|
+ {
|
|
|
succeeded.push(bridgeline);
|
|
|
if second_reachcred.is_some()
|
|
|
&& eligible_for_trust_promotion(&config.la_net, &second_cred).await
|