Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Time Flag For The Iperf Server Process #1684

Open
wants to merge 6 commits into
base: master
Choose a base branch
from
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 @@ -293,6 +293,7 @@ struct iperf_test
int server_port;
int omit; /* duration of omit period (-O flag) */
int duration; /* total duration of test (-t flag) */
int server_duration; /* maximum possible duration of test as enforced by the server (--server-time flag) */
char *diskfile_name; /* -F option */
int affinity, server_affinity; /* -A option */
#if defined(HAVE_CPUSET_SETAFFINITY)
Expand Down
18 changes: 14 additions & 4 deletions src/iperf_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -892,15 +892,15 @@ void
iperf_on_test_start(struct iperf_test *test)
{
if (test->json_output) {
cJSON_AddItemToObject(test->json_start, "test_start", iperf_json_printf("protocol: %s num_streams: %d blksize: %d omit: %d duration: %d bytes: %d blocks: %d reverse: %d tos: %d target_bitrate: %d bidir: %d fqrate: %d interval: %f", test->protocol->name, (int64_t) test->num_streams, (int64_t) test->settings->blksize, (int64_t) test->omit, (int64_t) test->duration, (int64_t) test->settings->bytes, (int64_t) test->settings->blocks, test->reverse?(int64_t)1:(int64_t)0, (int64_t) test->settings->tos, (int64_t) test->settings->rate, (int64_t) test->bidirectional, (uint64_t) test->settings->fqrate, test->stats_interval));
cJSON_AddItemToObject(test->json_start, "test_start", iperf_json_printf("protocol: %s num_streams: %d blksize: %d omit: %d duration: %d server_duration: %d bytes: %d blocks: %d reverse: %d tos: %d target_bitrate: %d bidir: %d fqrate: %d interval: %f", test->protocol->name, (int64_t) test->num_streams, (int64_t) test->settings->blksize, (int64_t) test->omit, (int64_t) test->duration, (int64_t) test->server_duration, (int64_t) test->settings->bytes, (int64_t) test->settings->blocks, test->reverse?(int64_t)1:(int64_t)0, (int64_t) test->settings->tos, (int64_t) test->settings->rate, (int64_t) test->bidirectional, (uint64_t) test->settings->fqrate, test->stats_interval));
} else {
if (test->verbose) {
if (test->settings->bytes)
iperf_printf(test, test_start_bytes, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->settings->bytes, test->settings->tos);
else if (test->settings->blocks)
iperf_printf(test, test_start_blocks, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->settings->blocks, test->settings->tos);
else
iperf_printf(test, test_start_time, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, test->duration, test->settings->tos);
iperf_printf(test, test_start_time, test->protocol->name, test->num_streams, test->settings->blksize, test->omit, (test->server_duration > 0 && test->duration > test->server_duration) ? test->server_duration : test->duration, test->settings->tos);
}
}
if (test->json_stream) {
Expand Down Expand Up @@ -1080,7 +1080,8 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
{"udp", no_argument, NULL, 'u'},
{"bitrate", required_argument, NULL, 'b'},
{"bandwidth", required_argument, NULL, 'b'},
{"server-bitrate-limit", required_argument, NULL, OPT_SERVER_BITRATE_LIMIT},
{"server-bitrate-limit", required_argument, NULL, OPT_SERVER_BITRATE_LIMIT},
{"server-time", required_argument, NULL, OPT_SERVER_TIME},
{"time", required_argument, NULL, 't'},
{"bytes", required_argument, NULL, 'n'},
{"blockcount", required_argument, NULL, 'k'},
Expand Down Expand Up @@ -1164,7 +1165,7 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
int rcv_timeout_in = 0;

blksize = 0;
server_flag = client_flag = rate_flag = duration_flag = rcv_timeout_flag = snd_timeout_flag =0;
server_flag = client_flag = rate_flag = duration_flag = rcv_timeout_flag = snd_timeout_flag = 0;
#if defined(HAVE_SSL)
char *client_username = NULL, *client_rsa_public_key = NULL, *server_rsa_private_key = NULL;
FILE *ptr_file;
Expand Down Expand Up @@ -1312,6 +1313,14 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
test->settings->bitrate_limit = unit_atof_rate(optarg);
server_flag = 1;
break;
case OPT_SERVER_TIME:
test->server_duration = atoi(optarg);
if (test->server_duration > MAX_TIME || test->server_duration < 0) {
i_errno = IEDURATION;
return -1;
}
server_flag = 1;
break;
case 't':
test->duration = atoi(optarg);
if (test->duration > MAX_TIME || test->duration < 0) {
Expand Down Expand Up @@ -2929,6 +2938,7 @@ iperf_defaults(struct iperf_test *testp)

testp->omit = OMIT;
testp->duration = DURATION;
testp->server_duration = 0;
testp->diskfile_name = (char*) 0;
testp->affinity = -1;
testp->server_affinity = -1;
Expand Down
3 changes: 3 additions & 0 deletions src/iperf_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ typedef atomic_uint_fast64_t atomic_iperf_size_t;
#define OPT_JSON_STREAM 28
#define OPT_SND_TIMEOUT 29
#define OPT_USE_PKCS1_PADDING 30
#define OPT_SERVER_TIME 31

/* states */
#define TEST_START 1
Expand Down Expand Up @@ -475,6 +476,8 @@ enum {
IEPTHREADJOIN=152, // Unable to join thread (check perror)
IEPTHREADATTRINIT=153, // Unable to initialize thread attribute (check perror)
IEPTHREADATTRDESTROY=154, // Unable to destroy thread attribute (check perror)
IESENDSERVERDURATION=155, // Unable to send the server's maximum measurement duration
IERECVSERVERDURATION=156, // Unable to receive the server's maximum measurement duration
/* Stream errors */
IECREATESTREAM = 200, // Unable to create a new stream (check herror/perror)
IEINITSTREAM = 201, // Unable to initialize stream (check herror/perror)
Expand Down
32 changes: 28 additions & 4 deletions src/iperf_client_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -203,14 +203,26 @@ create_client_timers(struct iperf_test * test)
}
cd.p = test;
test->timer = test->stats_timer = test->reporter_timer = NULL;
if (test->duration != 0) {
test->done = 0;
test->timer = tmr_create(&now, test_timer_proc, cd, ( test->duration + test->omit ) * SEC_TO_US, 0);

int duration = test->duration;
if (duration != 0) {
/**
* The duration of the measurement should only be overridden if it exceeds the duration set by the server or
* if no duration is set on the server.
*
*/
if (test->server_duration > 0 && test->server_duration < duration) {
duration = test->server_duration;
}

test->done = 0;
test->timer = tmr_create(&now, test_timer_proc, cd, (duration + test->omit) * SEC_TO_US, 0);
if (test->timer == NULL) {
i_errno = IEINITTEST;
return -1;
}
}
}

if (test->stats_interval != 0) {
test->stats_timer = tmr_create(&now, client_stats_timer_proc, cd, test->stats_interval * SEC_TO_US, 1);
if (test->stats_timer == NULL) {
Expand Down Expand Up @@ -426,6 +438,18 @@ iperf_connect(struct iperf_test *test)
return -1;
}

/**
* If the server has a value set for the --server-time flag, the client will read it here and adjust its measurement time accordingly.
* If the value is 0, then the measurement will run for the duration that the client has set.
*/
char server_duration_str[15] = "";
if (Nread(test->ctrl_sck, server_duration_str, sizeof(server_duration_str), Ptcp) != sizeof(server_duration_str))
{
i_errno = IERECVSERVERDURATION;
return -1;
}
test->server_duration = atoi(server_duration_str);

FD_SET(test->ctrl_sck, &test->read_set);
if (test->ctrl_sck > test->max_fd) test->max_fd = test->ctrl_sck;

Expand Down
2 changes: 2 additions & 0 deletions src/iperf_locale.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,8 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
" --time-skew-threshold time skew threshold (in seconds) between the server\n"
" and client during the authentication process\n"
" --use-pkcs1-padding use pkcs1 padding at your own risk\n"
" --server-time time in seconds to transmit for. selected when \n"
" value is less than client's duration.\n"
#endif //HAVE_SSL
"Client specific:\n"
" -c, --client <host>[%%<dev>] run in client mode, connecting to <host>\n"
Expand Down
34 changes: 30 additions & 4 deletions src/iperf_server_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -175,8 +175,23 @@ iperf_accept(struct iperf_test *test)
i_errno = IERECVCOOKIE;
goto error_handling;
}
FD_SET(test->ctrl_sck, &test->read_set);
if (test->ctrl_sck > test->max_fd) test->max_fd = test->ctrl_sck;

/**
* If the server has a value set for the --server-time flag, send it to the client
* so that it can adjust its measurement time accordingly. If the value was not set
* via the flag, then the client will see a value of 0, which means that the server
* does not have a maximum measurement time.
*/
char server_duration_str[15] = "";
sprintf(server_duration_str, "%d", test->server_duration);

if (Nwrite(test->ctrl_sck, server_duration_str, sizeof(server_duration_str), Ptcp) < 0) {
i_errno = IESENDSERVERDURATION;
goto error_handling;
}

FD_SET(test->ctrl_sck, &test->read_set);
if (test->ctrl_sck > test->max_fd) test->max_fd = test->ctrl_sck;

if (iperf_set_send_state(test, PARAM_EXCHANGE) != 0)
goto error_handling;
Expand Down Expand Up @@ -340,9 +355,20 @@ create_server_timers(struct iperf_test * test)
}
cd.p = test;
test->timer = test->stats_timer = test->reporter_timer = NULL;
if (test->duration != 0 ) {

int duration = test->duration;
if (duration != 0 ) {
/**
* The duration of the measurement should only be overridden if it exceeds the duration set by the server or
* if no duration is set on the server.
*
*/
if (test->server_duration > 0 && test->server_duration < duration) {
duration = test->server_duration;
}

test->done = 0;
test->timer = tmr_create(&now, server_timer_proc, cd, (test->duration + test->omit + grace_period) * SEC_TO_US, 0);
test->timer = tmr_create(&now, server_timer_proc, cd, (duration + test->omit + grace_period) * SEC_TO_US, 0);
if (test->timer == NULL) {
i_errno = IEINITTEST;
return -1;
Expand Down
Loading