diff --git a/src/iperf.h b/src/iperf.h index 6b55559..b1ff1e8 100644 --- a/src/iperf.h +++ b/src/iperf.h @@ -77,6 +77,7 @@ struct iperf_interval_results int snd_cwnd; TAILQ_ENTRY(iperf_interval_results) irlistentries; void *custom_data; + int rtt; }; struct iperf_stream_result @@ -89,6 +90,8 @@ struct iperf_stream_result int stream_retrans; int stream_prev_total_sacks; int stream_sacks; + int stream_max_rtt; + int stream_max_snd_cwnd; struct timeval start_time; struct timeval end_time; TAILQ_HEAD(irlisthead, iperf_interval_results) interval_results; diff --git a/src/iperf_api.c b/src/iperf_api.c index d9b3983..b8f7891 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -2015,6 +2015,13 @@ iperf_stats_callback(struct iperf_test *test) rp->stream_prev_total_retrans = total_retrans; temp.snd_cwnd = get_snd_cwnd(&temp); + if (temp.snd_cwnd > rp->stream_max_snd_cwnd) { + rp->stream_max_snd_cwnd = temp.snd_cwnd; + } + temp.rtt = get_rtt(&temp); + if (temp.rtt > rp->stream_max_rtt) { + rp->stream_max_rtt = temp.rtt; + } } } } else { @@ -2211,7 +2218,7 @@ iperf_print_results(struct iperf_test *test) if (test->sender_has_retransmits) { /* Summary, TCP with retransmits. */ if (test->json_output) - cJSON_AddItemToObject(json_summary_stream, "sender", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d", (int64_t) sp->socket, (double) start_time, (double) end_time, (double) end_time, (int64_t) bytes_sent, bandwidth * 8, (int64_t) sp->result->stream_retrans)); + cJSON_AddItemToObject(json_summary_stream, "sender", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d max_snd_cwnd: %d max_rtt: %d", (int64_t) sp->socket, (double) start_time, (double) end_time, (double) end_time, (int64_t) bytes_sent, bandwidth * 8, (int64_t) sp->result->stream_retrans, (int64_t) sp->result->stream_max_snd_cwnd, (int64_t) sp->result->stream_max_rtt)); else iprintf(test, report_bw_retrans_format, sp->socket, start_time, end_time, ubuf, nbuf, sp->result->stream_retrans, report_sender); } else { @@ -2395,7 +2402,7 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON * if (test->sender && test->sender_has_retransmits) { /* Interval, TCP with retransmits. */ if (test->json_output) - cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d snd_cwnd: %d omitted: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->interval_retrans, (int64_t) irp->snd_cwnd, irp->omitted)); + cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d snd_cwnd: %d rtt: %d omitted: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->interval_retrans, (int64_t) irp->snd_cwnd, (int64_t) irp->rtt, irp->omitted)); else { unit_snprintf(cbuf, UNIT_LEN, irp->snd_cwnd, 'A'); iprintf(test, report_bw_retrans_cwnd_format, sp->socket, st, et, ubuf, nbuf, irp->interval_retrans, cbuf, irp->omitted?report_omitted:""); diff --git a/src/iperf_api.h b/src/iperf_api.h index 368f498..0fe85b8 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -197,6 +197,7 @@ int has_tcpinfo_retransmits(void); void save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp); long get_total_retransmits(struct iperf_interval_results *irp); long get_snd_cwnd(struct iperf_interval_results *irp); +long get_rtt(struct iperf_interval_results *irp); void print_tcpinfo(struct iperf_test *test); void build_tcpinfo_message(struct iperf_interval_results *r, char *message); diff --git a/src/tcp_info.c b/src/tcp_info.c index cd3154c..ebf44e9 100644 --- a/src/tcp_info.c +++ b/src/tcp_info.c @@ -100,8 +100,9 @@ save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp) iperf_err(sp->test, "getsockopt - %s", strerror(errno)); if (sp->test->debug) { - printf("tcpi_snd_cwnd %u tcpi_snd_mss %u\n", - irp->tcpInfo.tcpi_snd_cwnd, irp->tcpInfo.tcpi_snd_mss); + printf("tcpi_snd_cwnd %u tcpi_snd_mss %u tcpi_rtt %u\n", + irp->tcpInfo.tcpi_snd_cwnd, irp->tcpInfo.tcpi_snd_mss, + irp->tcpInfo.tcpi_rtt); } #endif @@ -140,6 +141,24 @@ get_snd_cwnd(struct iperf_interval_results *irp) #endif } +/*************************************************************/ +/* + * Return rtt in usec. + */ +long +get_rtt(struct iperf_interval_results *irp) +{ +#if defined(linux) && defined(TCP_MD5SIG) + return irp->tcpInfo.tcpi_rtt; +#else +#if defined(__FreeBSD__) && __FreeBSD_version >= 600000 + return irp->tcpInfo.tcpi_rtt; +#else + return -1; +#endif +#endif +} + /*************************************************************/ void build_tcpinfo_message(struct iperf_interval_results *r, char *message)