Skip to content

Commit 7b9877a

Browse files
committed
Add statistics support for CWND and RTT
1 parent f533949 commit 7b9877a

5 files changed

Lines changed: 75 additions & 31 deletions

File tree

src/iperf_api.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -630,7 +630,7 @@ iperf_set_on_test_finish_callback(struct iperf_test* ipt, void (*callback)(struc
630630
static void
631631
check_sender_has_retransmits(struct iperf_test *ipt)
632632
{
633-
if (ipt->mode != RECEIVER && ipt->protocol->id == Ptcp && has_tcpinfo_retransmits())
633+
if (ipt->mode != RECEIVER && (ipt->protocol->id == Ptcp || ipt->protocol->id == Pquic) && has_tcpinfo_retransmits())
634634
ipt->sender_has_retransmits = 1;
635635
else
636636
ipt->sender_has_retransmits = 0;
@@ -2661,7 +2661,7 @@ get_parameters(struct iperf_test *test)
26612661
#endif //HAVE_SSL
26622662
if ((j_p = cJSON_GetObjectItem(j, "skip_rx_copy")) != NULL)
26632663
test->settings->skip_rx_copy = j_p->valueint;
2664-
if (test->mode && test->protocol->id == Ptcp && has_tcpinfo_retransmits())
2664+
if (test->mode && (test->protocol->id == Ptcp || test->protocol->id == Pquic) && has_tcpinfo_retransmits())
26652665
test->sender_has_retransmits = 1;
26662666
if (test->settings->rate)
26672667
cJSON_AddNumberToObject(test->json_start, "target_bitrate", test->settings->rate);
@@ -3746,7 +3746,7 @@ iperf_stats_callback(struct iperf_test *test)
37463746
memcpy(&temp.interval_end_time, &rp->end_time, sizeof(struct iperf_time));
37473747
iperf_time_diff(&temp.interval_start_time, &temp.interval_end_time, &temp_time);
37483748
temp.interval_duration = iperf_time_in_secs(&temp_time);
3749-
if (test->protocol->id == Ptcp) {
3749+
if (test->protocol->id == Ptcp || test->protocol->id == Pquic) {
37503750
if ( has_tcpinfo()) {
37513751
save_tcpinfo(sp, &temp);
37523752
if (test->sender_has_retransmits == 1) {
@@ -3985,7 +3985,7 @@ iperf_print_intermediate(struct iperf_test *test)
39853985
return;
39863986
}
39873987
bytes += irp->bytes_transferred;
3988-
if (test->protocol->id == Ptcp) {
3988+
if (test->protocol->id == Ptcp || test->protocol->id == Pquic) {
39893989
if (test->sender_has_retransmits == 1) {
39903990
retransmits += irp->interval_retrans;
39913991
}
@@ -4028,7 +4028,7 @@ iperf_print_intermediate(struct iperf_test *test)
40284028
start_time = iperf_time_in_secs(&temp_time);
40294029
iperf_time_diff(&sp->result->start_time,&irp->interval_end_time, &temp_time);
40304030
end_time = iperf_time_in_secs(&temp_time);
4031-
if (test->protocol->id == Ptcp || test->protocol->id == Psctp) {
4031+
if (test->protocol->id == Ptcp || test->protocol->id == Psctp || test->protocol->id == Pquic) {
40324032
if (test->sender_has_retransmits == 1 && stream_must_be_sender) {
40334033
/* Interval sum, TCP with retransmits. */
40344034
if (test->json_output)

src/iperf_error.c

Lines changed: 24 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,10 +32,7 @@
3232
#include <stdarg.h>
3333
#include "iperf.h"
3434
#include "iperf_api.h"
35-
36-
#if defined(HAVE_QUIC_NGTCP2)
3735
#include "iperf_quic.h"
38-
#endif /* HAVE_QUIC_NGTCP2 */
3936

4037
int gerror;
4138

@@ -449,27 +446,6 @@ iperf_strerror(int int_errno)
449446
case IESTREAMID:
450447
snprintf(errstr, len, "stream has an invalid id");
451448
break;
452-
case IEQUICINIT:
453-
snprintf(errstr, len, "unable to initialize QUIC stream");
454-
break;
455-
case IEQUICCONNECTIONID:
456-
snprintf(errstr, len, "unable to set QUIC connection ID in call-back function");
457-
break;
458-
case IEQUICPARSEID:
459-
snprintf(errstr, len, "unable to parse QUIC connection IDs from initial packet");
460-
break;
461-
case IEQUICOPENSSLINIT:
462-
snprintf(errstr, len, "unable to initialize OpenSSL for QUIC");
463-
break;
464-
case IEQUICSEND:
465-
snprintf(errstr, len, "unable to send on QUIC stream");
466-
break;
467-
case IEQUICRECV:
468-
snprintf(errstr, len, "unable to receive on QUIC stream");
469-
break;
470-
case IEQUICEXPIRED:
471-
snprintf(errstr, len, "QUIC connection timeout has expired");
472-
break;
473449
case IENEWTIMER:
474450
snprintf(errstr, len, "unable to create new timer");
475451
perr = 1;
@@ -583,13 +559,36 @@ iperf_strerror(int int_errno)
583559
case IEMAXSERVERTESTDURATIONEXCEEDED:
584560
snprintf(errstr, len, "client's requested duration exceeds the server's maximum permitted limit");
585561
break;
562+
#if defined(HAVE_QUIC_NGTCP2)
586563
case IEQUICNONSUPPORTOPTIONS:
587564
snprintf(errstr, len, "using QUIC does not support Zero-copy or Skip-rx-copy options");
588565
break;
589566
case IEQUICBLOCKSIZE:
590567
snprintf(errstr, len, "QUIC block size invalid (maximum = %d bytes)", IPERF_QUIC_MAX_TX_PAYLOAD_SIZE);
591568
break;
592-
default:
569+
case IEQUICINIT:
570+
snprintf(errstr, len, "unable to initialize QUIC stream");
571+
break;
572+
case IEQUICCONNECTIONID:
573+
snprintf(errstr, len, "unable to set QUIC connection ID in call-back function");
574+
break;
575+
case IEQUICPARSEID:
576+
snprintf(errstr, len, "unable to parse QUIC connection IDs from initial packet");
577+
break;
578+
case IEQUICOPENSSLINIT:
579+
snprintf(errstr, len, "unable to initialize OpenSSL for QUIC");
580+
break;
581+
case IEQUICSEND:
582+
snprintf(errstr, len, "unable to send on QUIC stream");
583+
break;
584+
case IEQUICRECV:
585+
snprintf(errstr, len, "unable to receive on QUIC stream");
586+
break;
587+
case IEQUICEXPIRED:
588+
snprintf(errstr, len, "QUIC connection timeout has expired");
589+
break;
590+
#endif /* HAVE_QUIC_NGTCP2 */
591+
default:
593592
snprintf(errstr, len, "int_errno=%d", int_errno);
594593
perr = 1;
595594
break;

src/iperf_quic.c

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1359,4 +1359,37 @@ iperf_quic_init(struct iperf_test *test)
13591359
return 0;
13601360
}
13611361

1362+
1363+
/* iperf_quic_get_tcpinfo
1364+
*
1365+
* Retrieve TCP info from QUIC stream info
1366+
*/
1367+
void
1368+
iperf_quic_get_tcpinfo(struct iperf_stream *sp, struct tcp_info *tcpinfo)
1369+
{
1370+
ngtcp2_conn_info cinfo;
1371+
1372+
// Get QUIC connection info
1373+
memset(&cinfo, 0, sizeof(cinfo));
1374+
ngtcp2_conn_get_conn_info(sp->quic_conn_data.pconn, &cinfo);
1375+
1376+
// Map QUIC connection info to tcp_info structure
1377+
memset(tcpinfo, 0, sizeof(struct tcp_info));
1378+
tcpinfo->tcpi_rto = 0; // Retransmission timeout
1379+
tcpinfo->tcpi_snd_mss = 1; // Max send UDP payload size //TBD: set to 1 to allow get_snd_cwnd() to return the CWND value
1380+
tcpinfo->tcpi_rcv_mss = 0; // Max recv UDP payload size
1381+
tcpinfo->tcpi_snd_ssthresh = cinfo.ssthresh; // Slow start threshold
1382+
tcpinfo->tcpi_bytes_acked = cinfo.bytes_sent - cinfo.bytes_lost - cinfo.bytes_in_flight; // Bytes sent
1383+
tcpinfo->tcpi_bytes_received = cinfo.bytes_recv; // Bytes received
1384+
tcpinfo->tcpi_snd_cwnd = cinfo.cwnd; // Congestion window
1385+
tcpinfo->tcpi_rtt = (uint32_t)(cinfo.latest_rtt / 1000ull); // RTT in micro-sec
1386+
tcpinfo->tcpi_rttvar = (uint32_t)(cinfo.rttvar / 1000ull); // RTT variance in micro-sec
1387+
tcpinfo->tcpi_snd_wnd = 0; // Send window
1388+
tcpinfo->tcpi_total_retrans = cinfo.pkt_lost; // Packets lost
1389+
tcpinfo->tcpi_segs_in = cinfo.pkt_recv; // Packets received
1390+
tcpinfo->tcpi_segs_out = cinfo.pkt_sent; // Packets sent
1391+
1392+
return;
1393+
}
1394+
13621395
#endif /* HAVE_QUIC_NGTCP2 */

src/iperf_quic.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@
3636

3737
#define IPERF_QUIC_DEFAULT_MAX_IDLE_TIMEOUT 10000 // 10 seconds
3838

39-
#define IPERF_QUIC_MAX_TX_PAYLOAD_SIZE (1024 * 60) //TBD: should be Something else? (current value is from tests)
39+
#define IPERF_QUIC_MAX_TX_PAYLOAD_SIZE (1024 * 60) //TBD: should be Something else? (current value is based on tests)
4040

4141
#define IPERF_QUIC_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE NGTCP2_DEFAULT_MAX_RECV_UDP_PAYLOAD_SIZE //TBD: is this ok?
4242

@@ -64,6 +64,8 @@ int iperf_quic_connection_init(struct iperf_stream *sp);
6464

6565
void iperf_quic_delete_connection(struct iperf_quic_conn_data *quic_conn_data);
6666

67+
void iperf_quic_get_tcpinfo(struct iperf_stream *sp, struct tcp_info *tcpinfo);
68+
6769
#endif
6870

6971
#endif /* HAVE_QUIC_NGTCP2 */

src/tcp_info.c

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@
5555
#include "iperf.h"
5656
#include "iperf_api.h"
5757
#include "iperf_locale.h"
58+
#include "iperf_quic.h"
5859

5960
/*************************************************************/
6061
int
@@ -96,10 +97,19 @@ save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp)
9697
{
9798
#if (defined(linux) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)) && \
9899
defined(TCP_INFO)
100+
101+
#if defined(HAVE_QUIC_NGTCP2)
102+
if (sp->test->protocol->id == Pquic) {
103+
iperf_quic_get_tcpinfo(sp, &irp->tcpInfo);
104+
}
105+
else
106+
#endif /* HAVE_QUIC_NGTCP2 */
107+
{
99108
socklen_t tcp_info_length = sizeof(struct tcp_info);
100109

101110
if (getsockopt(sp->socket, IPPROTO_TCP, TCP_INFO, (void *)&irp->tcpInfo, &tcp_info_length) < 0)
102111
iperf_err(sp->test, "getsockopt - %s", strerror(errno));
112+
}
103113

104114
if (sp->test->debug) {
105115
printf("tcpi_snd_cwnd %u tcpi_snd_mss %u tcpi_rtt %u\n",

0 commit comments

Comments
 (0)