@@ -767,12 +767,17 @@ impl Session {
767767 let mut opening_cipher = Box :: new ( clear:: Key ) as Box < dyn OpeningKey + Send > ;
768768 std:: mem:: swap ( & mut opening_cipher, & mut self . common . cipher . remote_to_local ) ;
769769
770+ let time_for_keepalive = tokio:: time:: sleep_until ( self . common . config . keepalive_deadline ( ) ) ;
770771 let reading = start_reading ( stream_read, buffer, opening_cipher) ;
771772 pin ! ( reading) ;
773+ pin ! ( time_for_keepalive) ;
772774
773775 #[ allow( clippy:: panic) ] // false positive in select! macro
774776 while !self . common . disconnected {
775777 tokio:: select! {
778+ ( ) = & mut time_for_keepalive => {
779+ self . send_keepalive( true ) ;
780+ }
776781 r = & mut reading => {
777782 let ( stream_read, buffer, mut opening_cipher) = match r {
778783 Ok ( ( _, stream_read, buffer, opening_cipher) ) => ( stream_read, buffer, opening_cipher) ,
@@ -812,6 +817,7 @@ impl Session {
812817
813818 std:: mem:: swap( & mut opening_cipher, & mut self . common. cipher. remote_to_local) ;
814819 reading. set( start_reading( stream_read, buffer, opening_cipher) ) ;
820+ time_for_keepalive. as_mut( ) . reset( self . common. config. keepalive_deadline( ) ) ;
815821 }
816822 msg = self . receiver. recv( ) , if !self . is_rekeying( ) => {
817823 match msg {
@@ -829,6 +835,7 @@ impl Session {
829835 Err ( _) => break
830836 }
831837 }
838+ time_for_keepalive. as_mut( ) . reset( self . common. config. keepalive_deadline( ) ) ;
832839 }
833840 msg = self . inbound_channel_receiver. recv( ) , if !self . is_rekeying( ) => {
834841 match msg {
@@ -1260,10 +1267,18 @@ pub struct Config {
12601267 pub preferred : negotiation:: Preferred ,
12611268 /// Time after which the connection is garbage-collected.
12621269 pub inactivity_timeout : Option < std:: time:: Duration > ,
1270+ /// If nothing is sent or received for this amount of time, send a keepalive message.
1271+ pub keepalive_interval : Option < std:: time:: Duration > ,
12631272 /// Whether to expect and wait for an authentication call.
12641273 pub anonymous : bool ,
12651274}
12661275
1276+ impl Config {
1277+ fn keepalive_deadline ( & self ) -> tokio:: time:: Instant {
1278+ tokio:: time:: Instant :: now ( ) + self . keepalive_interval . unwrap_or ( std:: time:: Duration :: from_secs ( 86400 * 365 ) )
1279+ }
1280+ }
1281+
12671282impl Default for Config {
12681283 fn default ( ) -> Config {
12691284 Config {
@@ -1277,6 +1292,7 @@ impl Default for Config {
12771292 maximum_packet_size : 32768 ,
12781293 preferred : Default :: default ( ) ,
12791294 inactivity_timeout : None ,
1295+ keepalive_interval : None ,
12801296 anonymous : false ,
12811297 }
12821298 }
0 commit comments