Compare commits
2 Commits
50ce57765d
...
cc86baa4b5
Author | SHA1 | Date |
---|---|---|
|
cc86baa4b5 | |
|
28233ec8a5 |
12
src/lib.rs
12
src/lib.rs
|
@ -65,6 +65,8 @@ pub struct BridgeInfo {
|
||||||
pub fingerprint: [u8; 20],
|
pub fingerprint: [u8; 20],
|
||||||
/// nickname of bridge (probably not necessary)
|
/// nickname of bridge (probably not necessary)
|
||||||
pub nickname: String,
|
pub nickname: String,
|
||||||
|
/// first Julian date we started collecting data on this bridge
|
||||||
|
pub first_seen: u32,
|
||||||
/// flag indicating whether the bridge is believed to be blocked
|
/// flag indicating whether the bridge is believed to be blocked
|
||||||
pub is_blocked: bool,
|
pub is_blocked: bool,
|
||||||
/// map of dates to data for that day
|
/// map of dates to data for that day
|
||||||
|
@ -76,6 +78,7 @@ impl BridgeInfo {
|
||||||
Self {
|
Self {
|
||||||
fingerprint: fingerprint,
|
fingerprint: fingerprint,
|
||||||
nickname: nickname,
|
nickname: nickname,
|
||||||
|
first_seen: get_date(),
|
||||||
is_blocked: false,
|
is_blocked: false,
|
||||||
info_by_day: HashMap::<u32, DailyBridgeInfo>::new(),
|
info_by_day: HashMap::<u32, DailyBridgeInfo>::new(),
|
||||||
}
|
}
|
||||||
|
@ -89,6 +92,7 @@ impl fmt::Display for BridgeInfo {
|
||||||
array_bytes::bytes2hex("", self.fingerprint).as_str()
|
array_bytes::bytes2hex("", self.fingerprint).as_str()
|
||||||
);
|
);
|
||||||
str.push_str(format!("nickname: {}\n", self.nickname).as_str());
|
str.push_str(format!("nickname: {}\n", self.nickname).as_str());
|
||||||
|
str.push_str(format!("first_seen: {}\n", self.first_seen).as_str());
|
||||||
str.push_str(format!("is_blocked: {}\n", self.is_blocked).as_str());
|
str.push_str(format!("is_blocked: {}\n", self.is_blocked).as_str());
|
||||||
str.push_str("info_by_day:");
|
str.push_str("info_by_day:");
|
||||||
for day in self.info_by_day.keys() {
|
for day in self.info_by_day.keys() {
|
||||||
|
@ -111,8 +115,8 @@ pub struct DailyBridgeInfo {
|
||||||
/// Map of country codes and how many users (rounded up to a multiple of
|
/// Map of country codes and how many users (rounded up to a multiple of
|
||||||
/// 8) have connected to that bridge during the day.
|
/// 8) have connected to that bridge during the day.
|
||||||
pub bridge_ips: BTreeMap<String, u32>,
|
pub bridge_ips: BTreeMap<String, u32>,
|
||||||
/// Set of negative reports received during this day
|
/// Map of negative reports to count of negative reports received
|
||||||
pub negative_reports: Vec<SerializableNegativeReport>,
|
pub negative_reports: BTreeMap<SerializableNegativeReport, u32>,
|
||||||
/// Set of positive reports received during this day
|
/// Set of positive reports received during this day
|
||||||
pub positive_reports: Vec<SerializablePositiveReport>,
|
pub positive_reports: Vec<SerializablePositiveReport>,
|
||||||
// We don't care about ordering of the reports, but I'm using vectors for
|
// We don't care about ordering of the reports, but I'm using vectors for
|
||||||
|
@ -127,7 +131,7 @@ impl DailyBridgeInfo {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
bridge_ips: BTreeMap::<String, u32>::new(),
|
bridge_ips: BTreeMap::<String, u32>::new(),
|
||||||
negative_reports: Vec::<SerializableNegativeReport>::new(),
|
negative_reports: BTreeMap::<SerializableNegativeReport, u32>::new(),
|
||||||
positive_reports: Vec::<SerializablePositiveReport>::new(),
|
positive_reports: Vec::<SerializablePositiveReport>::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -191,7 +195,7 @@ pub fn add_extra_info_to_db(db: &Db, extra_info: ExtraInfo) {
|
||||||
// No existing entry; make a new one.
|
// No existing entry; make a new one.
|
||||||
let daily_bridge_info = DailyBridgeInfo {
|
let daily_bridge_info = DailyBridgeInfo {
|
||||||
bridge_ips: extra_info.bridge_ips,
|
bridge_ips: extra_info.bridge_ips,
|
||||||
negative_reports: Vec::<SerializableNegativeReport>::new(),
|
negative_reports: BTreeMap::<SerializableNegativeReport, u32>::new(),
|
||||||
positive_reports: Vec::<SerializablePositiveReport>::new(),
|
positive_reports: Vec::<SerializablePositiveReport>::new(),
|
||||||
};
|
};
|
||||||
bridge_info
|
bridge_info
|
||||||
|
|
|
@ -12,6 +12,7 @@ pub enum NegativeReportError {
|
||||||
DateInFuture,
|
DateInFuture,
|
||||||
FailedToDeserialize, // couldn't deserialize to SerializableNegativeReport
|
FailedToDeserialize, // couldn't deserialize to SerializableNegativeReport
|
||||||
InvalidCountryCode,
|
InvalidCountryCode,
|
||||||
|
MissingCountryCode,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// A report that the user was unable to connect to the bridge
|
/// A report that the user was unable to connect to the bridge
|
||||||
|
@ -20,7 +21,7 @@ pub struct NegativeReport {
|
||||||
pub fingerprint: [u8; 20],
|
pub fingerprint: [u8; 20],
|
||||||
/// some way to prove knowledge of bridge
|
/// some way to prove knowledge of bridge
|
||||||
bridge_pok: ProofOfBridgeKnowledge,
|
bridge_pok: ProofOfBridgeKnowledge,
|
||||||
/// user's country code, may be an empty string
|
/// user's country code
|
||||||
pub country: String,
|
pub country: String,
|
||||||
/// today's Julian date
|
/// today's Julian date
|
||||||
pub date: u32,
|
pub date: u32,
|
||||||
|
@ -87,7 +88,7 @@ impl NegativeReport {
|
||||||
ProofOfBridgeKnowledge::HashOfBridgeLine(pok) => {
|
ProofOfBridgeKnowledge::HashOfBridgeLine(pok) => {
|
||||||
let hash = HashOfBridgeLine::new(bl);
|
let hash = HashOfBridgeLine::new(bl);
|
||||||
hash == pok
|
hash == pok
|
||||||
},
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,7 +99,7 @@ impl NegativeReport {
|
||||||
ProofOfBridgeKnowledge::HashOfBucket(pok) => {
|
ProofOfBridgeKnowledge::HashOfBucket(pok) => {
|
||||||
let hash = HashOfBucket::new(bucket);
|
let hash = HashOfBucket::new(bucket);
|
||||||
hash == pok
|
hash == pok
|
||||||
},
|
}
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +107,7 @@ impl NegativeReport {
|
||||||
|
|
||||||
/// (De)serializable negative report object which must be consumed by the
|
/// (De)serializable negative report object which must be consumed by the
|
||||||
/// checking function before it can be used
|
/// checking function before it can be used
|
||||||
#[derive(Deserialize, Serialize)]
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
||||||
pub struct SerializableNegativeReport {
|
pub struct SerializableNegativeReport {
|
||||||
pub fingerprint: [u8; 20],
|
pub fingerprint: [u8; 20],
|
||||||
bridge_pok: ProofOfBridgeKnowledge,
|
bridge_pok: ProofOfBridgeKnowledge,
|
||||||
|
@ -116,7 +117,10 @@ pub struct SerializableNegativeReport {
|
||||||
|
|
||||||
impl SerializableNegativeReport {
|
impl SerializableNegativeReport {
|
||||||
pub fn to_report(self) -> Result<NegativeReport, NegativeReportError> {
|
pub fn to_report(self) -> Result<NegativeReport, NegativeReportError> {
|
||||||
if self.country != "" && !COUNTRY_CODES.contains(self.country.as_str()) {
|
if self.country == "" {
|
||||||
|
return Err(NegativeReportError::MissingCountryCode);
|
||||||
|
}
|
||||||
|
if !COUNTRY_CODES.contains(self.country.as_str()) {
|
||||||
return Err(NegativeReportError::InvalidCountryCode);
|
return Err(NegativeReportError::InvalidCountryCode);
|
||||||
}
|
}
|
||||||
if self.date > get_date().into() {
|
if self.date > get_date().into() {
|
||||||
|
@ -132,7 +136,7 @@ impl SerializableNegativeReport {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Proof that the user knows (and should be able to access) a given bridge
|
/// Proof that the user knows (and should be able to access) a given bridge
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
||||||
pub enum ProofOfBridgeKnowledge {
|
pub enum ProofOfBridgeKnowledge {
|
||||||
/// Hash of bridge line as proof of knowledge of bridge line
|
/// Hash of bridge line as proof of knowledge of bridge line
|
||||||
HashOfBridgeLine(HashOfBridgeLine),
|
HashOfBridgeLine(HashOfBridgeLine),
|
||||||
|
@ -141,7 +145,7 @@ pub enum ProofOfBridgeKnowledge {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hash of bridge line to prove knowledge of that bridge
|
/// Hash of bridge line to prove knowledge of that bridge
|
||||||
#[derive(PartialEq, Serialize, Deserialize)]
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
||||||
pub struct HashOfBridgeLine {
|
pub struct HashOfBridgeLine {
|
||||||
hash: [u8; 32],
|
hash: [u8; 32],
|
||||||
}
|
}
|
||||||
|
@ -156,7 +160,7 @@ impl HashOfBridgeLine {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hash of bucket ID to prove knowledge of bridges in that bucket
|
/// Hash of bucket ID to prove knowledge of bridges in that bucket
|
||||||
#[derive(PartialEq, Serialize, Deserialize)]
|
#[derive(Eq, PartialEq, Ord, PartialOrd, Serialize, Deserialize)]
|
||||||
pub struct HashOfBucket {
|
pub struct HashOfBucket {
|
||||||
hash: [u8; 32],
|
hash: [u8; 32],
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue