censor.rs 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. use crate::{
  2. get_date,
  3. simulation::{bridge::Bridge, config::Config},
  4. PositiveReport,
  5. };
  6. use lox_cli::{get_lox_pub, networking::Networking};
  7. use lox_library::{cred::Lox, scalar_u32};
  8. use rand::Rng;
  9. use serde::Deserialize;
  10. use std::{
  11. cmp::min,
  12. collections::{HashMap, HashSet},
  13. };
  14. pub struct Censor {
  15. pub known_bridges: HashSet<[u8; 20]>,
  16. // We don't actually implement the technical restriction to prevent
  17. // one Lox credential from being used to submit many reports, so we
  18. // just implement this as a map of bridge fingerprint to (most
  19. // recent Lox credential for this bridge, count of unique level 3+
  20. // credentials we have for this bridge).
  21. pub lox_credentials: HashMap<[u8; 20], (Lox, u32)>,
  22. // If censor implements random blocking, this is the date when it
  23. // will start blocking all the bridges it knows.
  24. pub delay_date: u32,
  25. // If censor implements partial blocking, what percent of
  26. // connections are blocked?
  27. pub partial_blocking_percent: f64,
  28. }
  29. impl Censor {
  30. pub fn new(config: &Config) -> Self {
  31. let mut rng = rand::thread_rng();
  32. let delay_date = if config.censor_speed == Speed::Random {
  33. let num: u32 = rng.gen_range(1..365);
  34. get_date() + num
  35. } else {
  36. 0
  37. };
  38. let partial_blocking_percent = if config.censor_totality == Totality::Partial {
  39. config.censor_partial_blocking_percent
  40. } else {
  41. 1.0
  42. };
  43. Censor {
  44. known_bridges: HashSet::<[u8; 20]>::new(),
  45. lox_credentials: HashMap::<[u8; 20], (Lox, u32)>::new(),
  46. delay_date: delay_date,
  47. partial_blocking_percent: partial_blocking_percent,
  48. }
  49. }
  50. pub fn knows_bridge(&self, fingerprint: &[u8; 20]) -> bool {
  51. self.known_bridges.contains(fingerprint)
  52. }
  53. pub fn blocks_bridge(&self, config: &Config, fingerprint: &[u8; 20]) -> bool {
  54. self.knows_bridge(fingerprint)
  55. && (config.censor_speed == Speed::Fast
  56. || config.censor_speed == Speed::Lox && self.has_lox_cred(fingerprint)
  57. || config.censor_speed == Speed::Random && self.delay_date <= get_date())
  58. }
  59. pub fn learn_bridge(&mut self, fingerprint: &[u8; 20]) {
  60. self.known_bridges.insert(*fingerprint);
  61. }
  62. pub fn has_lox_cred(&self, fingerprint: &[u8; 20]) -> bool {
  63. self.lox_credentials.contains_key(fingerprint)
  64. && self.lox_credentials.get(fingerprint).unwrap().1 > 0
  65. }
  66. pub fn give_lox_cred(&mut self, fingerprint: &[u8; 20], cred: &Lox) {
  67. // We only need one level 3+ credential per bridge. (This will
  68. // change if we restrict positive reports to one per bridge per
  69. // credential.)
  70. if scalar_u32(&cred.trust_level).unwrap() >= 3 {
  71. // We want to clone the credential, but that's not allowed,
  72. // so we're going to serialize it and then deserialize it.
  73. let cloned_cred = bincode::deserialize(&bincode::serialize(&cred).unwrap()).unwrap();
  74. // Insert the new credential and add to the count of unique
  75. // credentials we have. We assume that a duplicate
  76. // credential will never be given. If we don't want to make
  77. // this assumption, we could change the count from a u32 to
  78. // a set of credential IDs and get the count as its length.
  79. let count = match self.lox_credentials.get(fingerprint) {
  80. Some((_cred, count)) => *count,
  81. None => 0,
  82. };
  83. self.lox_credentials
  84. .insert(*fingerprint, (cloned_cred, count + 1));
  85. }
  86. }
  87. // Censor sends a positive report for the given bridge. Returns true
  88. // if successful, false otherwise.
  89. pub async fn send_positive_report(&self, config: &Config, fingerprint: &[u8; 20]) -> bool {
  90. // If we don't have an appropriate Lox credential, we can't send
  91. // a report. Return false.
  92. if !self.has_lox_cred(fingerprint) {
  93. return false;
  94. }
  95. let (cred, _) = &self.lox_credentials.get(fingerprint).unwrap();
  96. let pr = PositiveReport::from_lox_credential(
  97. *fingerprint,
  98. None,
  99. cred,
  100. get_lox_pub(&config.la_pubkeys),
  101. config.country.clone(),
  102. )
  103. .unwrap();
  104. if config
  105. .tp_net
  106. .request("/positivereport".to_string(), pr.to_json().into_bytes())
  107. .await
  108. .is_err()
  109. {
  110. // failed to send positive report
  111. return false;
  112. }
  113. true
  114. }
  115. // Make a bunch of connections and submit positive reports if possible
  116. async fn flood(&self, config: &Config, bridges: &mut HashMap<[u8; 20], Bridge>) {
  117. // Only do this if Flooding censor
  118. if config.censor_secrecy == Secrecy::Flooding {
  119. for fingerprint in &self.known_bridges {
  120. // Only do this if we're blocking the bridge
  121. if config.censor_speed == Speed::Fast
  122. || config.censor_speed == Speed::Lox && self.has_lox_cred(fingerprint)
  123. || config.censor_speed == Speed::Random && self.delay_date <= get_date()
  124. {
  125. let bridge = bridges.get_mut(fingerprint).unwrap();
  126. // A large number
  127. let num_connections = 30000;
  128. // Make a bunch of connections to the bridge
  129. bridge.censor_flood(num_connections);
  130. // If we have a lv3+ credential, submit a bunch of
  131. // positive reports
  132. if self.has_lox_cred(fingerprint) {
  133. let (_cred, cred_count) =
  134. &self.lox_credentials.get(&bridge.fingerprint).unwrap();
  135. let num_prs = if config.one_positive_report_per_cred {
  136. *cred_count
  137. } else {
  138. 30000
  139. };
  140. for _ in 0..num_prs {
  141. self.send_positive_report(config, &bridge.fingerprint).await;
  142. }
  143. }
  144. }
  145. }
  146. }
  147. }
  148. // Send one positive report per connection we blocked
  149. async fn send_positive_reports(
  150. &self,
  151. config: &Config,
  152. bridges: &mut HashMap<[u8; 20], Bridge>,
  153. ) {
  154. // Only do this if Hiding censor. Flooding censors should use
  155. // flood() instead.
  156. if config.censor_secrecy == Secrecy::Hiding {
  157. for fingerprint in &self.known_bridges {
  158. // Only do this if we're blocking the bridge
  159. if self.blocks_bridge(config, fingerprint) && self.has_lox_cred(fingerprint) {
  160. let bridge = bridges.get_mut(fingerprint).unwrap();
  161. // We may be restricted to one positive report per
  162. // credential
  163. let num_reports_to_send = if config.one_positive_report_per_cred {
  164. min(
  165. bridge.total_connections - bridge.real_connections,
  166. self.lox_credentials.get(fingerprint).unwrap().1,
  167. )
  168. } else {
  169. bridge.total_connections - bridge.real_connections
  170. };
  171. for _ in 0..num_reports_to_send {
  172. self.send_positive_report(config, fingerprint).await;
  173. }
  174. }
  175. }
  176. }
  177. }
  178. fn recompute_delay(&mut self, config: &Config) {
  179. // Only do this if Random censor
  180. if config.censor_speed == Speed::Random
  181. && self.delay_date + config.censor_event_duration <= get_date()
  182. {
  183. // Compute new delay date
  184. self.delay_date = {
  185. let mut rng = rand::thread_rng();
  186. let num: u32 = rng.gen_range(1..365);
  187. get_date() + num
  188. }
  189. }
  190. }
  191. pub async fn end_of_day_tasks(
  192. &mut self,
  193. config: &Config,
  194. bridges: &mut HashMap<[u8; 20], Bridge>,
  195. ) {
  196. if config.censor_secrecy == Secrecy::Flooding
  197. && !(config.censor_speed == Speed::Random && self.delay_date <= get_date())
  198. {
  199. self.flood(config, bridges).await;
  200. } else if config.censor_secrecy == Secrecy::Hiding
  201. && !(config.censor_speed == Speed::Random && self.delay_date <= get_date())
  202. {
  203. self.send_positive_reports(config, bridges).await;
  204. }
  205. self.recompute_delay(config);
  206. }
  207. }
  208. #[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
  209. pub enum Speed {
  210. Fast,
  211. Lox,
  212. Random,
  213. }
  214. #[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
  215. pub enum Secrecy {
  216. Overt,
  217. Hiding,
  218. Flooding,
  219. }
  220. #[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
  221. pub enum Totality {
  222. Full,
  223. Partial,
  224. Throttling,
  225. }