The server now runs until terminated by the user. Also fixed several memory leaks.
This commit is contained in:
parent
181d61afab
commit
efdc02f743
@ -214,7 +214,8 @@ enum
|
||||
CLIENT_TERMINATE = 14,
|
||||
EXCHANGE_RESULTS = 15,
|
||||
DISPLAY_RESULTS = 16,
|
||||
IPERF_DONE = 17,
|
||||
IPERF_START = 17,
|
||||
IPERF_DONE = 18,
|
||||
ACCESS_DENIED = -1,
|
||||
};
|
||||
|
||||
|
@ -173,9 +173,9 @@ iperf_send(struct iperf_test *test)
|
||||
update_timer(reporter_interval, test->reporter_interval, 0);
|
||||
}
|
||||
} else {
|
||||
free(timer);
|
||||
free(stats_interval);
|
||||
free(reporter_interval);
|
||||
free_timer(timer);
|
||||
free_timer(stats_interval);
|
||||
free_timer(reporter_interval);
|
||||
|
||||
// Send TEST_DONE (ALL_STREAMS_END) message
|
||||
test->state = TEST_END;
|
||||
@ -333,6 +333,9 @@ parse_parameters(struct iperf_test *test)
|
||||
break;
|
||||
}
|
||||
}
|
||||
// XXX: optreset is not needed on ubuntu
|
||||
optreset = 1;
|
||||
optind = 0;
|
||||
|
||||
free(params);
|
||||
|
||||
@ -363,7 +366,6 @@ iperf_exchange_parameters(struct iperf_test * test)
|
||||
|
||||
test->prot_listener = netannounce(test->protocol, NULL, test->server_port + 1);
|
||||
FD_SET(test->prot_listener, &test->read_set);
|
||||
FD_SET(test->prot_listener, &test->write_set);
|
||||
test->max_fd = (test->prot_listener > test->max_fd) ? test->prot_listener : test->max_fd;
|
||||
|
||||
// Send the control message to create streams and start the test
|
||||
@ -628,13 +630,12 @@ iperf_new_test()
|
||||
perror("malloc");
|
||||
return (NULL);
|
||||
}
|
||||
/* initialise everything to zero */
|
||||
/* initialize everything to zero */
|
||||
memset(testp, 0, sizeof(struct iperf_test));
|
||||
|
||||
testp->default_settings = (struct iperf_settings *) malloc(sizeof(struct iperf_settings));
|
||||
memset(testp->default_settings, 0, sizeof(struct iperf_settings));
|
||||
|
||||
/* return an empty iperf_test* with memory alloted. */
|
||||
return testp;
|
||||
}
|
||||
|
||||
@ -777,12 +778,6 @@ iperf_free_test(struct iperf_test * test)
|
||||
{
|
||||
free(test->default_settings);
|
||||
|
||||
// This funciton needs to be updated to free and close streams
|
||||
// Currently it just sets the pointer to the streams list to NULL...
|
||||
|
||||
close(test->listener_sock_tcp);
|
||||
close(test->listener_sock_udp);
|
||||
|
||||
test->streams = NULL;
|
||||
test->accept = NULL;
|
||||
test->stats_callback = NULL;
|
||||
@ -997,9 +992,15 @@ print_interval_results(struct iperf_test * test, struct iperf_stream * sp)
|
||||
void
|
||||
iperf_free_stream(struct iperf_stream * sp)
|
||||
{
|
||||
struct iperf_interval_results *ip, *np;
|
||||
|
||||
/* XXX: need to free interval list too! */
|
||||
free(sp->buffer);
|
||||
free(sp->settings);
|
||||
for (ip = sp->result->interval_results; ip; ip = np) {
|
||||
np = ip->next;
|
||||
free(ip);
|
||||
}
|
||||
free(sp->result);
|
||||
free(sp->send_timer);
|
||||
free(sp);
|
||||
@ -1112,7 +1113,7 @@ iperf_add_stream(struct iperf_test * test, struct iperf_stream * sp)
|
||||
int
|
||||
iperf_client_end(struct iperf_test *test)
|
||||
{
|
||||
struct iperf_stream *sp;
|
||||
struct iperf_stream *sp, *np;
|
||||
printf("Test Complete. Summary Results:\n");
|
||||
|
||||
/* show final summary */
|
||||
@ -1135,8 +1136,9 @@ iperf_client_end(struct iperf_test *test)
|
||||
//printf("Done getting/printing results. \n");
|
||||
|
||||
/* Deleting all streams - CAN CHANGE FREE_STREAM FN */
|
||||
for (sp = test->streams; sp != NULL; sp = sp->next) {
|
||||
for (sp = test->streams; sp; sp = np) {
|
||||
close(sp->socket);
|
||||
np = sp->next;
|
||||
iperf_free_stream(sp);
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ iperf_server_listen(struct iperf_test *test)
|
||||
printf("-----------------------------------------------------------\n");
|
||||
|
||||
FD_ZERO(&test->read_set);
|
||||
FD_ZERO(&test->temp_set);
|
||||
FD_ZERO(&test->write_set);
|
||||
FD_SET(test->listener, &test->read_set);
|
||||
test->max_fd = (test->listener > test->max_fd) ? test->listener : test->max_fd;
|
||||
|
||||
@ -140,6 +140,8 @@ iperf_accept(struct iperf_test *test)
|
||||
int
|
||||
iperf_handle_message_server(struct iperf_test *test)
|
||||
{
|
||||
struct iperf_stream *sp;
|
||||
|
||||
if (read(test->ctrl_sck, &test->state, sizeof(char)) < 0) {
|
||||
// XXX: Needs to indicate read error
|
||||
return -1;
|
||||
@ -154,6 +156,11 @@ iperf_handle_message_server(struct iperf_test *test)
|
||||
case TEST_RUNNING:
|
||||
break;
|
||||
case TEST_END:
|
||||
for (sp = test->streams; sp; sp = sp->next) {
|
||||
FD_CLR(sp->socket, &test->read_set);
|
||||
FD_CLR(sp->socket, &test->write_set);
|
||||
close(sp->socket);
|
||||
}
|
||||
test->state = EXCHANGE_RESULTS;
|
||||
if (write(test->ctrl_sck, &test->state, sizeof(char)) < 0) {
|
||||
perror("write EXCHANGE_RESULTS");
|
||||
@ -181,11 +188,42 @@ iperf_handle_message_server(struct iperf_test *test)
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
iperf_test_reset(struct iperf_test *test)
|
||||
{
|
||||
struct iperf_stream *sp, *np;
|
||||
struct iperf_settings *settings;
|
||||
int listener;
|
||||
|
||||
close(test->ctrl_sck);
|
||||
|
||||
/* Free streams */
|
||||
for (sp = test->streams; sp; sp = np) {
|
||||
np = sp->next;
|
||||
iperf_free_stream(sp);
|
||||
}
|
||||
|
||||
/* Clear memory and reset defaults */
|
||||
memset(test->default_settings, 0, sizeof(struct iperf_settings));
|
||||
settings = test->default_settings;
|
||||
listener = test->listener;
|
||||
memset(test, 0, sizeof(struct iperf_test));
|
||||
test->role = 's';
|
||||
test->default_settings = settings;
|
||||
iperf_defaults(test);
|
||||
test->listener = listener;
|
||||
FD_ZERO(&test->read_set);
|
||||
FD_ZERO(&test->write_set);
|
||||
FD_SET(test->listener, &test->read_set);
|
||||
test->max_fd = (test->listener > test->max_fd) ? test->listener : test->max_fd;
|
||||
}
|
||||
|
||||
int
|
||||
iperf_run_server(struct iperf_test *test)
|
||||
{
|
||||
int result;
|
||||
int streams_accepted = 0;
|
||||
int streams_accepted;
|
||||
fd_set temp_read_set, temp_write_set;
|
||||
struct timeval tv;
|
||||
|
||||
// Open socket and listen
|
||||
@ -207,43 +245,46 @@ iperf_run_server(struct iperf_test *test)
|
||||
exit(1);
|
||||
}
|
||||
|
||||
test->default_settings->state = TEST_RUNNING;
|
||||
for (;;) {
|
||||
|
||||
test->state = IPERF_START;
|
||||
streams_accepted = 0;
|
||||
|
||||
while (test->state != IPERF_DONE) {
|
||||
|
||||
// XXX: Move test->temp_set over to local fd_set
|
||||
memcpy(&test->temp_set, &test->read_set, sizeof(fd_set));
|
||||
memcpy(&temp_read_set, &test->read_set, sizeof(fd_set));
|
||||
memcpy(&temp_write_set, &test->write_set, sizeof(fd_set));
|
||||
tv.tv_sec = 15;
|
||||
tv.tv_usec = 0;
|
||||
|
||||
result = select(test->max_fd + 1, &test->temp_set, NULL, NULL, &tv);
|
||||
result = select(test->max_fd + 1, &temp_read_set, &temp_write_set, NULL, &tv);
|
||||
if (result < 0 && errno != EINTR) {
|
||||
// Change the way this handles errors
|
||||
perror("select");
|
||||
exit(1);
|
||||
} else if (result > 0) {
|
||||
if (FD_ISSET(test->listener, &test->temp_set)) {
|
||||
if (FD_ISSET(test->listener, &temp_read_set)) {
|
||||
if (iperf_accept(test) < 0) {
|
||||
fprintf(stderr, "iperf_accept: error accepting control socket. exiting...\n");
|
||||
exit(1);
|
||||
}
|
||||
FD_CLR(test->listener, &test->temp_set);
|
||||
FD_CLR(test->listener, &temp_read_set);
|
||||
}
|
||||
if (FD_ISSET(test->ctrl_sck, &test->temp_set)) {
|
||||
if (FD_ISSET(test->ctrl_sck, &temp_read_set)) {
|
||||
// Handle control messages
|
||||
iperf_handle_message_server(test);
|
||||
FD_CLR(test->ctrl_sck, &test->temp_set);
|
||||
FD_CLR(test->ctrl_sck, &temp_read_set);
|
||||
}
|
||||
|
||||
if (test->state == CREATE_STREAMS) {
|
||||
if (FD_ISSET(test->prot_listener, &test->temp_set)) {
|
||||
if (FD_ISSET(test->prot_listener, &temp_read_set)) {
|
||||
// Spawn new streams
|
||||
// XXX: This works, but should it check cookies for authenticity
|
||||
// Also, currently it uses 5202 for stream connections.
|
||||
// Should this be fixed to use 5201 instead?
|
||||
iperf_tcp_accept(test);
|
||||
++streams_accepted;
|
||||
FD_CLR(test->prot_listener, &test->temp_set);
|
||||
FD_CLR(test->prot_listener, &temp_read_set);
|
||||
}
|
||||
if (streams_accepted == test->num_streams) {
|
||||
FD_CLR(test->prot_listener, &test->read_set);
|
||||
@ -266,14 +307,15 @@ iperf_run_server(struct iperf_test *test)
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up the last test */
|
||||
iperf_test_reset(test);
|
||||
printf("\n");
|
||||
|
||||
}
|
||||
|
||||
// XXX: Need to put the above while loop into another control structure
|
||||
// that initiates a new test upon each connection rather than dying.
|
||||
|
||||
/* reset cookie when client is finished */
|
||||
/* XXX: which cookie to reset, and why is it stored to 2 places? */
|
||||
//memset(test->streams->settings->cookie, '\0', COOKIE_SIZE);
|
||||
/* All memory for the previous run needs to be freed here */
|
||||
memset(test->default_settings->cookie, '\0', COOKIE_SIZE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -11,4 +11,6 @@ int iperf_acept(struct iperf_test *);
|
||||
|
||||
int iperf_handle_message_server(struct iperf_test *);
|
||||
|
||||
void iperf_test_reset(struct iperf_test *);
|
||||
|
||||
#endif
|
||||
|
@ -98,7 +98,7 @@ netannounce(int proto, char *local, int port)
|
||||
/********************************************************************/
|
||||
|
||||
int
|
||||
Nread(int fd, char *buf, int count, int prot)
|
||||
Nread(int fd, void *buf, int count, int prot)
|
||||
{
|
||||
struct sockaddr from;
|
||||
socklen_t len = sizeof(from);
|
||||
@ -135,7 +135,7 @@ Nread(int fd, char *buf, int count, int prot)
|
||||
*/
|
||||
|
||||
int
|
||||
Nwrite(int fd, char *buf, int count, int prot)
|
||||
Nwrite(int fd, void *buf, int count, int prot)
|
||||
{
|
||||
register int n;
|
||||
register int nleft = count;
|
||||
|
@ -3,8 +3,8 @@
|
||||
|
||||
int netdial(int, char *, int);
|
||||
int netannounce(int, char *, int);
|
||||
int Nwrite(int, char *, int, int);
|
||||
int Nread(int, char *, int, int);
|
||||
int Nwrite(int, void *, int, int);
|
||||
int Nread(int, void *, int, int);
|
||||
int getsock_tcp_mss(int);
|
||||
int set_tcp_options(int, int, int);
|
||||
int setnonblocking(int);
|
||||
|
13
src/uuid.c
13
src/uuid.c
@ -15,10 +15,11 @@
|
||||
|
||||
|
||||
/* XXX: this code is not portable: not all versions of linux install libuuidgen
|
||||
by default
|
||||
* if not installed, may need to do something like this:
|
||||
* yum install libuuid-devel
|
||||
* apt-get install apt-get install
|
||||
* by default
|
||||
*
|
||||
* if not installed, may need to do something like this:
|
||||
* yum install libuuid-devel
|
||||
* apt-get install uuid-dev
|
||||
*/
|
||||
|
||||
|
||||
@ -39,4 +40,8 @@ get_uuid(char *temp)
|
||||
#error No uuid function specified
|
||||
#endif
|
||||
memcpy(temp, s, 37);
|
||||
|
||||
// XXX: Freeing s only works if you HAVE_UUID_GENERATE
|
||||
// Otherwise use rpc_string_free (?)
|
||||
free(s);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user