diff --git a/c_src/quicer_config.c b/c_src/quicer_config.c index 53457af8..529c7339 100644 --- a/c_src/quicer_config.c +++ b/c_src/quicer_config.c @@ -571,8 +571,73 @@ encode_parm_to_eterm(ErlNifEnv *env, { ERL_NIF_TERM res = ERROR_TUPLE_2(ATOM_ERROR_NOT_FOUND); if (QUICER_PARAM_HANDLE_TYPE_CONN == Type - && QUIC_PARAM_CONN_STATISTICS == Param - && sizeof(QUIC_STATISTICS) == BufferLength) + && QUIC_PARAM_CONN_STATISTICS_V2 == Param + && sizeof(QUIC_STATISTICS_V2) == BufferLength) + { + QUIC_STATISTICS_V2 *statics = (QUIC_STATISTICS_V2 *)Buffer; + ERL_NIF_TERM term = enif_make_list( + env, + 36, + STAT_TUPLE_U64(ATOM_QUIC_CORRELATION_ID, CorrelationId), + STAT_TUPLE_U32(ATOM_QUIC_VERSION_NEGOTIATION, VersionNegotiation), + STAT_TUPLE_U32(ATOM_QUIC_STATELESS_RETRY, StatelessRetry), + STAT_TUPLE_U32(ATOM_QUIC_RESUMPTION_ATTEMPTED, ResumptionAttempted), + STAT_TUPLE_U32(ATOM_QUIC_RESUMPTION_SUCCEEDED, ResumptionSucceeded), + STAT_TUPLE_U32(ATOM_QUIC_GREASE_BIT_NEGOTIATED, GreaseBitNegotiated), + STAT_TUPLE_U32(ATOM_QUIC_ECN_CAPABLE, EcnCapable), + STAT_TUPLE_U32(ATOM_QUIC_ENCRYPTION_OFFLOADED, EncryptionOffloaded), + STAT_TUPLE_U32(ATOM_QUIC_RESERVED, RESERVED), + STAT_TUPLE_U32(ATOM_QUIC_RTT, Rtt), + STAT_TUPLE_U32(ATOM_QUIC_MIN_RTT, MinRtt), + STAT_TUPLE_U32(ATOM_QUIC_MAX_RTT, MaxRtt), + STAT_TUPLE_U64(ATOM_QUIC_TIMING_START, TimingStart), + STAT_TUPLE_U64(ATOM_QUIC_TIMING_INITIAL_FLIGHT_END, + TimingInitialFlightEnd), + STAT_TUPLE_U64(ATOM_QUIC_TIMING_HANDSHAKE_FLIGHT_END, + TimingHandshakeFlightEnd), + STAT_TUPLE_U32(ATOM_QUIC_HANDSHAKE_CLIENT_FLIGHT_1_BYTES, + HandshakeClientFlight1Bytes), + STAT_TUPLE_U32(ATOM_QUIC_HANDSHAKE_SERVER_FLIGHT_1_BYTES, + HandshakeServerFlight1Bytes), + STAT_TUPLE_U32(ATOM_QUIC_HANDSHAKE_CLIENT_FLIGHT_2_BYTES, + HandshakeClientFlight2Bytes), + STAT_TUPLE_U32(ATOM_QUIC_SEND_PATH_MTU, SendPathMtu), + STAT_TUPLE_U64(ATOM_QUIC_SEND_TOTAL_PACKETS, SendTotalPackets), + STAT_TUPLE_U64(ATOM_QUIC_SEND_RETRANSMITABLE_PACKETS, + SendRetransmittablePackets), + STAT_TUPLE_U64(ATOM_QUIC_SEND_SUSPECTED_LOST_PACKETS, + SendSuspectedLostPackets), + STAT_TUPLE_U64(ATOM_QUIC_SEND_SPURIOUS_LOST_PACKETS, + SendSpuriousLostPackets), + STAT_TUPLE_U64(ATOM_QUIC_SEND_TOTAL_BYTES, SendTotalBytes), + STAT_TUPLE_U64(ATOM_QUIC_SEND_TOTAL_STREAM_BYTES, + SendTotalStreamBytes), + STAT_TUPLE_U32(ATOM_QUIC_SEND_CONGESTION_COUNT, SendCongestionCount), + STAT_TUPLE_U32(ATOM_QUIC_SEND_PERSISTENT_CONGESTION_COUNT, + SendPersistentCongestionCount), + STAT_TUPLE_U64(ATOM_QUIC_RECV_TOTAL_PACKETS, RecvTotalPackets), + STAT_TUPLE_U64(ATOM_QUIC_RECV_REORDERED_PACKETS, + RecvReorderedPackets), + STAT_TUPLE_U64(ATOM_QUIC_RECV_DROPPED_PACKETS, RecvDroppedPackets), + STAT_TUPLE_U64(ATOM_QUIC_RECV_DUPLICATE_PACKETS, + RecvDuplicatePackets), + STAT_TUPLE_U64(ATOM_QUIC_RECV_TOTAL_BYTES, RecvTotalBytes), + STAT_TUPLE_U64(ATOM_QUIC_RECV_TOTAL_STREAM_BYTES, + RecvTotalStreamBytes), + STAT_TUPLE_U64(ATOM_QUIC_RECV_DECRYPTION_FAILURES, + RecvDecryptionFailures), + STAT_TUPLE_U64(ATOM_QUIC_RECV_VALID_ACK_FRAMES, RecvValidAckFrames), + STAT_TUPLE_U32(ATOM_QUIC_KEY_UPDATE_COUNT, KeyUpdateCount), + STAT_TUPLE_U32(ATOM_QUIC_SEND_CONGESTION_WINDOW, + SendCongestionWindow), + STAT_TUPLE_U32(ATOM_QUIC_DEST_CID_UPDATE_COUNT, DestCidUpdateCount), + STAT_TUPLE_U32(ATOM_QUIC_SEND_ECN_CONGESTION_COUNT, + SendEcnCongestionCount)); + res = SUCCESS(term); + } + else if (QUICER_PARAM_HANDLE_TYPE_CONN == Type + && QUIC_PARAM_CONN_STATISTICS == Param + && sizeof(QUIC_STATISTICS) == BufferLength) { QUIC_STATISTICS *statics = (QUIC_STATISTICS *)Buffer; res = SUCCESS(enif_make_list( @@ -1498,6 +1563,11 @@ get_connection_opt(ErlNifEnv *env, Param = QUIC_PARAM_CONN_STATISTICS; BufferLength = sizeof(QUIC_STATISTICS); } + else if (IS_SAME_TERM(optname, ATOM_QUIC_PARAM_CONN_STATISTICS_V2)) + { + Param = QUIC_PARAM_CONN_STATISTICS_V2; + BufferLength = sizeof(QUIC_STATISTICS_V2); + } else if (IS_SAME_TERM(optname, ATOM_QUIC_PARAM_CONN_STATISTICS_PLAT)) { Param = QUIC_PARAM_CONN_STATISTICS_PLAT; diff --git a/c_src/quicer_config.h b/c_src/quicer_config.h index 3ffef943..fffde558 100644 --- a/c_src/quicer_config.h +++ b/c_src/quicer_config.h @@ -124,4 +124,10 @@ ERL_NIF_TERM set_connection_opt(ErlNifEnv *env, const char *QuicStatusToString(_In_ QUIC_STATUS Status); +#define STAT_TUPLE_U64(ATOM, FIELD) \ + enif_make_tuple2(env, ATOM, enif_make_uint64(env, statics->FIELD)) + +#define STAT_TUPLE_U32(ATOM, FIELD) \ + enif_make_tuple2(env, ATOM, enif_make_uint(env, statics->FIELD)) + #endif // __QUICER_CONFIG_H_ diff --git a/c_src/quicer_eterms.h b/c_src/quicer_eterms.h index c5003efa..71b66b2c 100644 --- a/c_src/quicer_eterms.h +++ b/c_src/quicer_eterms.h @@ -175,6 +175,7 @@ extern ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_REMOTE_ADDRESS; extern ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_IDEAL_PROCESSOR; extern ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_SETTINGS; extern ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_STATISTICS; +extern ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_STATISTICS_V2; extern ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_STATISTICS_PLAT; extern ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_SHARE_UDP_BINDING; extern ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_LOCAL_BIDI_STREAM_COUNT; @@ -393,6 +394,54 @@ extern ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED; extern ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED_SPURIOUS; extern ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_CANCELED; +extern ERL_NIF_TERM ATOM_QUIC_CORRELATION_ID; +extern ERL_NIF_TERM ATOM_QUIC_VERSION_NEGOTIATION; +extern ERL_NIF_TERM ATOM_QUIC_STATELESS_RETRY; +extern ERL_NIF_TERM ATOM_QUIC_RESUMPTION_ATTEMPTED; +extern ERL_NIF_TERM ATOM_QUIC_RESUMPTION_SUCCEEDED; +extern ERL_NIF_TERM ATOM_QUIC_GREASE_BIT_NEGOTIATED; +extern ERL_NIF_TERM ATOM_QUIC_ECN_CAPABLE; +extern ERL_NIF_TERM ATOM_QUIC_ENCRYPTION_OFFLOADED; +extern ERL_NIF_TERM ATOM_QUIC_RESERVED; +extern ERL_NIF_TERM ATOM_QUIC_RTT; +extern ERL_NIF_TERM ATOM_QUIC_MIN_RTT; +extern ERL_NIF_TERM ATOM_QUIC_MAX_RTT; + +extern ERL_NIF_TERM ATOM_QUIC_TIMING_START; +extern ERL_NIF_TERM ATOM_QUIC_TIMING_INITIAL_FLIGHT_END; +extern ERL_NIF_TERM ATOM_QUIC_TIMING_HANDSHAKE_FLIGHT_END; + +extern ERL_NIF_TERM ATOM_QUIC_HANDSHAKE_CLIENT_FLIGHT_1_BYTES; +extern ERL_NIF_TERM ATOM_QUIC_HANDSHAKE_SERVER_FLIGHT_1_BYTES; +extern ERL_NIF_TERM ATOM_QUIC_HANDSHAKE_CLIENT_FLIGHT_2_BYTES; + +extern ERL_NIF_TERM ATOM_QUIC_SEND_PATH_MTU; +extern ERL_NIF_TERM ATOM_QUIC_SEND_TOTAL_PACKETS; +extern ERL_NIF_TERM ATOM_QUIC_SEND_RETRANSMITABLE_PACKETS; +extern ERL_NIF_TERM ATOM_QUIC_SEND_SUSPECTED_LOST_PACKETS; +extern ERL_NIF_TERM ATOM_QUIC_SEND_SPURIOUS_LOST_PACKETS; +extern ERL_NIF_TERM ATOM_QUIC_SEND_TOTAL_BYTES; +extern ERL_NIF_TERM ATOM_QUIC_SEND_TOTAL_STREAM_BYTES; +extern ERL_NIF_TERM ATOM_QUIC_SEND_CONGESTION_COUNT; +extern ERL_NIF_TERM ATOM_QUIC_SEND_PERSISTENT_CONGESTION_COUNT; + +extern ERL_NIF_TERM ATOM_QUIC_RECV_TOTAL_PACKETS; +extern ERL_NIF_TERM ATOM_QUIC_RECV_REORDERED_PACKETS; +extern ERL_NIF_TERM ATOM_QUIC_RECV_DROPPED_PACKETS; +extern ERL_NIF_TERM ATOM_QUIC_RECV_DUPLICATE_PACKETS; +extern ERL_NIF_TERM ATOM_QUIC_RECV_TOTAL_BYTES; +extern ERL_NIF_TERM ATOM_QUIC_RECV_TOTAL_STREAM_BYTES; +extern ERL_NIF_TERM ATOM_QUIC_RECV_DECRYPTION_FAILURES; +extern ERL_NIF_TERM ATOM_QUIC_RECV_VALID_ACK_FRAMES; + +extern ERL_NIF_TERM ATOM_QUIC_KEY_UPDATE_COUNT; + +extern ERL_NIF_TERM ATOM_QUIC_SEND_CONGESTION_WINDOW; + +extern ERL_NIF_TERM ATOM_QUIC_DEST_CID_UPDATE_COUNT; + +extern ERL_NIF_TERM ATOM_QUIC_SEND_ECN_CONGESTION_COUNT; + /*----------------------------------------------------------*/ /* ATOMS ends here */ /*----------------------------------------------------------*/ diff --git a/c_src/quicer_nif.c b/c_src/quicer_nif.c index 8885703f..545d8857 100644 --- a/c_src/quicer_nif.c +++ b/c_src/quicer_nif.c @@ -198,6 +198,7 @@ ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_REMOTE_ADDRESS; ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_IDEAL_PROCESSOR; ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_SETTINGS; ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_STATISTICS; +ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_STATISTICS_V2; ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_STATISTICS_PLAT; ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_SHARE_UDP_BINDING; ERL_NIF_TERM ATOM_QUIC_PARAM_CONN_LOCAL_BIDI_STREAM_COUNT; @@ -414,6 +415,53 @@ ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED; ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED_SPURIOUS; ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_CANCELED; +ERL_NIF_TERM ATOM_QUIC_CORRELATION_ID; +ERL_NIF_TERM ATOM_QUIC_VERSION_NEGOTIATION; +ERL_NIF_TERM ATOM_QUIC_STATELESS_RETRY; +ERL_NIF_TERM ATOM_QUIC_RESUMPTION_ATTEMPTED; +ERL_NIF_TERM ATOM_QUIC_RESUMPTION_SUCCEEDED; +ERL_NIF_TERM ATOM_QUIC_GREASE_BIT_NEGOTIATED; +ERL_NIF_TERM ATOM_QUIC_ECN_CAPABLE; +ERL_NIF_TERM ATOM_QUIC_ENCRYPTION_OFFLOADED; +ERL_NIF_TERM ATOM_QUIC_RESERVED; +ERL_NIF_TERM ATOM_QUIC_RTT; +ERL_NIF_TERM ATOM_QUIC_MIN_RTT; +ERL_NIF_TERM ATOM_QUIC_MAX_RTT; + +ERL_NIF_TERM ATOM_QUIC_TIMING_START; +ERL_NIF_TERM ATOM_QUIC_TIMING_INITIAL_FLIGHT_END; +ERL_NIF_TERM ATOM_QUIC_TIMING_HANDSHAKE_FLIGHT_END; + +ERL_NIF_TERM ATOM_QUIC_HANDSHAKE_CLIENT_FLIGHT_1_BYTES; +ERL_NIF_TERM ATOM_QUIC_HANDSHAKE_SERVER_FLIGHT_1_BYTES; +ERL_NIF_TERM ATOM_QUIC_HANDSHAKE_CLIENT_FLIGHT_2_BYTES; + +ERL_NIF_TERM ATOM_QUIC_SEND_PATH_MTU; +ERL_NIF_TERM ATOM_QUIC_SEND_TOTAL_PACKETS; +ERL_NIF_TERM ATOM_QUIC_SEND_RETRANSMITABLE_PACKETS; +ERL_NIF_TERM ATOM_QUIC_SEND_SUSPECTED_LOST_PACKETS; +ERL_NIF_TERM ATOM_QUIC_SEND_SPURIOUS_LOST_PACKETS; +ERL_NIF_TERM ATOM_QUIC_SEND_TOTAL_BYTES; +ERL_NIF_TERM ATOM_QUIC_SEND_TOTAL_STREAM_BYTES; +ERL_NIF_TERM ATOM_QUIC_SEND_CONGESTION_COUNT; +ERL_NIF_TERM ATOM_QUIC_SEND_PERSISTENT_CONGESTION_COUNT; + +ERL_NIF_TERM ATOM_QUIC_RECV_TOTAL_PACKETS; +ERL_NIF_TERM ATOM_QUIC_RECV_REORDERED_PACKETS; +ERL_NIF_TERM ATOM_QUIC_RECV_DROPPED_PACKETS; +ERL_NIF_TERM ATOM_QUIC_RECV_DUPLICATE_PACKETS; +ERL_NIF_TERM ATOM_QUIC_RECV_TOTAL_BYTES; +ERL_NIF_TERM ATOM_QUIC_RECV_TOTAL_STREAM_BYTES; +ERL_NIF_TERM ATOM_QUIC_RECV_DECRYPTION_FAILURES; +ERL_NIF_TERM ATOM_QUIC_RECV_VALID_ACK_FRAMES; + +ERL_NIF_TERM ATOM_QUIC_KEY_UPDATE_COUNT; + +ERL_NIF_TERM ATOM_QUIC_SEND_CONGESTION_WINDOW; + +ERL_NIF_TERM ATOM_QUIC_DEST_CID_UPDATE_COUNT; +ERL_NIF_TERM ATOM_QUIC_SEND_ECN_CONGESTION_COUNT; + // Mirror 'status' in msquic_linux.h /* @@ -556,6 +604,7 @@ ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_CANCELED; ATOM(ATOM_QUIC_PARAM_CONN_IDEAL_PROCESSOR, ideal_processor); \ ATOM(ATOM_QUIC_PARAM_CONN_SETTINGS, settings); \ ATOM(ATOM_QUIC_PARAM_CONN_STATISTICS, statistics); \ + ATOM(ATOM_QUIC_PARAM_CONN_STATISTICS_V2, statistics_v2); \ ATOM(ATOM_QUIC_PARAM_CONN_STATISTICS_PLAT, statistics_plat); \ ATOM(ATOM_QUIC_PARAM_CONN_SHARE_UDP_BINDING, share_udp_binding); \ ATOM(ATOM_QUIC_PARAM_CONN_LOCAL_BIDI_STREAM_COUNT, \ @@ -766,6 +815,49 @@ ERL_NIF_TERM ATOM_QUIC_DATAGRAM_SEND_CANCELED; ATOM(ATOM_QUIC_DATAGRAM_SEND_ACKNOWLEDGED_SPURIOUS, \ dgram_send_acknowledged_spurious); \ ATOM(ATOM_QUIC_DATAGRAM_SEND_CANCELED, dgram_send_canceled); \ + ATOM(ATOM_QUIC_CORRELATION_ID, correlation_id); \ + ATOM(ATOM_QUIC_VERSION_NEGOTIATION, version_negotiation); \ + ATOM(ATOM_QUIC_STATELESS_RETRY, stateless_retry); \ + ATOM(ATOM_QUIC_RESUMPTION_ATTEMPTED, resumption_attempted); \ + ATOM(ATOM_QUIC_RESUMPTION_SUCCEEDED, resumption_succeeded); \ + ATOM(ATOM_QUIC_GREASE_BIT_NEGOTIATED, grease_bit_negotiated); \ + ATOM(ATOM_QUIC_ECN_CAPABLE, ecn_capable); \ + ATOM(ATOM_QUIC_ENCRYPTION_OFFLOADED, encryption_offloaded); \ + ATOM(ATOM_QUIC_RESERVED, reserved); \ + ATOM(ATOM_QUIC_RTT, rtt); \ + ATOM(ATOM_QUIC_MIN_RTT, min_rtt); \ + ATOM(ATOM_QUIC_MAX_RTT, max_rtt); \ + ATOM(ATOM_QUIC_TIMING_START, timing_start); \ + ATOM(ATOM_QUIC_TIMING_INITIAL_FLIGHT_END, timing_initial_flight_end); \ + ATOM(ATOM_QUIC_TIMING_HANDSHAKE_FLIGHT_END, timing_handshake_flight_end); \ + ATOM(ATOM_QUIC_HANDSHAKE_CLIENT_FLIGHT_1_BYTES, \ + handshake_client_flight_1_bytes); \ + ATOM(ATOM_QUIC_HANDSHAKE_SERVER_FLIGHT_1_BYTES, \ + handshake_server_flight_1_bytes); \ + ATOM(ATOM_QUIC_HANDSHAKE_CLIENT_FLIGHT_2_BYTES, \ + handshake_client_flight_2_bytes); \ + ATOM(ATOM_QUIC_SEND_PATH_MTU, send_path_mtu); \ + ATOM(ATOM_QUIC_SEND_TOTAL_PACKETS, send_total_packets); \ + ATOM(ATOM_QUIC_SEND_RETRANSMITABLE_PACKETS, send_retransmittable_packets); \ + ATOM(ATOM_QUIC_SEND_SUSPECTED_LOST_PACKETS, send_suspected_lost_packets); \ + ATOM(ATOM_QUIC_SEND_SPURIOUS_LOST_PACKETS, send_spurious_lost_packets); \ + ATOM(ATOM_QUIC_SEND_TOTAL_BYTES, send_total_bytes); \ + ATOM(ATOM_QUIC_SEND_TOTAL_STREAM_BYTES, send_total_stream_bytes); \ + ATOM(ATOM_QUIC_SEND_CONGESTION_COUNT, send_congestion_count); \ + ATOM(ATOM_QUIC_SEND_PERSISTENT_CONGESTION_COUNT, \ + send_persistent_congestion_count); \ + ATOM(ATOM_QUIC_RECV_TOTAL_PACKETS, recv_total_packets); \ + ATOM(ATOM_QUIC_RECV_REORDERED_PACKETS, recv_reordered_packets); \ + ATOM(ATOM_QUIC_RECV_DROPPED_PACKETS, recv_dropped_packets); \ + ATOM(ATOM_QUIC_RECV_DUPLICATE_PACKETS, recv_duplicate_packets); \ + ATOM(ATOM_QUIC_RECV_TOTAL_BYTES, recv_total_bytes); \ + ATOM(ATOM_QUIC_RECV_TOTAL_STREAM_BYTES, recv_total_stream_bytes); \ + ATOM(ATOM_QUIC_RECV_DECRYPTION_FAILURES, recv_decryption_failures); \ + ATOM(ATOM_QUIC_RECV_VALID_ACK_FRAMES, recv_valid_ack_frames); \ + ATOM(ATOM_QUIC_KEY_UPDATE_COUNT, key_update_count); \ + ATOM(ATOM_QUIC_SEND_CONGESTION_WINDOW, send_congestion_window); \ + ATOM(ATOM_QUIC_DEST_CID_UPDATE_COUNT, dest_cid_update_count); \ + ATOM(ATOM_QUIC_SEND_ECN_CONGESTION_COUNT, send_ecn_congestion_count); \ ATOM(ATOM_UNDEFINED, undefined); extern QuicerRegistrationCTX *G_r_ctx; diff --git a/test/quicer_SUITE.erl b/test/quicer_SUITE.erl index 709cc052..74d5d589 100644 --- a/test/quicer_SUITE.erl +++ b/test/quicer_SUITE.erl @@ -77,6 +77,7 @@ % , tc_getopt_raw/1 tc_getopt/1, + tc_getopt_statistics_v2/1, tc_setopt_conn_settings/1, tc_setopt_bad_opt/1, tc_setopt_bad_nst/1, @@ -1004,6 +1005,66 @@ tc_getopt(Config) -> ct:fail("listener_timeout") end. +tc_getopt_statistics_v2(Config) -> + Parm = statistics_v2, + Port = select_port(), + Owner = self(), + {SPid, Ref} = spawn_monitor(fun() -> echo_server(Owner, Config, Port) end), + receive + listener_ready -> + ok + after 5000 -> + ct:fail("listener_timeout") + end, + {ok, Conn} = quicer:connect("localhost", Port, default_conn_opts(), 5000), + {ok, Stats} = quicer:getopt(Conn, Parm, false), + {ok, Stm} = quicer:start_stream(Conn, []), + {ok, 4} = quicer:send(Stm, <<"ping">>), + ?assertMatch( + [ + {correlation_id, _}, + {version_negotiation, _}, + {stateless_retry, _}, + {resumption_attempted, _}, + {resumption_succeeded, _}, + {grease_bit_negotiated, _}, + {ecn_capable, _}, + {encryption_offloaded, _}, + {reserved, _}, + {rtt, _}, + {min_rtt, _}, + {max_rtt, _}, + {timing_start, _}, + {timing_initial_flight_end, _}, + {timing_handshake_flight_end, _}, + {handshake_client_flight_1_bytes, _}, + {handshake_server_flight_1_bytes, _}, + {handshake_client_flight_2_bytes, _}, + {send_path_mtu, _}, + {send_total_packets, _}, + {send_retransmittable_packets, _}, + {send_suspected_lost_packets, _}, + {send_spurious_lost_packets, _}, + {send_total_bytes, _}, + {send_total_stream_bytes, _}, + {send_congestion_count, _}, + {send_persistent_congestion_count, _}, + {recv_total_packets, _}, + {recv_reordered_packets, _}, + {recv_dropped_packets, _}, + {recv_duplicate_packets, _}, + {recv_total_bytes, _}, + {recv_total_stream_bytes, _}, + {recv_decryption_failures, _}, + {recv_valid_ack_frames, _}, + {key_update_count, _} + ], + Stats + ), + SPid ! done, + ensure_server_exit_normal(Ref), + ok. + tc_getopt_settings(Config) -> Port = select_port(), Owner = self(),