Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/iperf.h
Original file line number Diff line number Diff line change
Expand Up @@ -318,6 +318,7 @@ struct iperf_test
char *title; /* -T option */
char *extra_data; /* --extra-data */
char *congestion; /* -C option */
char *congestion_server; /* -C option - used only in the client side to pass the `congestion` value to the server */
char *congestion_used; /* what was actually used */
char *remote_congestion_used; /* what the other side used */
char *pidfile; /* -P option */
Expand Down
57 changes: 48 additions & 9 deletions src/iperf_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,12 @@ iperf_get_test_congestion_control(struct iperf_test* ipt)
return ipt->congestion;
}

char*
iperf_get_test_congestion_control_server(struct iperf_test* ipt)
{
return ipt->congestion_server;
}

int
iperf_get_test_mss(struct iperf_test *ipt)
{
Expand Down Expand Up @@ -848,6 +854,12 @@ iperf_set_test_congestion_control(struct iperf_test* ipt, char* cc)
ipt->congestion = strdup(cc);
}

void
iperf_set_test_congestion_server_control_server(struct iperf_test* ipt, char* cc)
{
ipt->congestion_server = strdup(cc);
}

void
iperf_set_test_mss(struct iperf_test *ipt, int mss)
{
Expand Down Expand Up @@ -1128,10 +1140,8 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
{"affinity", required_argument, NULL, 'A'},
#endif /* HAVE_CPU_AFFINITY */
{"title", required_argument, NULL, 'T'},
#if defined(HAVE_TCP_CONGESTION)
{"congestion", required_argument, NULL, 'C'},
{"linux-congestion", required_argument, NULL, 'C'},
#endif /* HAVE_TCP_CONGESTION */
#if defined(HAVE_SCTP_H)
{"sctp", no_argument, NULL, OPT_SCTP},
{"nstreams", required_argument, NULL, OPT_NUMSTREAMS},
Expand Down Expand Up @@ -1613,13 +1623,30 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
client_flag = 1;
break;
case 'C':
#if defined(HAVE_TCP_CONGESTION)
test->congestion = strdup(optarg);
if (optarg) {
slash = strchr(optarg, '/');
if (slash) {
*slash = '\0';
++slash;
if (strlen(slash) > 0) {
test->congestion_server = strdup(slash);
}
}
if (strlen(optarg) > 0) {
test->congestion = strdup(optarg);
if (!test->congestion_server) {
test->congestion_server = strdup(test->congestion);
}
}
}
client_flag = 1;
#else /* HAVE_TCP_CONGESTION */
i_errno = IEUNIMP;
return -1;
#ifndef HAVE_TCP_CONGESTION
if (test->congestion) { // Client does not support congestion control, so should not be set for the client
i_errno = IECONGESTIONSUPPORT;
return -1;
}
#endif /* HAVE_TCP_CONGESTION */

break;
case 'd':
test->debug = 1;
Expand Down Expand Up @@ -1885,6 +1912,14 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
return -1;
}

// Warning if congestion control algorithm was set to non-sending client or server
if (test->congestion != NULL && test->mode == RECEIVER) {
warning("Congestion control algorithm was set to non-sending client");
}
if (test->congestion == NULL && test->congestion_server != NULL && test->mode == SENDER) {
warning("Congestion control algorithm was set to non-sending server");
}

