@@ -237,6 +237,13 @@ impl Tunn {
237237 }
238238 }
239239
240+ fn next_expired_session ( & self ) -> Option < Instant > {
241+ self . sessions
242+ . iter ( )
243+ . flat_map ( |s| Some ( s. as_ref ( ) ?. established_at ( ) + REJECT_AFTER_TIME ) )
244+ . min ( )
245+ }
246+
240247 #[ deprecated( note = "Prefer `Timers::update_timers_at` to avoid time-impurity" ) ]
241248 pub fn update_timers < ' a > ( & mut self , dst : & ' a mut [ u8 ] ) -> TunnResult < ' a > {
242249 self . update_timers_at ( dst, Instant :: now ( ) )
@@ -420,7 +427,36 @@ impl Tunn {
420427 ///
421428 /// If this returns `None`, you may call it at your usual desired precision (usually once a second is enough).
422429 pub fn next_timer_update ( & self ) -> Option < Instant > {
423- self . timers . send_handshake_at
430+ // Mimic the `update_timers_at` function: If we have a handshake scheduled, other timers don't matter.
431+ if let Some ( scheduled_handshake) = self . timers . send_handshake_at {
432+ return Some ( scheduled_handshake) ;
433+ }
434+
435+ let common_timers = [
436+ self . next_expired_session ( ) ,
437+ self . handshake . cookie_expiration ( ) ,
438+ Some ( self . timers . reject_after_time ( ) ) ,
439+ ]
440+ . into_iter ( ) ;
441+
442+ if let Some ( rekey_timeout) = self . handshake . rekey_timeout ( ) {
443+ earliest (
444+ common_timers. chain ( [ Some ( rekey_timeout) , Some ( self . timers . rekey_attempt_time ( ) ) ] ) ,
445+ )
446+ } else {
447+ // Persistent keep-alive only makes sense if the current session is active.
448+ let persistent_keepalive = self . sessions [ self . current % N_SESSIONS ]
449+ . as_ref ( )
450+ . and_then ( |_| self . timers . next_persistent_keepalive ( ) ) ;
451+
452+ earliest ( common_timers. chain ( [
453+ self . timers . rekey_after_time_on_send ( ) ,
454+ self . timers . reject_after_time_on_receive ( ) ,
455+ self . timers . rekey_after_time_without_response ( ) ,
456+ self . timers . keepalive_after_time_without_send ( ) ,
457+ persistent_keepalive,
458+ ] ) )
459+ }
424460 }
425461
426462 #[ deprecated( note = "Prefer `Tunn::time_since_last_handshake_at` to avoid time-impurity" ) ]
@@ -449,3 +485,7 @@ impl Tunn {
449485 }
450486 }
451487}
488+
489+ fn earliest ( instants : impl IntoIterator < Item = Option < Instant > > ) -> Option < Instant > {
490+ instants. into_iter ( ) . flatten ( ) . min ( )
491+ }
0 commit comments