@@ -13,7 +13,7 @@ use quinn::{rustls, ClientConfig, MtuDiscoveryConfig};
1313use rand:: random;
1414use static_assertions:: const_assert;
1515use std:: net:: { Ipv4Addr , SocketAddr } ;
16- use std:: num:: NonZeroU32 ;
16+ use std:: num:: { NonZeroU32 , Saturating } ;
1717use std:: ops:: ControlFlow ;
1818use std:: sync:: { Arc , Mutex } ;
1919use thiserror:: Error ;
@@ -111,7 +111,8 @@ struct WgState {
111111 buffer : Vec < u8 > ,
112112 wg : Tunn ,
113113 traffic_stats : QuicWgTrafficStats ,
114- ticks_since_last_packet : u32 ,
114+ ticks_since_last_packet : Saturating < u32 > ,
115+ ticks_since_last_pong : Saturating < u32 > ,
115116 last_send_err_logged_at : Option < Instant > ,
116117}
117118
@@ -151,7 +152,8 @@ impl QuicWgConn {
151152 wg,
152153 traffic_stats : QuicWgTrafficStats { connected_at : now, tx_bytes : 0 , rx_bytes : 0 , latest_latency_ms : 0 } ,
153154 buffer : vec ! [ 0u8 ; u16 :: MAX as usize ] ,
154- ticks_since_last_packet : 0 ,
155+ ticks_since_last_packet : Saturating ( 0 ) ,
156+ ticks_since_last_pong : Saturating ( 0 ) ,
155157 last_send_err_logged_at : None ,
156158 } ) ;
157159 Ok ( Self {
@@ -293,9 +295,10 @@ impl QuicWgConn {
293295 select_biased ! {
294296 _ = self . wg_tick_notify. notified( ) . fuse( ) => {
295297 let mut wg_state = self . wg_state. lock( ) . unwrap( ) ;
296- let WgState { buffer, wg, ticks_since_last_packet, .. } = & mut * wg_state;
297- if ticks_since_last_packet. saturating_mul( WG_TICK_MS ) > WG_MAX_IDLE_MS {
298- tracing:: error!( "no packets received for at least {WG_MAX_IDLE_MS}ms" ) ;
298+ let WgState { buffer, wg, ticks_since_last_packet, ticks_since_last_pong, .. } = & mut * wg_state;
299+ tracing:: info!( message_id = "WKqFjXMA" , ticks_since_last_packet = ticks_since_last_packet. 0 , ticks_since_last_pong = ticks_since_last_pong. 0 , "wg tick" ) ;
300+ if ( * ticks_since_last_packet * Saturating ( WG_TICK_MS ) ) . 0 > WG_MAX_IDLE_MS {
301+ tracing:: error!( message_id = "YQwnx6rF" , "no packets received for {WG_MAX_IDLE_MS}ms" ) ;
299302 return Err ( QuicWgReceiveError :: WireguardIdleTimeout )
300303 }
301304 loop {
@@ -309,12 +312,13 @@ impl QuicWgConn {
309312 let ping_packet = self . build_ping_keepalive_packet( ) ;
310313 let ping_result = wg. encapsulate( & ping_packet, buffer) ;
311314 Self :: handle_result( & self . quic, ping_result) ?;
312- * ticks_since_last_packet += 1 ;
315+ * ticks_since_last_packet += 1 ;
316+ * ticks_since_last_pong += 1 ;
313317 }
314318 receive_quic = self . receive_quic( ) . fuse( ) => {
315319 let mut datagram = receive_quic?;
316320 let mut wg_state = self . wg_state. lock( ) . unwrap( ) ;
317- let WgState { buffer, wg, ticks_since_last_packet, traffic_stats, .. } = & mut * wg_state;
321+ let WgState { buffer, wg, ticks_since_last_packet, ticks_since_last_pong , traffic_stats, .. } = & mut * wg_state;
318322 loop {
319323 let res = wg. decapsulate( None , & datagram, buffer) ;
320324 match Self :: handle_result( & self . quic, res) ? {
@@ -323,11 +327,12 @@ impl QuicWgConn {
323327 continue
324328 }
325329 ControlFlow :: Break ( Some ( packet) ) => {
326- * ticks_since_last_packet = 0 ;
330+ * ticks_since_last_packet = Saturating ( 0 ) ;
327331 traffic_stats. rx_bytes += packet. len( ) as u64 ;
328332 if let Some ( latest_latency_ms) = self . latency_ms_from_pong_keepalive_packet( & packet) {
329333 tracing:: info!( "received keepalive pong after {}ms" , latest_latency_ms) ;
330334 traffic_stats. latest_latency_ms = latest_latency_ms;
335+ * ticks_since_last_pong = Saturating ( 0 ) ;
331336 break
332337 }
333338 return Ok ( packet)
0 commit comments