Skip to content

Commit 17b6220

Browse files
quic: dynamically disable keep_alive
1 parent 3274a66 commit 17b6220

File tree

4 files changed

+44
-11
lines changed

4 files changed

+44
-11
lines changed

src/waltz/quic/fd_quic.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2957,7 +2957,7 @@ fd_quic_svc_poll( fd_quic_t * quic,
29572957
fd_quic_set_conn_state( conn, FD_QUIC_CONN_STATE_DEAD );
29582958
quic->metrics.conn_timeout_cnt++;
29592959
}
2960-
} else if( quic->config.keep_alive ) {
2960+
} else if( quic->config.keep_alive & !!(conn->let_die_ticks > now) ) {
29612961
/* send PING */
29622962
if( !( conn->flags & FD_QUIC_CONN_FLAGS_PING ) ) {
29632963
conn->flags |= FD_QUIC_CONN_FLAGS_PING;
@@ -4446,6 +4446,7 @@ fd_quic_conn_create( fd_quic_t * quic,
44464446
/* idle timeout */
44474447
conn->idle_timeout_ticks = config->idle_timeout;
44484448
conn->last_activity = state->now;
4449+
conn->let_die_ticks = ULONG_MAX;
44494450

44504451
/* update metrics */
44514452
quic->metrics.conn_active_cnt++;
@@ -5645,3 +5646,10 @@ fd_quic_conn_close( fd_quic_conn_t * conn,
56455646
/* set connection to be serviced ASAP */
56465647
fd_quic_svc_schedule1( conn, FD_QUIC_SVC_INSTANT );
56475648
}
5649+
5650+
void
5651+
fd_quic_conn_let_die( fd_quic_conn_t * conn,
5652+
ulong keep_alive_duration_ticks ) {
5653+
ulong const now = fd_quic_get_state( conn->quic )->now;
5654+
conn->let_die_ticks = fd_ulong_sat_add( now, keep_alive_duration_ticks );
5655+
}

src/waltz/quic/fd_quic.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -555,6 +555,23 @@ FD_QUIC_API void
555555
fd_quic_conn_close( fd_quic_conn_t * conn,
556556
uint reason );
557557

558+
/* fd_quic_conn_let_die stops keeping a conn alive after
559+
'keep_alive_duration_ticks'. No-op if keep-alive is not configured.
560+
Safe to call on a connection in any state.
561+
562+
If called multiple times on the same connection, only the latest
563+
call will stay in effect. However, it may not take effect if we
564+
already skipped a keep-alive due to a previous call. 'Undoing' a
565+
previous call can be done by passing ULONG_MAX.
566+
567+
This function does NOT guarantee that the connection will be closed
568+
immediately after the given duration. Rather, it just disables keep-alive
569+
behavior after the given duration. */
570+
571+
FD_QUIC_API void
572+
fd_quic_conn_let_die( fd_quic_conn_t * conn,
573+
ulong keep_alive_duration_ticks );
574+
558575
/* Service API ********************************************************/
559576

560577
/* fd_quic_get_next_wakeup returns the next requested service time.

src/waltz/quic/fd_quic_conn.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ struct fd_quic_conn {
212212
ulong idle_timeout_ticks;
213213
ulong last_activity;
214214
ulong last_ack;
215+
ulong let_die_ticks; /* stop keep-alive after this time */
215216

216217
/* round trip time related members */
217218
fd_rtt_estimate_t rtt[1];

src/waltz/quic/tests/test_quic_keep_alive.c

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -59,17 +59,24 @@ test_quic_keep_alive( fd_quic_t * client_quic, fd_quic_t * server_quic, int keep
5959
ulong const idle_timeout = client_quic->config.idle_timeout;
6060
ulong const timestep = idle_timeout>>3;
6161

62-
for( int i=0; i<10; ++i ) {
63-
now+=timestep;
64-
fd_quic_service( client_quic );
65-
fd_quic_service( server_quic );
66-
}
67-
if( keep_alive ) {
68-
FD_TEST( client_conn->state == FD_QUIC_CONN_STATE_ACTIVE );
69-
} else {
70-
FD_TEST( client_conn->state == FD_QUIC_CONN_STATE_DEAD ||
71-
client_conn->state == FD_QUIC_CONN_STATE_INVALID );
62+
63+
for( int let_die=0; let_die<2; ++let_die ) {
64+
for( int i=0; i<10; ++i ) {
65+
now+=timestep;
66+
fd_quic_service( client_quic );
67+
fd_quic_service( server_quic );
68+
}
69+
70+
if( keep_alive & !let_die ) {
71+
FD_TEST( client_conn->state == FD_QUIC_CONN_STATE_ACTIVE );
72+
} else {
73+
FD_TEST( client_conn->state == FD_QUIC_CONN_STATE_DEAD ||
74+
client_conn->state == FD_QUIC_CONN_STATE_INVALID );
75+
}
76+
77+
fd_quic_conn_let_die( client_conn, timestep );
7278
}
79+
7380
}
7481

7582

0 commit comments

Comments
 (0)