ss_rs/security/
mod.rs

1//! Networking security facilities for shadowsocks communication.
2
3use std::sync::Mutex;
4
5use bloom::{BloomFilter, ASMS};
6
7mod constants {
8    pub const EXPECTED_NUM_ITEMS: u32 = 1_000_000;
9}
10
11struct Bloom {
12    filters: [BloomFilter; 2],
13    current: usize,
14    count: u32,
15}
16
17impl Bloom {
18    fn new() -> Self {
19        Bloom {
20            filters: [
21                BloomFilter::with_rate(1e-6, constants::EXPECTED_NUM_ITEMS),
22                BloomFilter::with_rate(1e-6, constants::EXPECTED_NUM_ITEMS),
23            ],
24            current: 0,
25            count: 0,
26        }
27    }
28
29    fn check_and_insert(&mut self, element: &[u8]) -> bool {
30        if self.filters.iter().any(|x| x.contains(&element)) {
31            return false;
32        }
33
34        let filter = &mut self.filters[self.current];
35        filter.insert(&element);
36
37        self.count += 1;
38        if self.count == constants::EXPECTED_NUM_ITEMS {
39            self.current = (self.current + 1) % 2;
40            self.filters[self.current].clear();
41        }
42
43        true
44    }
45}
46
47/// Replay attack protection that serves as a set.
48pub struct ReplayProtection {
49    bloom: Mutex<Bloom>,
50}
51
52impl ReplayProtection {
53    /// Creates a new instance of the ReplayProtection.
54    pub fn new() -> Self {
55        ReplayProtection {
56            bloom: Mutex::new(Bloom::new()),
57        }
58    }
59
60    /// Inserts a element to the set.
61    ///
62    /// Returns false if there is already a same element in the set,
63    /// and thus failed to insert.
64    ///
65    /// Returns true if the element was successfully inserted.
66    pub fn check_and_insert(&self, element: &[u8]) -> bool {
67        self.bloom.lock().unwrap().check_and_insert(&element)
68    }
69}