11#[ cfg( test) ]
22mod replay_detector_test;
33
4+ use std:: collections:: HashMap ;
5+
46use super :: fixed_big_int:: * ;
57
68// ReplayDetector is the interface of sequence replay detector.
@@ -84,6 +86,7 @@ pub struct WrappedSlidingWindowDetector {
8486 window_size : usize ,
8587 mask : FixedBigInt ,
8688 init : bool ,
89+ duplicated : HashMap < u64 , u8 > ,
8790}
8891
8992impl WrappedSlidingWindowDetector {
@@ -98,16 +101,27 @@ impl WrappedSlidingWindowDetector {
98101 window_size,
99102 mask : FixedBigInt :: new ( window_size) ,
100103 init : false ,
104+ duplicated : HashMap :: new ( ) ,
101105 }
102106 }
103107}
104108
105109impl ReplayDetector for WrappedSlidingWindowDetector {
106110 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+
107117 self . accepted = false ;
108118
109119 if seq > self . max_seq {
110120 // Exceeded upper limit.
121+ log:: error!(
122+ "checked {seq} {}\n upper limit" ,
123+ self . duplicated. get( & seq) . unwrap_or( & 0 )
124+ ) ;
111125 return false ;
112126 }
113127 if !self . init {
@@ -129,10 +143,18 @@ impl ReplayDetector for WrappedSlidingWindowDetector {
129143
130144 if diff >= self . window_size as i64 {
131145 // Too old.
146+ log:: error!(
147+ "checked {seq} {}\n old" ,
148+ self . duplicated. get( & seq) . unwrap_or( & 0 )
149+ ) ;
132150 return false ;
133151 }
134152 if diff >= 0 && self . mask . bit ( diff as usize ) != 0 {
135153 // The sequence number is duplicated.
154+ log:: error!(
155+ "checked {seq} {}\n duplicated" ,
156+ self . duplicated. get( & seq) . unwrap_or( & 0 )
157+ ) ;
136158 return false ;
137159 }
138160
0 commit comments