aboutsummaryrefslogtreecommitdiff
path: root/src/iperf_server_api.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/iperf_server_api.c')
-rw-r--r--src/iperf_server_api.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c
index 40d99bc..e2ddf7f 100644
--- a/src/iperf_server_api.c
+++ b/src/iperf_server_api.c
@@ -1,5 +1,5 @@
/*
- * iperf, Copyright (c) 2014-2018 The Regents of the University of
+ * iperf, Copyright (c) 2014-2020 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.
@@ -354,6 +354,15 @@ create_server_omit_timer(struct iperf_test * test)
static void
cleanup_server(struct iperf_test *test)
{
+ struct iperf_stream *sp;
+
+ /* Close open streams */
+ SLIST_FOREACH(sp, &test->streams, streams) {
+ FD_CLR(sp->socket, &test->read_set);
+ FD_CLR(sp->socket, &test->write_set);
+ close(sp->socket);
+ }
+
/* Close open test sockets */
if (test->ctrl_sck) {
close(test->ctrl_sck);
@@ -437,12 +446,20 @@ iperf_run_server(struct iperf_test *test)
while (test->state != IPERF_DONE) {
+ // Check if average transfer rate was exceeded (condition set in the callback routines)
+ if (test->bitrate_limit_exceeded) {
+ cleanup_server(test);
+ i_errno = IETOTALRATE;
+ return -1;
+ }
+
memcpy(&read_set, &test->read_set, sizeof(fd_set));
memcpy(&write_set, &test->write_set, sizeof(fd_set));
iperf_time_now(&now);
timeout = tmr_timeout(&now);
result = select(test->max_fd + 1, &read_set, &write_set, NULL, timeout);
+
if (result < 0 && errno != EINTR) {
cleanup_server(test);
i_errno = IESELECT;
@@ -596,6 +613,17 @@ iperf_run_server(struct iperf_test *test)
}
}
test->prot_listener = -1;
+
+ /* Ensure that total requested data rate is not above limit */
+ iperf_size_t total_requested_rate = test->num_streams * test->settings->rate * (test->mode == BIDIRECTIONAL? 2 : 1);
+ if (test->settings->bitrate_limit > 0 && total_requested_rate > test->settings->bitrate_limit) {
+ iperf_err(test, "Client total requested throughput rate of %" PRIu64 " bps exceeded %" PRIu64 " bps limit",
+ total_requested_rate, test->settings->bitrate_limit);
+ cleanup_server(test);
+ i_errno = IETOTALRATE;
+ return -1;
+ }
+
if (iperf_set_send_state(test, TEST_START) != 0) {
cleanup_server(test);
return -1;
@@ -647,7 +675,7 @@ iperf_run_server(struct iperf_test *test)
return -1;
}
}
- }
+ }
}
if (result == 0 ||