@@ -67,8 +67,7 @@ pub enum TimerName {
67
67
}
68
68
69
69
impl TimerName {
70
- pub const VALUES : [ Self ; TimerName :: Top as usize ] = [
71
- Self :: TimeCurrent ,
70
+ pub const VALUES : [ Self ; TimerName :: Top as usize - 1 ] = [
72
71
Self :: TimeSessionEstablished ,
73
72
Self :: TimeLastHandshakeStarted ,
74
73
Self :: TimeLastPacketReceived ,
@@ -215,6 +214,14 @@ impl Tunn {
215
214
}
216
215
}
217
216
217
+ fn tick_marked_timers ( & mut self , timer_mask : u16 ) {
218
+ for timer_name in TimerName :: VALUES {
219
+ if ( timer_mask & ( 1 << ( timer_name as u16 ) ) ) != 0 {
220
+ self . timer_tick ( timer_name) ;
221
+ }
222
+ }
223
+ }
224
+
218
225
pub fn update_timers < ' a > ( & mut self , dst : & ' a mut [ u8 ] ) -> TunnResult < ' a > {
219
226
let mut handshake_initiation_required = false ;
220
227
let mut keepalive_required = false ;
@@ -234,16 +241,8 @@ impl Tunn {
234
241
let timer_mask = self
235
242
. timers
236
243
. timers_to_update_mask
237
- . load ( std:: sync:: atomic:: Ordering :: Relaxed ) ;
238
- for timer_name in TimerName :: VALUES {
239
- if ( timer_mask & ( 1 << ( timer_name as u16 ) ) ) != 0 {
240
- self . timer_tick ( timer_name) ;
241
- }
242
- }
243
- // Reset all marked bits
244
- self . timers
245
- . timers_to_update_mask
246
- . store ( 0 , std:: sync:: atomic:: Ordering :: Relaxed ) ;
244
+ . swap ( 0 , std:: sync:: atomic:: Ordering :: Relaxed ) ;
245
+ self . tick_marked_timers ( timer_mask) ;
247
246
248
247
self . update_session_timers ( now) ;
249
248
@@ -429,7 +428,7 @@ mod tests {
429
428
use super :: TimerName ;
430
429
431
430
#[ test]
432
- fn create_two_tuns ( ) {
431
+ fn test_update_marked_timers ( ) {
433
432
let my_secret_key = x25519_dalek:: StaticSecret :: random_from_rng ( OsRng ) ;
434
433
let my_idx = OsRng . next_u32 ( ) ;
435
434
@@ -469,4 +468,41 @@ mod tests {
469
468
assert ! ( my_tun. timers[ TimerName :: TimeLastDataPacketReceived ] . is_zero( ) ) ;
470
469
assert ! ( my_tun. timers[ TimerName :: TimePersistentKeepalive ] . is_zero( ) ) ;
471
470
}
471
+
472
+ #[ test]
473
+ fn test_mark_timers_during_update ( ) {
474
+ let my_secret_key = x25519_dalek:: StaticSecret :: random_from_rng ( OsRng ) ;
475
+ let my_idx = OsRng . next_u32 ( ) ;
476
+
477
+ let their_secret_key = x25519_dalek:: StaticSecret :: random_from_rng ( OsRng ) ;
478
+ let their_public_key = x25519_dalek:: PublicKey :: from ( & their_secret_key) ;
479
+
480
+ let mut my_tun =
481
+ Tunn :: new ( my_secret_key, their_public_key, None , None , my_idx, None ) . unwrap ( ) ;
482
+
483
+ // Mark timers to update
484
+ my_tun. mark_timer_to_update ( super :: TimerName :: TimeLastDataPacketSent ) ;
485
+
486
+ let timer_mask = my_tun
487
+ . timers
488
+ . timers_to_update_mask
489
+ . swap ( 0 , std:: sync:: atomic:: Ordering :: Relaxed ) ;
490
+
491
+ my_tun. mark_timer_to_update ( super :: TimerName :: TimeLastDataPacketReceived ) ;
492
+
493
+ my_tun. tick_marked_timers ( timer_mask) ;
494
+
495
+ // Only those timers marked should be udpated
496
+ assert ! ( !my_tun. timers[ TimerName :: TimeLastDataPacketSent ] . is_zero( ) ) ;
497
+ assert ! ( my_tun. timers[ TimerName :: TimeLastDataPacketReceived ] . is_zero( ) ) ;
498
+
499
+ // Reset the timers
500
+ my_tun. timers [ TimerName :: TimeLastDataPacketSent ] = SafeDuration :: from_millis ( 0 ) ;
501
+
502
+ my_tun. update_timers ( & mut [ 0 ] ) ;
503
+
504
+ // Now the timers should not update
505
+ assert ! ( my_tun. timers[ TimerName :: TimeLastDataPacketSent ] . is_zero( ) ) ;
506
+ assert ! ( !my_tun. timers[ TimerName :: TimeLastDataPacketReceived ] . is_zero( ) ) ;
507
+ }
472
508
}
0 commit comments