1
1
#[ cfg( test) ]
2
2
mod replay_detector_test;
3
3
4
+ use std:: collections:: HashMap ;
5
+
4
6
use super :: fixed_big_int:: * ;
5
7
6
8
// ReplayDetector is the interface of sequence replay detector.
@@ -84,6 +86,7 @@ pub struct WrappedSlidingWindowDetector {
84
86
window_size : usize ,
85
87
mask : FixedBigInt ,
86
88
init : bool ,
89
+ duplicated : HashMap < u64 , u8 > ,
87
90
}
88
91
89
92
impl WrappedSlidingWindowDetector {
@@ -98,16 +101,27 @@ impl WrappedSlidingWindowDetector {
98
101
window_size,
99
102
mask : FixedBigInt :: new ( window_size) ,
100
103
init : false ,
104
+ duplicated : HashMap :: new ( ) ,
101
105
}
102
106
}
103
107
}
104
108
105
109
impl ReplayDetector for WrappedSlidingWindowDetector {
106
110
fn check ( & mut self , seq : u64 ) -> bool {
111
+ self . duplicated
112
+ . entry ( seq)
113
+ . and_modify ( |i| * i += 1 )
114
+ . or_insert ( 1 ) ;
115
+ self . accepted = false ;
116
+
107
117
self . accepted = false ;
108
118
109
119
if seq > self . max_seq {
110
120
// Exceeded upper limit.
121
+ log:: error!(
122
+ "checked {seq} {}\n upper limit" ,
123
+ self . duplicated. get( & seq) . unwrap_or( & 0 )
124
+ ) ;
111
125
return false ;
112
126
}
113
127
if !self . init {
@@ -129,10 +143,18 @@ impl ReplayDetector for WrappedSlidingWindowDetector {
129
143
130
144
if diff >= self . window_size as i64 {
131
145
// Too old.
146
+ log:: error!(
147
+ "checked {seq} {}\n old" ,
148
+ self . duplicated. get( & seq) . unwrap_or( & 0 )
149
+ ) ;
132
150
return false ;
133
151
}
134
152
if diff >= 0 && self . mask . bit ( diff as usize ) != 0 {
135
153
// The sequence number is duplicated.
154
+ log:: error!(
155
+ "checked {seq} {}\n duplicated" ,
156
+ self . duplicated. get( & seq) . unwrap_or( & 0 )
157
+ ) ;
136
158
return false ;
137
159
}
138
160
0 commit comments