Retrieve RTT information on platforms supporting it.
This value is available on the sender side, expressed in microseconds. It's available in the JSON output. In the JSON output we also output the maximum observed RTT per-stream. Note that since the observation interval is many times the RTT, it's not clear how good this value would be at capturing the largest computed RTT value over the lifetime of each stream. While here, also determine the maximum observed snd_cwnd value over the lifetime of each stream. This all works pretty well on Linux, but on FreeBSD (which should theoretically be supported) we don't do a good job of supporting the tcp_info structure. We need to make this code a lot more portable, rather than just assuming the world of platforms is "Linux" vs. "everything else". Fixing this requires some rearchitecting of the way that we retrieve, compute, and print statistics. Part of a fix for #215.
Этот коммит содержится в:
родитель
8634b34804
Коммит
432ef7ebb3
@ -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;
|
||||
|
@ -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:"");
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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)
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user