Skip to content

Commit

Permalink
quic: test FD_QUIC_ACK_TX_ENOSPC metrics reporting
Browse files Browse the repository at this point in the history
  • Loading branch information
riptl authored and ripatel-fd committed Dec 10, 2024
1 parent 53568e6 commit 36bd1a5
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 2 deletions.
43 changes: 43 additions & 0 deletions src/waltz/quic/tests/fd_quic_sandbox.c
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#include "fd_quic_sandbox.h"
#include "../fd_quic_private.h"
#include "../templ/fd_quic_parse_util.h"

/* fd_quic_sandbox_capture_pkt captures a single outgoing packet sent by
fd_quic. */
Expand Down Expand Up @@ -304,6 +305,7 @@ fd_quic_sandbox_new_conn_established( fd_quic_sandbox_t * sandbox,
conn->handshake_complete = 1;
conn->hs_data_empty = 1;
conn->peer_enc_level = fd_quic_enc_level_appdata_id;
conn->keys_avail = 1U<<fd_quic_enc_level_appdata_id;

conn->idle_timeout = FD_QUIC_SANDBOX_IDLE_TIMEOUT;
conn->last_activity = sandbox->wallclock;
Expand Down Expand Up @@ -382,3 +384,44 @@ fd_quic_sandbox_send_lone_frame( fd_quic_sandbox_t * sandbox,
/* Synchronize log seq[0] from tx to rx */
fd_quic_log_tx_seq_update( fd_quic_get_state( sandbox->quic )->log_tx );
}

void
fd_quic_sandbox_send_ping_pkt( fd_quic_sandbox_t * sandbox,
fd_quic_conn_t * conn,
ulong pktnum ) {

uchar pkt_buf[ 256 ];
pkt_buf[0] = fd_quic_one_rtt_h0( /* spin */ 0,
/* key_phase */ !!conn->key_phase,
/* pktnum_len-1 */ 3 );
memcpy( pkt_buf+1, &conn->our_conn_id, FD_QUIC_CONN_ID_SZ );
uint pktnum_comp = fd_uint_bswap( (uint)( pktnum & UINT_MAX ) );
memcpy( pkt_buf+9, &pktnum_comp, 4 );
pkt_buf[13] = 0x01; /* PING frame */
memset( pkt_buf+14, 0, 18UL );

fd_quic_crypto_keys_t * keys = &conn->keys[fd_quic_enc_level_appdata_id][!conn->server];
ulong out_sz = 48UL;
int crypt_res = fd_quic_crypto_encrypt( pkt_buf, &out_sz, pkt_buf, 13UL, pkt_buf+13, 19UL, keys, keys, pktnum );
FD_TEST( crypt_res==FD_QUIC_SUCCESS );

fd_quic_pkt_t pkt_meta = {
.ip4 = {{
.verihl = FD_IP4_VERIHL(4,5),
.net_tot_len = 28,
.net_frag_off = 0x4000u, /* don't fragment */
.ttl = 64,
.protocol = FD_IP4_HDR_PROTOCOL_UDP,
}},
.udp = {{
.net_sport = FD_QUIC_SANDBOX_PEER_PORT,
.net_dport = FD_QUIC_SANDBOX_SELF_PORT,
.net_len = 8,
}},
.pkt_number = pktnum,
.rcv_time = sandbox->wallclock,
.enc_level = fd_quic_enc_level_appdata_id,
};

fd_quic_process_quic_packet_v1( sandbox->quic, &pkt_meta, pkt_buf, out_sz );
}
8 changes: 8 additions & 0 deletions src/waltz/quic/tests/fd_quic_sandbox.h
Original file line number Diff line number Diff line change
Expand Up @@ -225,6 +225,14 @@ fd_quic_sandbox_send_lone_frame( fd_quic_sandbox_t * sandbox,
uchar const * frame,
ulong frame_sz );

/* fd_quic_sandbox_send_ping_pkt sends a 1-RTT packet containing only a
PING frame. */

void
fd_quic_sandbox_send_ping_pkt( fd_quic_sandbox_t * sandbox,
fd_quic_conn_t * conn,
ulong pktnum );

FD_PROTOTYPES_END

#endif /* HEADER_fd_src_waltz_quic_tests_fd_quic_sandbox_h */
37 changes: 35 additions & 2 deletions src/waltz/quic/tests/test_quic_conformance.c
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,40 @@ test_quic_server_alpn_fail( fd_quic_sandbox_t * sandbox,

}

/* Ensure that outgoing ACKs and metrics are done correctly if incoming
packets skip packet numbers aggressively. */

void
test_quic_pktnum_skip( fd_quic_sandbox_t * sandbox,
fd_rng_t * rng ) {

fd_quic_sandbox_init( sandbox, FD_QUIC_ROLE_SERVER );
fd_quic_conn_t * conn = fd_quic_sandbox_new_conn_established( sandbox, rng );
fd_quic_ack_gen_t * ack_gen = conn->ack_gen;
fd_quic_metrics_t * metrics = &conn->quic->metrics;
FD_TEST( ack_gen->tail==0 && ack_gen->head==0 );

/* Fill the ACK TX buffer with pending ACK frames */
ulong pktnum = 60UL;
for( ulong j=0UL; j<FD_QUIC_ACK_QUEUE_CNT; j++ ) {
fd_quic_sandbox_send_ping_pkt( sandbox, conn, pktnum );
pktnum += 2UL;
}
FD_TEST( metrics->pkt_decrypt_fail_cnt==0 );
FD_TEST( ack_gen->head - ack_gen->tail == FD_QUIC_ACK_QUEUE_CNT );
FD_TEST( metrics->ack_tx[ FD_QUIC_ACK_TX_NOOP ] == 0 );
FD_TEST( metrics->ack_tx[ FD_QUIC_ACK_TX_NEW ] == FD_QUIC_ACK_QUEUE_CNT );
FD_TEST( metrics->ack_tx[ FD_QUIC_ACK_TX_MERGED ] == 0 );
FD_TEST( metrics->ack_tx[ FD_QUIC_ACK_TX_ENOSPC ] == 0 );
FD_TEST( metrics->ack_tx[ FD_QUIC_ACK_TX_CANCEL ] == 0 );

/* Overflow the ACK queue */
fd_quic_sandbox_send_ping_pkt( sandbox, conn, pktnum );
pktnum += 2UL;
FD_TEST( metrics->ack_tx[ FD_QUIC_ACK_TX_ENOSPC ] == 1 );

}

static __attribute__((noinline)) void
test_quic_parse_path_challenge( void ) {
fd_quic_path_challenge_frame_t path_challenge[1];
Expand All @@ -251,8 +285,6 @@ test_quic_parse_path_challenge( void ) {
} while(0);
}

/* Test FIN arriving out of place */

int
main( int argc,
char ** argv ) {
Expand Down Expand Up @@ -304,6 +336,7 @@ main( int argc,
test_quic_stream_concurrency ( sandbox, rng );
test_quic_ping_frame ( sandbox, rng );
test_quic_server_alpn_fail ( sandbox, rng );
test_quic_pktnum_skip ( sandbox, rng );
test_quic_parse_path_challenge();

/* Wind down */
Expand Down

0 comments on commit 36bd1a5

Please sign in to comment.