Skip to content

Commit

Permalink
Rebase changes to get formal version of the state change debug messages
Browse files Browse the repository at this point in the history
  • Loading branch information
davidBar-On committed Sep 13, 2024
1 parent d5713db commit e5364f9
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 33 deletions.
37 changes: 34 additions & 3 deletions src/iperf_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1706,9 +1706,6 @@ iperf_parse_arguments(struct iperf_test *test, int argc, char **argv)
} else if (test->role == 'c' && (test->server_skew_threshold != 0)){
i_errno = IESERVERONLY;
return -1;
} else if (test->role == 'c' && rcv_timeout_flag && test->mode == SENDER){
i_errno = IERVRSONLYRCVTIMEOUT;
return -1;
} else if (test->role == 's' && (server_rsa_private_key || test->server_authorized_users) &&
!(server_rsa_private_key && test->server_authorized_users)) {
i_errno = IESETSERVERAUTH;
Expand Down Expand Up @@ -2142,6 +2139,40 @@ iperf_create_send_timers(struct iperf_test * test)
return 0;
}

/* cancel send (pacing) timers */
void
iperf_cancel_send_timers(struct iperf_test * test)
{
struct iperf_stream *sp;

SLIST_FOREACH(sp, &test->streams, streams) {
if (sp->send_timer != NULL) {
tmr_cancel(sp->send_timer);
sp->send_timer = NULL;
}
}
}

/* cancel all periodic timers */
void
iperf_cancel_periodic_timers(struct iperf_test * test)
{
if (test->debug_level >= DEBUG_LEVEL_INFO) {
iperf_printf(test, "Canceling all periodic timers\n");
}

iperf_cancel_send_timers(test);

if (test->stats_timer != NULL) {
tmr_cancel(test->stats_timer);
test->stats_timer = NULL;
}
if (test->reporter_timer != NULL) {
tmr_cancel(test->reporter_timer);
test->reporter_timer = NULL;
}
}

