Fix retransmit accounting so it works right with the --omit flag.
This commit is contained in:
parent
8a7e01eb8f
commit
69376ec7ed
@ -30,12 +30,11 @@ struct iperf_interval_results
|
|||||||
int omitted;
|
int omitted;
|
||||||
#if defined(linux) || defined(__FreeBSD__)
|
#if defined(linux) || defined(__FreeBSD__)
|
||||||
struct tcp_info tcpInfo; /* getsockopt(TCP_INFO) for Linux and FreeBSD */
|
struct tcp_info tcpInfo; /* getsockopt(TCP_INFO) for Linux and FreeBSD */
|
||||||
int this_retrans;
|
|
||||||
#else
|
#else
|
||||||
/* Just placeholders, never accessed. */
|
/* Just placeholders, never accessed. */
|
||||||
char *tcpInfo;
|
char *tcpInfo;
|
||||||
int this_retrans;
|
|
||||||
#endif
|
#endif
|
||||||
|
int interval_retrans;
|
||||||
TAILQ_ENTRY(iperf_interval_results) irlistentries;
|
TAILQ_ENTRY(iperf_interval_results) irlistentries;
|
||||||
void *custom_data;
|
void *custom_data;
|
||||||
};
|
};
|
||||||
@ -46,7 +45,8 @@ struct iperf_stream_result
|
|||||||
iperf_size_t bytes_sent;
|
iperf_size_t bytes_sent;
|
||||||
iperf_size_t bytes_received_this_interval;
|
iperf_size_t bytes_received_this_interval;
|
||||||
iperf_size_t bytes_sent_this_interval;
|
iperf_size_t bytes_sent_this_interval;
|
||||||
int retransmits;
|
int stream_prev_total_retrans;
|
||||||
|
int stream_retrans;
|
||||||
struct timeval start_time;
|
struct timeval start_time;
|
||||||
struct timeval end_time;
|
struct timeval end_time;
|
||||||
TAILQ_HEAD(irlisthead, iperf_interval_results) interval_results;
|
TAILQ_HEAD(irlisthead, iperf_interval_results) interval_results;
|
||||||
|
@ -952,22 +952,6 @@ iperf_exchange_parameters(struct iperf_test *test)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*************************************************************/
|
|
||||||
|
|
||||||
int
|
|
||||||
iperf_sum_results(struct iperf_test *test)
|
|
||||||
{
|
|
||||||
struct iperf_stream *sp;
|
|
||||||
|
|
||||||
if (test->sender && test->sender_has_retransmits) {
|
|
||||||
SLIST_FOREACH(sp, &test->streams, streams) {
|
|
||||||
sp->result->retransmits = get_tcpinfo_total_retransmits(TAILQ_LAST(&sp->result->interval_results, irlisthead));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -1131,7 +1115,7 @@ send_results(struct iperf_test *test)
|
|||||||
} else {
|
} else {
|
||||||
cJSON_AddItemToArray(j_streams, j_stream);
|
cJSON_AddItemToArray(j_streams, j_stream);
|
||||||
bytes_transferred = test->sender ? sp->result->bytes_sent : sp->result->bytes_received;
|
bytes_transferred = test->sender ? sp->result->bytes_sent : sp->result->bytes_received;
|
||||||
retransmits = (test->sender && test->sender_has_retransmits) ? sp->result->retransmits : -1;
|
retransmits = (test->sender && test->sender_has_retransmits) ? sp->result->stream_retrans : -1;
|
||||||
cJSON_AddIntToObject(j_stream, "id", sp->id);
|
cJSON_AddIntToObject(j_stream, "id", sp->id);
|
||||||
cJSON_AddIntToObject(j_stream, "bytes", bytes_transferred);
|
cJSON_AddIntToObject(j_stream, "bytes", bytes_transferred);
|
||||||
cJSON_AddIntToObject(j_stream, "retransmits", retransmits);
|
cJSON_AddIntToObject(j_stream, "retransmits", retransmits);
|
||||||
@ -1231,7 +1215,7 @@ get_results(struct iperf_test *test)
|
|||||||
sp->result->bytes_received = bytes_transferred;
|
sp->result->bytes_received = bytes_transferred;
|
||||||
} else {
|
} else {
|
||||||
sp->result->bytes_sent = bytes_transferred;
|
sp->result->bytes_sent = bytes_transferred;
|
||||||
sp->result->retransmits = retransmits;
|
sp->result->stream_retrans = retransmits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1567,7 +1551,9 @@ iperf_reset_stats(struct iperf_test *test)
|
|||||||
rp = sp->result;
|
rp = sp->result;
|
||||||
rp->bytes_sent = rp->bytes_received = 0;
|
rp->bytes_sent = rp->bytes_received = 0;
|
||||||
rp->bytes_sent_this_interval = rp->bytes_received_this_interval = 0;
|
rp->bytes_sent_this_interval = rp->bytes_received_this_interval = 0;
|
||||||
rp->retransmits = 0;
|
if (test->sender && test->sender_has_retransmits)
|
||||||
|
rp->stream_prev_total_retrans = get_total_retransmits(sp->socket);
|
||||||
|
rp->stream_retrans = 0;
|
||||||
rp->start_time = now;
|
rp->start_time = now;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1588,7 +1574,6 @@ iperf_stats_callback(struct iperf_test *test)
|
|||||||
struct iperf_stream *sp;
|
struct iperf_stream *sp;
|
||||||
struct iperf_stream_result *rp = NULL;
|
struct iperf_stream_result *rp = NULL;
|
||||||
struct iperf_interval_results *irp, temp;
|
struct iperf_interval_results *irp, temp;
|
||||||
int prev_total_retransmits;
|
|
||||||
|
|
||||||
temp.omitted = test->omitting;
|
temp.omitted = test->omitting;
|
||||||
SLIST_FOREACH(sp, &test->streams, streams) {
|
SLIST_FOREACH(sp, &test->streams, streams) {
|
||||||
@ -1610,12 +1595,10 @@ iperf_stats_callback(struct iperf_test *test)
|
|||||||
if (test->protocol->id == Ptcp && has_tcpinfo()) {
|
if (test->protocol->id == Ptcp && has_tcpinfo()) {
|
||||||
save_tcpinfo(sp, &temp);
|
save_tcpinfo(sp, &temp);
|
||||||
if (test->sender && test->sender_has_retransmits) {
|
if (test->sender && test->sender_has_retransmits) {
|
||||||
irp = TAILQ_LAST(&rp->interval_results, irlisthead);
|
long total_retrans = get_total_retransmits(sp->socket);
|
||||||
if (irp == NULL)
|
temp.interval_retrans = total_retrans - rp->stream_prev_total_retrans;
|
||||||
prev_total_retransmits = 0;
|
rp->stream_retrans += temp.interval_retrans;
|
||||||
else
|
rp->stream_prev_total_retrans = total_retrans;
|
||||||
prev_total_retransmits = get_tcpinfo_total_retransmits(irp);
|
|
||||||
temp.this_retrans = get_tcpinfo_total_retransmits(&temp) - prev_total_retransmits;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
add_to_interval_list(rp, &temp);
|
add_to_interval_list(rp, &temp);
|
||||||
@ -1661,7 +1644,7 @@ iperf_print_intermediate(struct iperf_test *test)
|
|||||||
}
|
}
|
||||||
bytes += irp->bytes_transferred;
|
bytes += irp->bytes_transferred;
|
||||||
if (test->sender && test->sender_has_retransmits)
|
if (test->sender && test->sender_has_retransmits)
|
||||||
retransmits += irp->this_retrans;
|
retransmits += irp->interval_retrans;
|
||||||
}
|
}
|
||||||
if (bytes < 0) { /* this can happen if timer goes off just when client exits */
|
if (bytes < 0) { /* this can happen if timer goes off just when client exits */
|
||||||
iperf_err(test, "error: bytes < 0!");
|
iperf_err(test, "error: bytes < 0!");
|
||||||
@ -1748,7 +1731,7 @@ iperf_print_results(struct iperf_test *test)
|
|||||||
|
|
||||||
if (test->protocol->id == Ptcp) {
|
if (test->protocol->id == Ptcp) {
|
||||||
if (test->sender_has_retransmits)
|
if (test->sender_has_retransmits)
|
||||||
total_retransmits += sp->result->retransmits;
|
total_retransmits += sp->result->stream_retrans;
|
||||||
} else {
|
} else {
|
||||||
total_packets += (sp->packet_count - sp->omitted_packet_count);
|
total_packets += (sp->packet_count - sp->omitted_packet_count);
|
||||||
lost_packets += sp->cnt_error;
|
lost_packets += sp->cnt_error;
|
||||||
@ -1763,9 +1746,9 @@ iperf_print_results(struct iperf_test *test)
|
|||||||
fputs(" Sent\n", stdout);
|
fputs(" Sent\n", stdout);
|
||||||
if (test->sender_has_retransmits) {
|
if (test->sender_has_retransmits) {
|
||||||
if (test->json_output)
|
if (test->json_output)
|
||||||
cJSON_AddItemToObject(json_summary_stream, "sent", 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->retransmits));
|
cJSON_AddItemToObject(json_summary_stream, "sent", 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));
|
||||||
else
|
else
|
||||||
printf(report_bw_retrans_format, sp->socket, start_time, end_time, ubuf, nbuf, sp->result->retransmits, "");
|
printf(report_bw_retrans_format, sp->socket, start_time, end_time, ubuf, nbuf, sp->result->stream_retrans, "");
|
||||||
} else {
|
} else {
|
||||||
if (test->json_output)
|
if (test->json_output)
|
||||||
cJSON_AddItemToObject(json_summary_stream, "sent", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f", (int64_t) sp->socket, (double) start_time, (double) end_time, (double) end_time, (int64_t) bytes_sent, bandwidth * 8));
|
cJSON_AddItemToObject(json_summary_stream, "sent", iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f", (int64_t) sp->socket, (double) start_time, (double) end_time, (double) end_time, (int64_t) bytes_sent, bandwidth * 8));
|
||||||
@ -1919,9 +1902,9 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
|
|||||||
|
|
||||||
if (test->sender && test->sender_has_retransmits) {
|
if (test->sender && test->sender_has_retransmits) {
|
||||||
if (test->json_output)
|
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 omitted: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->this_retrans, 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 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, irp->omitted));
|
||||||
else
|
else
|
||||||
printf(report_bw_retrans_format, sp->socket, st, et, ubuf, nbuf, irp->this_retrans, irp->omitted?report_omitted:"");
|
printf(report_bw_retrans_format, sp->socket, st, et, ubuf, nbuf, irp->interval_retrans, irp->omitted?report_omitted:"");
|
||||||
} else {
|
} else {
|
||||||
if (test->json_output)
|
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 omitted: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, irp->omitted));
|
cJSON_AddItemToArray(json_interval_streams, iperf_json_printf("socket: %d start: %f end: %f seconds: %f bytes: %d bits_per_second: %f omitted: %b", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, irp->omitted));
|
||||||
|
@ -161,7 +161,7 @@ void iperf_free_stream(struct iperf_stream * sp);
|
|||||||
int has_tcpinfo(void);
|
int has_tcpinfo(void);
|
||||||
int has_tcpinfo_retransmits(void);
|
int has_tcpinfo_retransmits(void);
|
||||||
void save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp);
|
void save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp);
|
||||||
long get_tcpinfo_total_retransmits(struct iperf_interval_results *irp);
|
long get_total_retransmits(int socket);
|
||||||
void print_tcpinfo(struct iperf_test *test);
|
void print_tcpinfo(struct iperf_test *test);
|
||||||
void build_tcpinfo_message(struct iperf_interval_results *r, char *message);
|
void build_tcpinfo_message(struct iperf_interval_results *r, char *message);
|
||||||
|
|
||||||
@ -173,7 +173,6 @@ void sig_handler(int);
|
|||||||
void usage();
|
void usage();
|
||||||
void usage_long();
|
void usage_long();
|
||||||
void warning(char *);
|
void warning(char *);
|
||||||
int iperf_sum_results(struct iperf_test *);
|
|
||||||
int iperf_exchange_results(struct iperf_test *);
|
int iperf_exchange_results(struct iperf_test *);
|
||||||
int iperf_init_test(struct iperf_test *);
|
int iperf_init_test(struct iperf_test *);
|
||||||
int iperf_create_send_timers(struct iperf_test *);
|
int iperf_create_send_timers(struct iperf_test *);
|
||||||
|
@ -203,8 +203,6 @@ iperf_handle_message_client(struct iperf_test *test)
|
|||||||
case TEST_RUNNING:
|
case TEST_RUNNING:
|
||||||
break;
|
break;
|
||||||
case EXCHANGE_RESULTS:
|
case EXCHANGE_RESULTS:
|
||||||
if (iperf_sum_results(test) < 0)
|
|
||||||
return -1;
|
|
||||||
if (iperf_exchange_results(test) < 0)
|
if (iperf_exchange_results(test) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
@ -192,8 +192,6 @@ iperf_handle_message_server(struct iperf_test *test)
|
|||||||
}
|
}
|
||||||
if (iperf_set_send_state(test, EXCHANGE_RESULTS) != 0)
|
if (iperf_set_send_state(test, EXCHANGE_RESULTS) != 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (iperf_sum_results(test) < 0)
|
|
||||||
return -1;
|
|
||||||
if (iperf_exchange_results(test) < 0)
|
if (iperf_exchange_results(test) < 0)
|
||||||
return -1;
|
return -1;
|
||||||
if (iperf_set_send_state(test, DISPLAY_RESULTS) != 0)
|
if (iperf_set_send_state(test, DISPLAY_RESULTS) != 0)
|
||||||
|
@ -86,17 +86,28 @@ save_tcpinfo(struct iperf_stream *sp, struct iperf_interval_results *irp)
|
|||||||
|
|
||||||
/*************************************************************/
|
/*************************************************************/
|
||||||
long
|
long
|
||||||
get_tcpinfo_total_retransmits(struct iperf_interval_results *irp)
|
get_total_retransmits(int socket)
|
||||||
{
|
{
|
||||||
|
#if defined(linux) || defined(__FreeBSD__)
|
||||||
|
struct tcp_info ti;
|
||||||
|
socklen_t l = sizeof(ti);
|
||||||
|
|
||||||
|
if (getsockopt(socket, IPPROTO_TCP, TCP_INFO, (void *)&ti, &l) < 0)
|
||||||
|
return -1;
|
||||||
|
|
||||||
#if defined(linux) && defined(TCP_MD5SIG)
|
#if defined(linux) && defined(TCP_MD5SIG)
|
||||||
return irp->tcpInfo.tcpi_total_retrans;
|
return ti.tcpi_total_retrans;
|
||||||
#else
|
#else
|
||||||
#if defined(__FreeBSD__) && __FreeBSD_version >= 600000
|
#if defined(__FreeBSD__) && __FreeBSD_version >= 600000
|
||||||
return irp->tcpInfo.__tcpi_retransmits;
|
return ti.__tcpi_retransmits;
|
||||||
#else
|
#else
|
||||||
return -1;
|
return -1;
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#else
|
||||||
|
return -1;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef notdef
|
#ifdef notdef
|
||||||
|
Loading…
Reference in New Issue
Block a user