1
1
First, realize that we've been setting the congestion control (CC)
algorithm unnecessarily; rather than doing it for all listening or
connecting sockets, do it just for those sockets that are being used
for TCP test streams.

Record the CC algorithm in use (this handles the case where a CC algorithm
hasn't been specified), and have the client and server exchange this
information.

Report the CC algorithms that were used (note that it's theoretically
possible for the two ends of the test to be using different algorithms,
if no algorithm was explicitly specified and the two end hosts have
different defaults, or if one side allows setting the CC algorithm and
the other doesn't).

Committing to a branch to make it easier to test this code on a
wider combination of systems.
Этот коммит содержится в:
Bruce A. Mah 2016-09-22 13:34:52 -07:00
родитель 353615b772
Коммит 7eeaa1cb07
5 изменённых файлов: 99 добавлений и 23 удалений

Просмотреть файл

@ -220,6 +220,8 @@ struct iperf_test
#endif /* HAVE_CPUSET_SETAFFINITY */
char *title; /* -T option */
char *congestion; /* -C option */
char *congestion_used; /* what was actually used */
char *remote_congestion_used; /* what the other side used */
char *pidfile; /* -P option */
char *logfile; /* --logfile option */

Просмотреть файл

@ -1334,6 +1334,8 @@ send_parameters(struct iperf_test *test)
cJSON_AddStringToObject(j, "title", test->title);
if (test->congestion)
cJSON_AddStringToObject(j, "congestion", test->congestion);
if (test->congestion_used)
cJSON_AddStringToObject(j, "congestion_used", test->congestion_used);
if (test->get_server_output)
cJSON_AddNumberToObject(j, "get_server_output", iperf_get_test_get_server_output(test));
if (test->udp_counters_64bit)
@ -1414,6 +1416,8 @@ get_parameters(struct iperf_test *test)
test->title = strdup(j_p->valuestring);
if ((j_p = cJSON_GetObjectItem(j, "congestion")) != NULL)
test->congestion = strdup(j_p->valuestring);
if ((j_p = cJSON_GetObjectItem(j, "congestion_used")) != NULL)
test->congestion_used = strdup(j_p->valuestring);
if ((j_p = cJSON_GetObjectItem(j, "get_server_output")) != NULL)
iperf_set_test_get_server_output(test, 1);
if ((j_p = cJSON_GetObjectItem(j, "udp_counters_64bit")) != NULL)
@ -1455,6 +1459,9 @@ send_results(struct iperf_test *test)
else
sender_has_retransmits = test->sender_has_retransmits;
cJSON_AddNumberToObject(j, "sender_has_retransmits", sender_has_retransmits);
if ( test->congestion_used ) {
cJSON_AddStringToObject(j, "congestion_used", test->congestion_used);
}
/* If on the server and sending server output, then do this */
if (test->role == 's' && test->get_server_output) {
@ -1529,6 +1536,7 @@ get_results(struct iperf_test *test)
cJSON *j_cpu_util_total;
cJSON *j_cpu_util_user;
cJSON *j_cpu_util_system;
cJSON *j_remote_congestion_used;
cJSON *j_sender_has_retransmits;
int result_has_retransmits;
cJSON *j_streams;
@ -1637,6 +1645,12 @@ get_results(struct iperf_test *test)
}
}
}
j_remote_congestion_used = cJSON_GetObjectItem(j, "congestion_used");
if (j_remote_congestion_used != NULL) {
test->remote_congestion_used = strdup(j_remote_congestion_used->valuestring);
}
cJSON_Delete(j);
}
return r;
@ -1833,6 +1847,8 @@ iperf_defaults(struct iperf_test *testp)
#endif /* HAVE_CPUSET_SETAFFINITY */
testp->title = NULL;
testp->congestion = NULL;
testp->congestion_used = NULL;
testp->remote_congestion_used = NULL;
testp->server_port = PORT;
testp->ctrl_sck = -1;
testp->prot_listener = -1;
@ -1965,6 +1981,10 @@ iperf_free_test(struct iperf_test *test)
free(test->title);
if (test->congestion)
free(test->congestion);
if (test->congestion_used)
free(test->congestion_used);
if (test->remote_congestion_used)
free(test->remote_congestion_used);
if (test->omit_timer != NULL)
tmr_cancel(test->omit_timer);
if (test->timer != NULL)
@ -2500,11 +2520,24 @@ iperf_print_results(struct iperf_test *test)
}
}
if (test->json_output)
if (test->json_output) {
cJSON_AddItemToObject(test->json_end, "cpu_utilization_percent", iperf_json_printf("host_total: %f host_user: %f host_system: %f remote_total: %f remote_user: %f remote_system: %f", (double) test->cpu_util[0], (double) test->cpu_util[1], (double) test->cpu_util[2], (double) test->remote_cpu_util[0], (double) test->remote_cpu_util[1], (double) test->remote_cpu_util[2]));
if (test->congestion_used) {
cJSON_AddStringToObject(test->json_end, "local_tcp_congestion", test->congestion_used);
}
if (test->remote_congestion_used) {
cJSON_AddStringToObject(test->json_end, "remote_tcp_congestion", test->remote_congestion_used);
}
}
else {
if (test->verbose) {
iprintf(test, report_cpu, report_local, test->sender?report_sender:report_receiver, test->cpu_util[0], test->cpu_util[1], test->cpu_util[2], report_remote, test->sender?report_receiver:report_sender, test->remote_cpu_util[0], test->remote_cpu_util[1], test->remote_cpu_util[2]);
if (test->congestion_used) {
iprintf(test, "local_tcp_congestion %s\n", test->congestion_used);
}
if (test->remote_congestion_used) {
iprintf(test, "remote_tcp_congestion %s\n", test->remote_congestion_used);
}
}
/* Print server output if we're on the client and it was requested/provided */

Просмотреть файл

@ -1,5 +1,5 @@
/*
* iperf, Copyright (c) 2014, 2015, The Regents of the University of
* iperf, Copyright (c) 2014, 2015, 2016, The Regents of the University of
* California, through Lawrence Berkeley National Laboratory (subject
* to receipt of any required approvals from the U.S. Dept. of
* Energy). All rights reserved.
@ -43,6 +43,11 @@
#include "net.h"
#include "timer.h"
#if defined(HAVE_TCP_CONGESTION)
#if !defined(TCP_CA_NAME_MAX)
#define TCP_CA_NAME_MAX 16
#endif /* TCP_CA_NAME_MAX */
#endif /* HAVE_TCP_CONGESTION */
int
iperf_create_streams(struct iperf_test *test)
@ -59,6 +64,31 @@ iperf_create_streams(struct iperf_test *test)
if ((s = test->protocol->connect(test)) < 0)
return -1;
#if defined(HAVE_TCP_CONGESTION)
if (test->protocol->id == Ptcp) {
if (test->congestion) {
if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) {
close(s);
i_errno = IESETCONGESTION;
return -1;
}
}
{
int len = TCP_CA_NAME_MAX;
char ca[TCP_CA_NAME_MAX + 1];
if (getsockopt(s, IPPROTO_TCP, TCP_CONGESTION, ca, &len) < 0) {
close(s);
i_errno = IESETCONGESTION;
return -1;
}
test->congestion_used = strdup(ca);
if (test->debug) {
printf("Congestion algorithm is %s\n", test->congestion_used);
}
}
}
#endif /* HAVE_TCP_CONGESTION */
if (test->sender)
FD_SET(s, &test->write_set);
else

