The server now runs until terminated by the user. Also fixed several memory leaks.

This commit is contained in:
sethdelliott 2010-06-30 15:58:16 +00:00
parent 181d61afab
commit efdc02f743
7 changed files with 92 additions and 40 deletions

View File

@ -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,
};

View File

@ -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);
}

View File

@ -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;
}

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);
}