Fix logfile file descriptor server leak (#1369)

* Close log file when cleaning up test

* Reset socket fds to -1 after closing

* Run server cleanup in error case

Prevent logfile fd leak in any case.

Fixes #1360
This commit is contained in:
crazyfermions 2022-08-23 22:19:40 +02:00 committed by GitHub
parent f9813626e5
commit 89ede124d7
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 37 additions and 12 deletions

View File

@ -1756,6 +1756,14 @@ int iperf_open_logfile(struct iperf_test *test)
return 0;
}
void iperf_close_logfile(struct iperf_test *test)
{
if (test->outfile && test->outfile != stdout) {
fclose(test->outfile);
test->outfile = NULL;
}
}
int
iperf_set_send_state(struct iperf_test *test, signed char state)
{
@ -2769,6 +2777,7 @@ iperf_defaults(struct iperf_test *testp)
testp->remote_congestion_used = NULL;
testp->server_port = PORT;
testp->ctrl_sck = -1;
testp->listener = -1;
testp->prot_listener = -1;
testp->other_side_has_retransmits = 0;
@ -2954,10 +2963,7 @@ iperf_free_test(struct iperf_test *test)
if (test->logfile) {
free(test->logfile);
test->logfile = NULL;
if (test->outfile && test->outfile != stdout) {
fclose(test->outfile);
test->outfile = NULL;
}
iperf_close_logfile(test);
}
if (test->server_output_text) {
@ -3051,6 +3057,7 @@ iperf_reset_test(struct iperf_test *test)
test->state = 0;
test->ctrl_sck = -1;
test->listener = -1;
test->prot_listener = -1;
test->bytes_sent = 0;

View File

@ -307,6 +307,7 @@ int iperf_init_test(struct iperf_test *);
int iperf_create_send_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 *);
void iperf_reset_test(struct iperf_test *);
void iperf_reset_stats(struct iperf_test * test);

View File

@ -165,6 +165,7 @@ iperf_sctp_listen(struct iperf_test *test)
int s, opt, saved_errno;
close(test->listener);
test->listener = -1;
snprintf(portstr, 6, "%d", test->server_port);
memset(&hints, 0, sizeof(hints));

View File

@ -208,6 +208,7 @@ iperf_handle_message_server(struct iperf_test *test)
FD_CLR(sp->socket, &test->read_set);
FD_CLR(sp->socket, &test->write_set);
close(sp->socket);
sp->socket = -1;
}
test->reporter_callback(test);
if (iperf_set_send_state(test, EXCHANGE_RESULTS) != 0)
@ -238,6 +239,7 @@ iperf_handle_message_server(struct iperf_test *test)
FD_CLR(sp->socket, &test->read_set);
FD_CLR(sp->socket, &test->write_set);
close(sp->socket);
sp->socket = -1;
}
test->state = IPERF_DONE;
break;
@ -267,6 +269,7 @@ server_timer_proc(TimerClientData client_data, struct iperf_time *nowP)
iperf_free_stream(sp);
}
close(test->ctrl_sck);
test->ctrl_sck = -1;
}
static void
@ -381,23 +384,30 @@ static void
cleanup_server(struct iperf_test *test)
{
struct iperf_stream *sp;
iperf_close_logfile(test);
/* 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);
if (sp->socket > -1) {
FD_CLR(sp->socket, &test->read_set);
FD_CLR(sp->socket, &test->write_set);
close(sp->socket);
sp->socket = -1;
}
}
/* Close open test sockets */
if (test->ctrl_sck) {
if (test->ctrl_sck > -1) {
close(test->ctrl_sck);
test->ctrl_sck = -1;
}
if (test->listener) {
if (test->listener > -1) {
close(test->listener);
test->listener = -1;
}
if (test->prot_listener > -1) { // May remain open if create socket failed
close(test->prot_listener);
test->prot_listener = -1;
}
/* Cancel any remaining timers. */
@ -450,12 +460,16 @@ iperf_run_server(struct iperf_test *test)
return -2;
if (test->affinity != -1)
if (iperf_setaffinity(test, test->affinity) != 0)
if (iperf_setaffinity(test, test->affinity) != 0) {
cleanup_server(test);
return -2;
}
if (test->json_output)
if (iperf_json_start(test) < 0)
if (iperf_json_start(test) < 0) {
cleanup_server(test);
return -2;
}
if (test->json_output) {
cJSON_AddItemToObject(test->json_start, "version", cJSON_CreateString(version));
@ -469,6 +483,7 @@ iperf_run_server(struct iperf_test *test)
// Open socket and listen
if (iperf_server_listen(test) < 0) {
cleanup_server(test);
return -2;
}
@ -722,11 +737,12 @@ iperf_run_server(struct iperf_test *test)
if (test->protocol->id != Ptcp) {
FD_CLR(test->prot_listener, &test->read_set);
close(test->prot_listener);
test->prot_listener = -1;
} else {
if (test->no_delay || test->settings->mss || test->settings->socket_bufsize) {
FD_CLR(test->listener, &test->read_set);
close(test->listener);
test->listener = 0;
test->listener = -1;
if ((s = netannounce(test->settings->domain, Ptcp, test->bind_address, test->bind_dev, test->server_port)) < 0) {
cleanup_server(test);
i_errno = IELISTEN;