/* Set Total-rate average interval to multiplicity of State interval */
if (test->settings->bitrate_limit_interval != 0) {
test->settings->bitrate_limit_stats_per_interval =
Expand Down Expand Up @@ -2373,8 +2408,8 @@ send_parameters(struct iperf_test *test)
cJSON_AddStringToObject(j, "title", test->title);
if (test->extra_data)
cJSON_AddStringToObject(j, "extra_data", test->extra_data);
if (test->congestion)
cJSON_AddStringToObject(j, "congestion", test->congestion);
if (test->congestion_server)
cJSON_AddStringToObject(j, "congestion", test->congestion_server);
if (test->congestion_used)
cJSON_AddStringToObject(j, "congestion_used", test->congestion_used);
if (test->get_server_output)
Expand Down Expand Up @@ -3280,6 +3315,8 @@ iperf_free_test(struct iperf_test *test)
free(test->extra_data);
if (test->congestion)
free(test->congestion);
if (test->congestion_server)
free(test->congestion_server);
if (test->congestion_used)
free(test->congestion_used);
if (test->remote_congestion_used)
Expand Down Expand Up @@ -3395,6 +3432,8 @@ iperf_reset_test(struct iperf_test *test)

if (test->congestion)
free(test->congestion);
if (test->congestion_server)
free(test->congestion_server);
test->congestion = NULL;
if (test->remote_congestion_used)
free(test->remote_congestion_used);
Expand Down
3 changes: 3 additions & 0 deletions src/iperf_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ int iperf_get_test_no_delay( struct iperf_test* ipt );
int iperf_get_test_connect_timeout( struct iperf_test* ipt );
int iperf_get_dont_fragment( struct iperf_test* ipt );
char* iperf_get_test_congestion_control(struct iperf_test* ipt);
char* iperf_get_test_congestion_control_server(struct iperf_test* ipt);
int iperf_get_test_mss(struct iperf_test* ipt);
int iperf_get_mapped_v4(struct iperf_test* ipt);

Expand Down Expand Up @@ -215,6 +216,7 @@ void iperf_set_test_bidirectional( struct iperf_test* ipt, int bidirectional)
void iperf_set_test_no_delay( struct iperf_test* ipt, int no_delay);
void iperf_set_dont_fragment( struct iperf_test* ipt, int dont_fragment );
void iperf_set_test_congestion_control(struct iperf_test* ipt, char* cc);
void iperf_set_test_congestion_control_server(struct iperf_test* ipt, char* cc);
void iperf_set_test_mss(struct iperf_test* ipt, int mss);
void iperf_set_mapped_v4(struct iperf_test* ipt, const int val);
void iperf_set_on_new_stream_callback(struct iperf_test* ipt, void (*callback)(struct iperf_stream *));
Expand Down Expand Up @@ -495,6 +497,7 @@ enum {
IESETCNTLKAINTERVAL = 157, // Unable to set/get socket keepalive TCP retry interval (TCP_KEEPINTVL) option
IESETCNTLKACOUNT = 158, // Unable to set/get socket keepalive TCP number of retries (TCP_KEEPCNT) option
IEPTHREADSIGMASK=159, // Unable to initialize sub thread signal mask (check perror)
IECONGESTIONSUPPORT = 160, // Client does not support setting TCP congestion control algorithm
/* Stream errors */
IECREATESTREAM = 200, // Unable to create a new stream (check herror/perror)
IEINITSTREAM = 201, // Unable to initialize stream (check herror/perror)
Expand Down
3 changes: 3 additions & 0 deletions src/iperf_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -449,6 +449,9 @@ iperf_strerror(int int_errno)
snprintf(errstr, len, "unable to update timer");
perr = 1;
break;
case IECONGESTIONSUPPORT:
snprintf(errstr, len, "Client does not support setting TCP congestion control algorithm");
break;
case IESETCONGESTION:
snprintf(errstr, len, "unable to set TCP_CONGESTION: "
"Supplied congestion control algorithm not supported on this host");
Expand Down
5 changes: 4 additions & 1 deletion src/iperf_locale.c
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,10 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
" (indirectly sets TCP window size)\n"

#if defined(HAVE_TCP_CONGESTION)
" -C, --congestion <algo> set TCP congestion control algorithm (Linux and FreeBSD only)\n"
" -C, --congestion <algo>[/<server_algo>] set TCP congestion control algorithm (Linux and FreeBSD only)\n"
" <algo> for client & server, optional <algo_server> for the server\n"
#else /* HAVE_TCP_CONGESTION */
" -C, --congestion /<server_algo> set server TCP congestion control algorithm\n"
#endif /* HAVE_TCP_CONGESTION */
" -M, --set-mss # set TCP/SCTP maximum segment size (MTU - 40 bytes)\n"
" -N, --no-delay set TCP/SCTP no delay, disabling Nagle's Algorithm\n"
Expand Down
2 changes: 1 addition & 1 deletion src/iperf_server_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -533,7 +533,7 @@ iperf_run_server(struct iperf_test *test)
int result, s;
int send_streams_accepted, rec_streams_accepted;
int streams_to_send = 0, streams_to_rec = 0;
#if defined(HAVE_TCP_CONGESTION)
#if defined(HAVE_TCP_CONGESTION) || defined(HAVE_TCP_USER_TIMEOUT)
int saved_errno;
#endif /* HAVE_TCP_CONGESTION */
fd_set read_set, write_set;
Expand Down