Просмотреть файл

@ -62,6 +62,11 @@
#include "iperf_util.h"
#include "iperf_locale.h"
#if defined(HAVE_TCP_CONGESTION)
#if !defined(TCP_CA_NAME_MAX)
#define TCP_CA_NAME_MAX 16
#endif /* TCP_CA_NAME_MAX */
#endif /* HAVE_TCP_CONGESTION */
int
iperf_server_listen(struct iperf_test *test)
@ -510,6 +515,33 @@ iperf_run_server(struct iperf_test *test)
return -1;
}
#if defined(HAVE_TCP_CONGESTION)
if (test->protocol->id == Ptcp) {
if (test->congestion) {
if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) {
close(s);
cleanup_server(test);
i_errno = IESETCONGESTION;
return -1;
}
}
{
int len = TCP_CA_NAME_MAX;
char ca[TCP_CA_NAME_MAX + 1];
if (getsockopt(s, IPPROTO_TCP, TCP_CONGESTION, ca, &len) < 0) {
close(s);
cleanup_server(test);
i_errno = IESETCONGESTION;
return -1;
}
test->congestion_used = strdup(ca);
if (test->debug) {
printf("Congestion algorithm is %s\n", test->congestion_used);
}
}
}
#endif /* HAVE_TCP_CONGESTION */
if (!is_closed(s)) {
sp = iperf_new_stream(test, s);
if (!sp) {

Просмотреть файл

@ -235,16 +235,6 @@ iperf_tcp_listen(struct iperf_test *test)
}
printf("SO_SNDBUF is %u\n", opt);
}
#if defined(HAVE_TCP_CONGESTION)
if (test->congestion) {
if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) {
close(s);
freeaddrinfo(res);
i_errno = IESETCONGESTION;
return -1;
}
}
#endif /* HAVE_TCP_CONGESTION */
#if defined(HAVE_SO_MAX_PACING_RATE)
/* If socket pacing is available and not disabled, try it. */
if (! test->no_fq_socket_pacing) {
@ -473,17 +463,6 @@ iperf_tcp_connect(struct iperf_test *test)
}
#endif /* HAVE_FLOWLABEL */
#if defined(HAVE_TCP_CONGESTION)
if (test->congestion) {
if (setsockopt(s, IPPROTO_TCP, TCP_CONGESTION, test->congestion, strlen(test->congestion)) < 0) {
close(s);
freeaddrinfo(server_res);
i_errno = IESETCONGESTION;
return -1;
}
}
#endif /* HAVE_TCP_CONGESTION */
#if defined(HAVE_SO_MAX_PACING_RATE)
/* If socket pacing is available and not disabled, try it. */
if (! test->no_fq_socket_pacing) {