rtc_shared/replay_detector/
mod.rs1mod fixed_big_int;
2#[cfg(test)]
3mod replay_detector_test;
4
5use fixed_big_int::*;
6
7pub trait ReplayDetector {
9 fn check(&mut self, seq: u64) -> bool;
12 fn accept(&mut self);
13}
14
15pub struct SlidingWindowDetector {
16 accepted: bool,
17 seq: u64,
18 latest_seq: u64,
19 max_seq: u64,
20 window_size: usize,
21 mask: FixedBigInt,
22}
23
24impl SlidingWindowDetector {
25 pub fn new(window_size: usize, max_seq: u64) -> Self {
30 SlidingWindowDetector {
31 accepted: false,
32 seq: 0,
33 latest_seq: 0,
34 max_seq,
35 window_size,
36 mask: FixedBigInt::new(window_size),
37 }
38 }
39}
40
41impl ReplayDetector for SlidingWindowDetector {
42 fn check(&mut self, seq: u64) -> bool {
43 self.accepted = false;
44
45 if seq > self.max_seq {
46 return false;
48 }
49
50 if seq <= self.latest_seq {
51 if self.latest_seq >= self.window_size as u64 + seq {
52 return false;
53 }
54 if self.mask.bit((self.latest_seq - seq) as usize) != 0 {
55 return false;
57 }
58 }
59
60 self.accepted = true;
61 self.seq = seq;
62 true
63 }
64
65 fn accept(&mut self) {
66 if !self.accepted {
67 return;
68 }
69
70 if self.seq > self.latest_seq {
71 self.mask.lsh((self.seq - self.latest_seq) as usize);
73 self.latest_seq = self.seq;
74 }
75 let diff = (self.latest_seq - self.seq) % self.max_seq;
76 self.mask.set_bit(diff as usize);
77 }
78}
79
80pub struct WrappedSlidingWindowDetector {
81 accepted: bool,
82 seq: u64,
83 latest_seq: u64,
84 max_seq: u64,
85 window_size: usize,
86 mask: FixedBigInt,
87 init: bool,
88}
89
90impl WrappedSlidingWindowDetector {
91 pub fn new(window_size: usize, max_seq: u64) -> Self {
94 WrappedSlidingWindowDetector {
95 accepted: false,
96 seq: 0,
97 latest_seq: 0,
98 max_seq,
99 window_size,
100 mask: FixedBigInt::new(window_size),
101 init: false,
102 }
103 }
104}
105
106impl ReplayDetector for WrappedSlidingWindowDetector {
107 fn check(&mut self, seq: u64) -> bool {
108 self.accepted = false;
109
110 if seq > self.max_seq {
111 return false;
113 }
114 if !self.init {
115 if seq != 0 {
116 self.latest_seq = seq - 1;
117 } else {
118 self.latest_seq = self.max_seq;
119 }
120 self.init = true;
121 }
122
123 let mut diff = self.latest_seq as i64 - seq as i64;
124 if diff > self.max_seq as i64 / 2 {
126 diff -= (self.max_seq + 1) as i64;
127 } else if diff <= -(self.max_seq as i64 / 2) {
128 diff += (self.max_seq + 1) as i64;
129 }
130
131 if diff >= self.window_size as i64 {
132 return false;
134 }
135 if diff >= 0 && self.mask.bit(diff as usize) != 0 {
136 return false;
138 }
139
140 self.accepted = true;
141 self.seq = seq;
142 true
143 }
144
145 fn accept(&mut self) {
146 if !self.accepted {
147 return;
148 }
149
150 let mut diff = self.latest_seq as i64 - self.seq as i64;
151 if diff > self.max_seq as i64 / 2 {
153 diff -= (self.max_seq + 1) as i64;
154 } else if diff <= -(self.max_seq as i64 / 2) {
155 diff += (self.max_seq + 1) as i64;
156 }
157
158 assert!(diff < self.window_size as i64);
159
160 if diff < 0 {
161 self.mask.lsh((-diff) as usize);
163 self.latest_seq = self.seq;
164 }
165 self.mask
166 .set_bit((self.latest_seq as isize - self.seq as isize) as usize);
167 }
168}
169
170#[derive(Default)]
171pub struct NoOpReplayDetector;
172
173impl ReplayDetector for NoOpReplayDetector {
174 fn check(&mut self, _: u64) -> bool {
175 true
176 }
177 fn accept(&mut self) {}
178}