Handle retransmits correctly in reverse mode.
This commit is contained in:
parent
2c042fd469
commit
69bdbfd36d
@ -45,6 +45,7 @@ struct iperf_stream_result
|
||||
iperf_size_t bytes_sent;
|
||||
iperf_size_t bytes_received_this_interval;
|
||||
iperf_size_t bytes_sent_this_interval;
|
||||
int retransmits;
|
||||
struct timeval start_time;
|
||||
struct timeval end_time;
|
||||
TAILQ_HEAD(irlisthead, iperf_interval_results) interval_results;
|
||||
@ -126,6 +127,7 @@ struct iperf_test
|
||||
{
|
||||
char role; /* 'c' lient or 's' erver */
|
||||
int sender; /* client & !reverse or server & reverse */
|
||||
int sender_has_retransmits;
|
||||
struct protocol *protocol;
|
||||
char state;
|
||||
char *server_hostname; /* -c option */
|
||||
|
@ -619,6 +619,8 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
|
||||
}
|
||||
if (test->reverse)
|
||||
test->sender = ! test->sender;
|
||||
if (test->sender && test->protocol->id == Ptcp && has_tcpinfo_retransmits())
|
||||
test->sender_has_retransmits = 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -810,6 +812,21 @@ iperf_exchange_parameters(struct iperf_test *test)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
int
|
||||
iperf_sum_results(struct iperf_test *test)
|
||||
{
|
||||
struct iperf_stream *sp;
|
||||
|
||||
SLIST_FOREACH(sp, &test->streams, streams) {
|
||||
if (test->sender && test->sender_has_retransmits)
|
||||
sp->result->retransmits = get_tcpinfo_total_retransmits(TAILQ_LAST(&sp->result->interval_results, irlisthead));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/*************************************************************/
|
||||
|
||||
int
|
||||
@ -918,6 +935,8 @@ get_parameters(struct iperf_test *test)
|
||||
test->settings->rate = j_p->valueint;
|
||||
if ((j_p = cJSON_GetObjectItem(j, "TOS")) != NULL)
|
||||
test->settings->tos = j_p->valueint;
|
||||
if (test->sender && test->protocol->id == Ptcp && has_tcpinfo_retransmits())
|
||||
test->sender_has_retransmits = 1;
|
||||
cJSON_Delete(j);
|
||||
}
|
||||
return r;
|
||||
@ -933,7 +952,9 @@ send_results(struct iperf_test *test)
|
||||
cJSON *j_streams;
|
||||
struct iperf_stream *sp;
|
||||
cJSON *j_stream;
|
||||
int sender_has_retransmits;
|
||||
iperf_size_t bytes_transferred;
|
||||
int retransmits;
|
||||
|
||||
j = cJSON_CreateObject();
|
||||
if (j == NULL) {
|
||||
@ -941,6 +962,11 @@ send_results(struct iperf_test *test)
|
||||
r = -1;
|
||||
} else {
|
||||
cJSON_AddFloatToObject(j, "cpu_util", test->cpu_util);
|
||||
if ( ! test->sender )
|
||||
sender_has_retransmits = -1;
|
||||
else
|
||||
sender_has_retransmits = test->sender_has_retransmits;
|
||||
cJSON_AddIntToObject(j, "sender_has_retransmits", sender_has_retransmits);
|
||||
j_streams = cJSON_CreateArray();
|
||||
if (j_streams == NULL) {
|
||||
i_errno = IEPACKAGERESULTS;
|
||||
@ -955,8 +981,10 @@ send_results(struct iperf_test *test)
|
||||
} else {
|
||||
cJSON_AddItemToArray(j_streams, j_stream);
|
||||
bytes_transferred = test->sender ? sp->result->bytes_sent : sp->result->bytes_received;
|
||||
retransmits = (test->sender && test->sender_has_retransmits) ? sp->result->retransmits : -1;
|
||||
cJSON_AddIntToObject(j_stream, "id", sp->id);
|
||||
cJSON_AddIntToObject(j_stream, "bytes", bytes_transferred);
|
||||
cJSON_AddIntToObject(j_stream, "retransmits", retransmits);
|
||||
cJSON_AddFloatToObject(j_stream, "jitter", sp->jitter);
|
||||
cJSON_AddIntToObject(j_stream, "errors", sp->cnt_error);
|
||||
cJSON_AddIntToObject(j_stream, "packets", sp->packet_count);
|
||||
@ -980,17 +1008,21 @@ get_results(struct iperf_test *test)
|
||||
int r = 0;
|
||||
cJSON *j;
|
||||
cJSON *j_cpu_util;
|
||||
cJSON *j_sender_has_retransmits;
|
||||
int result_has_retransmits;
|
||||
cJSON *j_streams;
|
||||
int n, i;
|
||||
cJSON *j_stream;
|
||||
cJSON *j_id;
|
||||
cJSON *j_bytes;
|
||||
cJSON *j_retransmits;
|
||||
cJSON *j_jitter;
|
||||
cJSON *j_errors;
|
||||
cJSON *j_packets;
|
||||
int sid, cerror, pcount;
|
||||
double jitter;
|
||||
iperf_size_t bytes_transferred;
|
||||
int retransmits;
|
||||
struct iperf_stream *sp;
|
||||
|
||||
j = JSON_read(test->ctrl_sck);
|
||||
@ -999,11 +1031,15 @@ get_results(struct iperf_test *test)
|
||||
r = -1;
|
||||
} else {
|
||||
j_cpu_util = cJSON_GetObjectItem(j, "cpu_util");
|
||||
if (j_cpu_util == NULL) {
|
||||
j_sender_has_retransmits = cJSON_GetObjectItem(j, "sender_has_retransmits");
|
||||
if (j_cpu_util == NULL || j_sender_has_retransmits == NULL) {
|
||||
i_errno = IERECVRESULTS;
|
||||
r = -1;
|
||||
} else {
|
||||
test->remote_cpu_util = j_cpu_util->valuefloat;
|
||||
result_has_retransmits = j_sender_has_retransmits->valueint;
|
||||
if (! test->sender)
|
||||
test->sender_has_retransmits = result_has_retransmits;
|
||||
j_streams = cJSON_GetObjectItem(j, "streams");
|
||||
if (j_streams == NULL) {
|
||||
i_errno = IERECVRESULTS;
|
||||
@ -1018,15 +1054,17 @@ get_results(struct iperf_test *test)
|
||||
} else {
|
||||
j_id = cJSON_GetObjectItem(j_stream, "id");
|
||||
j_bytes = cJSON_GetObjectItem(j_stream, "bytes");
|
||||
j_retransmits = cJSON_GetObjectItem(j_stream, "retransmits");
|
||||
j_jitter = cJSON_GetObjectItem(j_stream, "jitter");
|
||||
j_errors = cJSON_GetObjectItem(j_stream, "errors");
|
||||
j_packets = cJSON_GetObjectItem(j_stream, "packets");
|
||||
if (j_id == NULL || j_bytes == NULL || j_jitter == NULL || j_errors == NULL || j_packets == NULL) {
|
||||
if (j_id == NULL || j_bytes == NULL || j_retransmits == NULL || j_jitter == NULL || j_errors == NULL || j_packets == NULL) {
|
||||
i_errno = IERECVRESULTS;
|
||||
r = -1;
|
||||
} else {
|
||||
sid = j_id->valueint;
|
||||
bytes_transferred = j_bytes->valueint;
|
||||
retransmits = j_retransmits->valueint;
|
||||
jitter = j_jitter->valuefloat;
|
||||
cerror = j_errors->valueint;
|
||||
pcount = j_packets->valueint;
|
||||
@ -1041,8 +1079,10 @@ get_results(struct iperf_test *test)
|
||||
sp->cnt_error = cerror;
|
||||
sp->packet_count = pcount;
|
||||
sp->result->bytes_received = bytes_transferred;
|
||||
} else
|
||||
} else {
|
||||
sp->result->bytes_sent = bytes_transferred;
|
||||
sp->result->retransmits = retransmits;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1313,6 +1353,7 @@ iperf_reset_test(struct iperf_test *test)
|
||||
|
||||
test->role = 's';
|
||||
test->sender = 0;
|
||||
test->sender_has_retransmits = 0;
|
||||
set_protocol(test, Ptcp);
|
||||
test->duration = DURATION;
|
||||
test->state = 0;
|
||||
@ -1374,7 +1415,7 @@ iperf_stats_callback(struct iperf_test *test)
|
||||
//temp.interval_duration = timeval_diff(&temp.interval_start_time, &temp.interval_end_time);
|
||||
if (test->protocol->id == Ptcp && has_tcpinfo()) {
|
||||
save_tcpinfo(sp, &temp);
|
||||
if (has_tcpinfo_retransmits()) {
|
||||
if (test->sender && test->sender_has_retransmits) {
|
||||
irp = TAILQ_LAST(&rp->interval_results, irlisthead);
|
||||
if (irp == NULL)
|
||||
prev_total_retransmits = 0;
|
||||
@ -1425,7 +1466,7 @@ iperf_print_intermediate(struct iperf_test *test)
|
||||
return;
|
||||
}
|
||||
bytes += irp->bytes_transferred;
|
||||
if (test->protocol->id == Ptcp && has_tcpinfo_retransmits())
|
||||
if (test->sender && test->sender_has_retransmits)
|
||||
retransmits += irp->this_retrans;
|
||||
}
|
||||
if (bytes < 0) { /* this can happen if timer goes off just when client exits */
|
||||
@ -1443,7 +1484,7 @@ iperf_print_intermediate(struct iperf_test *test)
|
||||
|
||||
start_time = timeval_diff(&sp->result->start_time,&irp->interval_start_time);
|
||||
end_time = timeval_diff(&sp->result->start_time,&irp->interval_end_time);
|
||||
if (test->protocol->id == Ptcp && has_tcpinfo_retransmits()) {
|
||||
if (test->sender && test->sender_has_retransmits) {
|
||||
if (test->json_output)
|
||||
cJSON_AddItemToObject(json_interval, "sum", iperf_json_printf("start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d", (double) start_time, (double) end_time, (double) irp->interval_duration, (int64_t) bytes, bandwidth * 8, (int64_t) retransmits));
|
||||
else
|
||||
@ -1463,7 +1504,7 @@ iperf_print_results(struct iperf_test *test)
|
||||
|
||||
cJSON *json_summary_streams = NULL;
|
||||
cJSON *json_summary_stream = NULL;
|
||||
long retransmits = 0, total_retransmits = 0;
|
||||
int total_retransmits = 0;
|
||||
int total_packets = 0, lost_packets = 0;
|
||||
char ubuf[UNIT_LEN];
|
||||
char nbuf[UNIT_LEN];
|
||||
@ -1484,7 +1525,7 @@ iperf_print_results(struct iperf_test *test)
|
||||
if (test->verbose)
|
||||
printf("Test Complete. Summary Results:\n");
|
||||
if (test->protocol->id == Ptcp)
|
||||
if (has_tcpinfo_retransmits())
|
||||
if (test->sender_has_retransmits)
|
||||
fputs(report_bw_retrans_header, stdout);
|
||||
else
|
||||
fputs(report_bw_header, stdout);
|
||||
@ -1510,10 +1551,8 @@ iperf_print_results(struct iperf_test *test)
|
||||
total_received += bytes_received;
|
||||
|
||||
if (test->protocol->id == Ptcp) {
|
||||
if (has_tcpinfo_retransmits()) {
|
||||
retransmits = get_tcpinfo_total_retransmits(TAILQ_LAST(&sp->result->interval_results, irlisthead));
|
||||
total_retransmits += retransmits;
|
||||
}
|
||||
if (test->sender_has_retransmits)
|
||||
total_retransmits += sp->result->retransmits;
|
||||
} else {
|
||||
total_packets += sp->packet_count;
|
||||
lost_packets += sp->cnt_error;
|
||||
@ -1527,11 +1566,11 @@ iperf_print_results(struct iperf_test *test)
|
||||
if (test->protocol->id == Ptcp) {
|
||||
if (!test->json_output)
|
||||
fputs(" Sent\n", stdout);
|
||||
if (has_tcpinfo_retransmits()) {
|
||||
if (test->sender_has_retransmits) {
|
||||
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) 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->retransmits));
|
||||
else
|
||||
printf(report_bw_retrans_format, sp->socket, start_time, end_time, ubuf, nbuf, retransmits);
|
||||
printf(report_bw_retrans_format, sp->socket, start_time, end_time, ubuf, nbuf, sp->result->retransmits);
|
||||
} else {
|
||||
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));
|
||||
@ -1573,7 +1612,7 @@ iperf_print_results(struct iperf_test *test)
|
||||
if (test->protocol->id == Ptcp) {
|
||||
if (!test->json_output)
|
||||
printf(" Total sent\n");
|
||||
if (has_tcpinfo_retransmits()) {
|
||||
if (test->sender_has_retransmits) {
|
||||
if (test->json_output)
|
||||
cJSON_AddItemToObject(test->json_end, "sum_sent", iperf_json_printf("start: %f end: %f seconds: %f bytes: %d bits_per_second: %f retransmits: %d", (double) start_time, (double) end_time, (double) end_time, (int64_t) total_sent, bandwidth * 8, (int64_t) total_retransmits));
|
||||
else
|
||||
@ -1658,7 +1697,7 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
|
||||
** else nothing.
|
||||
*/
|
||||
if (timeval_equals(&sp->result->start_time, &irp->interval_start_time))
|
||||
if (test->protocol->id == Ptcp && has_tcpinfo_retransmits())
|
||||
if (test->sender && test->sender_has_retransmits)
|
||||
fputs(report_bw_retrans_header, stdout);
|
||||
else
|
||||
fputs(report_bw_header, stdout);
|
||||
@ -1674,7 +1713,7 @@ print_interval_results(struct iperf_test *test, struct iperf_stream *sp, cJSON *
|
||||
st = timeval_diff(&sp->result->start_time, &irp->interval_start_time);
|
||||
et = timeval_diff(&sp->result->start_time, &irp->interval_end_time);
|
||||
|
||||
if (test->protocol->id == Ptcp && has_tcpinfo_retransmits()) {
|
||||
if (test->sender && test->sender_has_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", (int64_t) sp->socket, (double) st, (double) et, (double) irp->interval_duration, (int64_t) irp->bytes_transferred, bandwidth * 8, (int64_t) irp->this_retrans));
|
||||
else
|
||||
|
@ -169,6 +169,7 @@ void sig_handler(int);
|
||||
void usage();
|
||||
void usage_long();
|
||||
void warning(char *);
|
||||
int iperf_sum_results(struct iperf_test *);
|
||||
int iperf_exchange_results(struct iperf_test *);
|
||||
int iperf_init_test(struct iperf_test *);
|
||||
int iperf_parse_arguments(struct iperf_test *, int, char **);
|
||||
|
@ -87,6 +87,8 @@ iperf_handle_message_client(struct iperf_test *test)
|
||||
case TEST_RUNNING:
|
||||
break;
|
||||
case EXCHANGE_RESULTS:
|
||||
if (iperf_sum_results(test) < 0)
|
||||
return -1;
|
||||
if (iperf_exchange_results(test) < 0)
|
||||
return -1;
|
||||
break;
|
||||
|
@ -185,6 +185,8 @@ iperf_handle_message_server(struct iperf_test *test)
|
||||
i_errno = IESENDMESSAGE;
|
||||
return -1;
|
||||
}
|
||||
if (iperf_sum_results(test) < 0)
|
||||
return -1;
|
||||
if (iperf_exchange_results(test) < 0)
|
||||
return -1;
|
||||
test->state = DISPLAY_RESULTS;
|
||||
@ -260,6 +262,7 @@ iperf_test_reset(struct iperf_test *test)
|
||||
|
||||
test->reverse = 0;
|
||||
test->sender = 0;
|
||||
test->sender_has_retransmits = 0;
|
||||
test->no_delay = 0;
|
||||
|
||||
FD_ZERO(&test->read_set);
|
||||
|
Loading…
Reference in New Issue
Block a user