#if defined(HAVE_SSL)
int test_is_authorized(struct iperf_test *test){
if ( !(test->server_rsa_private_key && test->server_authorized_users)) {
Expand Down
2 changes: 1 addition & 1 deletion src/iperf_api.h
Original file line number Diff line number Diff line change
Expand Up @@ -333,6 +333,7 @@ void warning(const char *);
int iperf_exchange_results(struct iperf_test *);
int iperf_init_test(struct iperf_test *);
int iperf_create_send_timers(struct iperf_test *);
void iperf_cancel_periodic_timers(struct iperf_test *);
int iperf_parse_arguments(struct iperf_test *, int, char **);
int iperf_open_logfile(struct iperf_test *);
void iperf_close_logfile(struct iperf_test *);
Expand Down Expand Up @@ -416,7 +417,6 @@ enum {
IESKEWTHRESHOLD = 29, // Invalid value specified as skew threshold
IEIDLETIMEOUT = 30, // Invalid value specified as idle state timeout
IERCVTIMEOUT = 31, // Illegal message receive timeout
IERVRSONLYRCVTIMEOUT = 32, // Client receive timeout is valid only in reverse mode
IESNDTIMEOUT = 33, // Illegal message send timeout
IEUDPFILETRANSFER = 34, // Cannot transfer file using UDP
IESERVERAUTHUSERS = 35, // Cannot access authorized users file
Expand Down
46 changes: 29 additions & 17 deletions src/iperf_client_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ iperf_handle_message_client(struct iperf_test *test)
case TEST_RUNNING:
break;
case EXCHANGE_RESULTS:
iperf_cancel_periodic_timers(test);
if (iperf_exchange_results(test) < 0)
return -1;
break;
Expand Down Expand Up @@ -607,7 +608,7 @@ iperf_run_client(struct iperf_test * test)

/* Begin calculating CPU utilization */
cpu_util(NULL);
if (test->mode != SENDER)
if (test->mode != SENDER || test->state != TEST_RUNNING)
rcv_timeout_us = (test->settings->rcv_timeout.secs * SEC_TO_US) + test->settings->rcv_timeout.usecs;
else
rcv_timeout_us = 0;
Expand All @@ -622,16 +623,16 @@ iperf_run_client(struct iperf_test * test)
iperf_time_now(&now);
timeout = tmr_timeout(&now);

// In reverse active mode client ensures data is received
if (test->state == TEST_RUNNING && rcv_timeout_us > 0) {
// In non-sending active mode or not during active test, client ensures data םor control messages are received
if (rcv_timeout_us > 0) {
timeout_us = -1;
if (timeout != NULL) {
used_timeout.tv_sec = timeout->tv_sec;
used_timeout.tv_usec = timeout->tv_usec;
timeout_us = (timeout->tv_sec * SEC_TO_US) + timeout->tv_usec;
}
/* Cap the maximum select timeout at 1 second */
if (timeout_us > SEC_TO_US) {
/* Cap the maximum select timeout at 1 second during active test*/
if (test->state == TEST_RUNNING && timeout_us > SEC_TO_US) {
timeout_us = SEC_TO_US;
}
if (timeout_us < 0 || timeout_us > rcv_timeout_us) {
Expand All @@ -641,6 +642,8 @@ iperf_run_client(struct iperf_test * test)
timeout = &used_timeout;
}

if (timeout) timeout_us = (timeout->tv_sec * SEC_TO_US) + timeout->tv_usec;

#if (defined(__vxworks)) || (defined(__VXWORKS__))
if (timeout != NULL && timeout->tv_sec == 0 && timeout->tv_usec == 0) {
taskDelay (1);
Expand All @@ -657,23 +660,32 @@ iperf_run_client(struct iperf_test * test)
if (result < 0 && errno != EINTR) {
i_errno = IESELECT;
goto cleanup_and_fail;
} else if (result == 0 && test->state == TEST_RUNNING && rcv_timeout_us > 0) {
} else if (result == 0 && rcv_timeout_us > 0) {
/*
* If nothing was received in non-reverse running state
* then probably something got stuck - either client,
* server or network, and test should be terminated./
* If nothing was received then probably something got stuck -
* either client, server or network, and test should be terminated.
*/
iperf_time_now(&now);
if (iperf_time_diff(&now, &last_receive_time, &diff_time) == 0) {
t_usecs = iperf_time_in_usecs(&diff_time);
if (t_usecs > rcv_timeout_us) {
/* Idle timeout if no new blocks received */
if (test->blocks_received == last_receive_blocks) {
i_errno = IENOMSG;
goto cleanup_and_fail;
if (test->state == TEST_RUNNING && test->mode != SENDER) { // Check if data is received
if (iperf_time_diff(&now, &last_receive_time, &diff_time) == 0) {
t_usecs = iperf_time_in_usecs(&diff_time);
if (t_usecs > rcv_timeout_us) {
/* Idle timeout if no new blocks received */
if (test->blocks_received == last_receive_blocks) {
if (test->debug_level >= DEBUG_LEVEL_INFO) {
iperf_printf(test, "Receiving data blocks timed out\n");
}
i_errno = IENOMSG;
goto cleanup_and_fail;
}
}
}

} else if (test->state != TEST_RUNNING && rcv_timeout_us == timeout_us) { // Check if control messages are received
if (test->debug >= DEBUG_LEVEL_INFO) {
iperf_printf(test, "Receiving control messages timed out\n");
}
i_errno = IENOMSG;
goto cleanup_and_fail;
}
}

Expand Down
6 changes: 1 addition & 5 deletions src/iperf_error.c
Original file line number Diff line number Diff line change
Expand Up @@ -377,10 +377,6 @@ iperf_strerror(int int_errno)
case IEUDPFILETRANSFER:
snprintf(errstr, len, "cannot transfer file using UDP");
break;
case IERVRSONLYRCVTIMEOUT:
snprintf(errstr, len, "client receive timeout is valid only in receiving mode");
perr = 1;
break;
case IEDAEMON:
snprintf(errstr, len, "unable to become a daemon");
perr = 1;
Expand Down Expand Up @@ -480,7 +476,7 @@ iperf_strerror(int int_errno)
snprintf(errstr, len, "host device name (ip%%<dev>) is supported (and required) only for IPv6 link-local address");
break;
case IENOMSG:
snprintf(errstr, len, "idle timeout for receiving data");
snprintf(errstr, len, "idle timeout for receiving data or control messages");
break;
case IESETDONTFRAGMENT:
snprintf(errstr, len, "unable to set IP Do-Not-Fragment flag");
Expand Down
2 changes: 1 addition & 1 deletion src/iperf_locale.c
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,7 @@ const char usage_longstr[] = "Usage: iperf3 [-s|-c host] [options]\n"
" --timestamps<=format> emit a timestamp at the start of each output line\n"
" (optional \"=\" and format string as per strftime(3))\n"

" --rcv-timeout # idle timeout for receiving data (default %d ms)\n"
" --rcv-timeout # idle timeout for receiving data or control messages (default %d ms)\n"
#if defined(HAVE_TCP_USER_TIMEOUT)
" --snd-timeout # timeout for unacknowledged TCP data\n"
" (in ms, default is system settings)\n"
Expand Down
18 changes: 12 additions & 6 deletions src/iperf_server_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -272,6 +272,9 @@ iperf_handle_message_server(struct iperf_test *test)
test->reporter_callback(test);
if (iperf_set_send_state(test, EXCHANGE_RESULTS) != 0)
return -1;

iperf_cancel_periodic_timers(test);

if (iperf_exchange_results(test) < 0)
return -1;
if (iperf_set_send_state(test, DISPLAY_RESULTS) != 0)
Expand Down Expand Up @@ -605,15 +608,16 @@ iperf_run_server(struct iperf_test *test)
used_timeout.tv_usec = 0;
timeout = &used_timeout;
}
} else if (test->mode != SENDER) { // In non-reverse active mode server ensures data is received
} else if (test->mode != SENDER || test->state != TEST_RUNNING) {
// In non-reverse active mode or not during active test, server ensures data םor control messages are received
timeout_us = -1;
if (timeout != NULL) {
used_timeout.tv_sec = timeout->tv_sec;
used_timeout.tv_usec = timeout->tv_usec;
timeout_us = (timeout->tv_sec * SEC_TO_US) + timeout->tv_usec;
}
/* Cap the maximum select timeout at 1 second */
if (timeout_us > SEC_TO_US) {
/* Cap the maximum select timeout at 1 second during active test */
if (test->state == TEST_RUNNING && timeout_us > SEC_TO_US) {
timeout_us = SEC_TO_US;
}
if (timeout_us < 0 || timeout_us > rcv_timeout_us) {
Expand Down Expand Up @@ -660,10 +664,12 @@ iperf_run_server(struct iperf_test *test)
}

/*
* Running a test. If we're receiving, be sure we're making
* progress (sender hasn't died/crashed).
* Receiver when running a test or after test ended.
* Be sure we're making progress (sender hasn't died/crashed).
*/
else if (test->mode != SENDER && t_usecs > rcv_timeout_us) {
else if ( t_usecs > rcv_timeout_us &&
(test->mode != SENDER || test->state != TEST_RUNNING) )
{
/* Idle timeout if no new blocks received */
if (test->blocks_received == last_receive_blocks) {
test->server_forced_no_msg_restarts_count += 1;
Expand Down

0 comments on commit e5364f9

Please sign in to comment.