diff --git a/src/Makefile.old b/src/Makefile.old index 38e3b15..a544455 100644 --- a/src/Makefile.old +++ b/src/Makefile.old @@ -1,5 +1,5 @@ CFLAGS=-g -Wall -OBJS=main.o iperf_api.o iperf_server_api.o iperf_tcp.o iperf_udp.o timer.o net.o tcp_window_size.o units.o iperf_util.o tcp_info.o locale.o iperf_error.o +OBJS=main.o iperf_api.o iperf_server_api.o iperf_tcp.o iperf_udp.o timer.o net.o tcp_window_size.o units.o iperf_util.o tcp_info.o locale.o iperf_error.o iperf_client_api.o LDFLAGS= UNAME=$(shell uname) diff --git a/src/iperf_api.c b/src/iperf_api.c index fab18bc..d088555 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -450,16 +450,7 @@ iperf_init_test(struct iperf_test *test) test->timer = new_timer(test->duration, 0); if (test->timer == NULL) return (-1); -/* - printf(test_start_time, test->protocol->name, test->num_streams, test->settings->blksize, - test->duration); -*/ - } else { -/* - printf(test_start_bytes, test->protocol->name, test->num_streams, test->settings->blksize, - test->settings->bytes); -*/ - } + } if (test->stats_interval != 0) { test->stats_timer = new_timer(test->stats_interval, 0); @@ -806,7 +797,6 @@ parse_results(struct iperf_test *test, char *results) for (sp = test->streams; sp; sp = sp->next) if (sp->id == sid) break; if (sp == NULL) { - // fprintf(stderr, "error: No stream with id %d\n", sid); i_errno = IESTREAMID; return (-1); } @@ -959,121 +949,6 @@ iperf_defaults(struct iperf_test * testp) return (0); } -/**************************************************************************/ - -int -iperf_create_streams(struct iperf_test *test) -{ - int i, s; - struct iperf_stream *sp; - - for (i = 0; i < test->num_streams; ++i) { - - if ((s = test->protocol->connect(test)) < 0) - return (-1); - - FD_SET(s, &test->read_set); - FD_SET(s, &test->write_set); - test->max_fd = (test->max_fd < s) ? s : test->max_fd; - - sp = iperf_new_stream(test, s); - if (!sp) - return (-1); - - /* Perform the new stream callback */ - if (test->on_new_stream) - test->on_new_stream(sp); - } - - return (0); -} - -int -iperf_handle_message_client(struct iperf_test *test) -{ - int rval; - - if ((rval = read(test->ctrl_sck, &test->state, sizeof(char))) <= 0) { - if (rval == 0) { - i_errno = IECTRLCLOSE; - return (-1); - } else { - i_errno = IERECVMESSAGE; - return (-1); - } - } - - switch (test->state) { - case PARAM_EXCHANGE: - if (iperf_exchange_parameters(test) < 0) - return (-1); - if (test->on_connect) - test->on_connect(test); - break; - case CREATE_STREAMS: - if (iperf_create_streams(test) < 0) - return (-1); - break; - case TEST_START: - if (iperf_init_test(test) < 0) - return (-1); - break; - case TEST_RUNNING: - break; - case EXCHANGE_RESULTS: - if (iperf_exchange_results(test) < 0) - return (-1); - break; - case DISPLAY_RESULTS: - if (test->on_test_finish) - test->on_test_finish(test); - iperf_client_end(test); - break; - case IPERF_DONE: - break; - case SERVER_TERMINATE: - i_errno = IESERVERTERM; - return (-1); - case ACCESS_DENIED: - i_errno = IEACCESSDENIED; - return (-1); - default: - i_errno = IEMESSAGE; - return (-1); - } - - return 0; -} - -/* iperf_connect -- client to server connection function */ -int -iperf_connect(struct iperf_test *test) -{ -// printf("Connecting to host %s, port %d\n", test->server_hostname, test->server_port); - - FD_ZERO(&test->read_set); - FD_ZERO(&test->write_set); - - get_uuid(test->cookie); - - /* Create and connect the control channel */ - test->ctrl_sck = netdial(Ptcp, test->server_hostname, test->server_port); - if (test->ctrl_sck < 0) { - i_errno = IECONNECT; - return (-1); - } - - if (Nwrite(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) < 0) { - i_errno = IESENDCOOKIE; - return (-1); - } - - FD_SET(test->ctrl_sck, &test->read_set); - FD_SET(test->ctrl_sck, &test->write_set); - test->max_fd = (test->ctrl_sck > test->max_fd) ? test->ctrl_sck : test->max_fd; - - return (0); -} /**************************************************************************/ void @@ -1419,114 +1294,9 @@ iperf_add_stream(struct iperf_test * test, struct iperf_stream * sp) } -/**************************************************************************/ - -int -iperf_client_end(struct iperf_test *test) -{ - struct iperf_stream *sp, *np; - - /* show final summary */ - test->reporter_callback(test); - - /* Deleting all streams - CAN CHANGE FREE_STREAM FN */ - for (sp = test->streams; sp; sp = np) { - close(sp->socket); - np = sp->next; - iperf_free_stream(sp); - } - - test->state = IPERF_DONE; - if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - i_errno = IESENDMESSAGE; - return (-1); - } - - return (0); -} - void sig_handler(int sig) { longjmp(env, 1); } -int -iperf_run_client(struct iperf_test * test) -{ - int result; - fd_set temp_read_set, temp_write_set; - struct timeval tv; - - /* Start the client and connect to the server */ - if (iperf_connect(test) < 0) { - return (-1); - } - - // XXX: Do we need to check signal() for errors? - signal(SIGINT, sig_handler); - if (setjmp(env)) { - test->state = CLIENT_TERMINATE; - if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - i_errno = IESENDMESSAGE; - return (-1); - } - exit(1); - } - - while (test->state != IPERF_DONE) { - - 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, &temp_read_set, &temp_write_set, NULL, &tv); - if (result < 0 && errno != EINTR) { - i_errno = IESELECT; - return (-1); - } else if (result > 0) { - if (FD_ISSET(test->ctrl_sck, &temp_read_set)) { - if (iperf_handle_message_client(test) < 0) - return (-1); - FD_CLR(test->ctrl_sck, &temp_read_set); - } - - if (test->state == TEST_RUNNING) { - if (test->reverse) { - // Reverse mode. Client receives. - if (iperf_recv(test) < 0) - return (-1); - } else { - // Regular mode. Client sends. - if (iperf_send(test) < 0) - return (-1); - } - - /* Perform callbacks */ - if (timer_expired(test->stats_timer)) { - test->stats_callback(test); - if (update_timer(test->stats_timer, test->stats_interval, 0) < 0) - return (-1); - } - if (timer_expired(test->reporter_timer)) { - test->reporter_callback(test); - if (update_timer(test->reporter_timer, test->reporter_interval, 0) < 0) - return (-1); - } - - /* Send TEST_END if all data has been sent or timer expired */ - if (all_data_sent(test) || timer_expired(test->timer)) { - test->stats_callback(test); - test->state = TEST_END; - if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - i_errno = IESENDMESSAGE; - return (-1); - } - } - } - } - } - - return (0); -} diff --git a/src/iperf_api.h b/src/iperf_api.h index 281f9f4..903671b 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -44,12 +44,6 @@ void iperf_stats_callback(struct iperf_test * test); void iperf_reporter_callback(struct iperf_test * test); -/** - * iperf_run_client -- Runs the client portion of a test - * - */ -int iperf_run_client(struct iperf_test * test); - /** * iperf_new_test -- return a new iperf_test with default values * @@ -100,8 +94,6 @@ void print_tcpinfo(struct iperf_interval_results *); void build_tcpinfo_message(struct iperf_interval_results *r, char *message); void print_interval_results(struct iperf_test * test, struct iperf_stream *sp); -int iperf_connect(struct iperf_test *); -int iperf_client_end(struct iperf_test *); int iperf_send(struct iperf_test *); int iperf_recv(struct iperf_test *); void sig_handler(int); @@ -110,8 +102,6 @@ void usage_long(); int all_data_sent(struct iperf_test *); int package_parameters(struct iperf_test *); int parse_parameters(struct iperf_test *); -int iperf_create_streams(struct iperf_test *); -int iperf_handle_message_client(struct iperf_test *); int iperf_exchange_results(struct iperf_test *); int parse_results(struct iperf_test *, char *); int iperf_init_test(struct iperf_test *); diff --git a/src/iperf_client_api.c b/src/iperf_client_api.c new file mode 100644 index 0000000..293a0dd --- /dev/null +++ b/src/iperf_client_api.c @@ -0,0 +1,240 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "iperf.h" +#include "iperf_api.h" +#include "iperf_client_api.h" +#include "iperf_error.h" +#include "iperf_util.h" +#include "net.h" +#include "timer.h" + + +int +iperf_create_streams(struct iperf_test *test) +{ + int i, s; + struct iperf_stream *sp; + + for (i = 0; i < test->num_streams; ++i) { + + if ((s = test->protocol->connect(test)) < 0) + return (-1); + + FD_SET(s, &test->read_set); + FD_SET(s, &test->write_set); + test->max_fd = (test->max_fd < s) ? s : test->max_fd; + + sp = iperf_new_stream(test, s); + if (!sp) + return (-1); + + /* Perform the new stream callback */ + if (test->on_new_stream) + test->on_new_stream(sp); + } + + return (0); +} + +int +iperf_handle_message_client(struct iperf_test *test) +{ + int rval; + + if ((rval = read(test->ctrl_sck, &test->state, sizeof(char))) <= 0) { + if (rval == 0) { + i_errno = IECTRLCLOSE; + return (-1); + } else { + i_errno = IERECVMESSAGE; + return (-1); + } + } + + switch (test->state) { + case PARAM_EXCHANGE: + if (iperf_exchange_parameters(test) < 0) + return (-1); + if (test->on_connect) + test->on_connect(test); + break; + case CREATE_STREAMS: + if (iperf_create_streams(test) < 0) + return (-1); + break; + case TEST_START: + if (iperf_init_test(test) < 0) + return (-1); + break; + case TEST_RUNNING: + break; + case EXCHANGE_RESULTS: + if (iperf_exchange_results(test) < 0) + return (-1); + break; + case DISPLAY_RESULTS: + if (test->on_test_finish) + test->on_test_finish(test); + iperf_client_end(test); + break; + case IPERF_DONE: + break; + case SERVER_TERMINATE: + i_errno = IESERVERTERM; + return (-1); + case ACCESS_DENIED: + i_errno = IEACCESSDENIED; + return (-1); + default: + i_errno = IEMESSAGE; + return (-1); + } + + return 0; +} + + + +/* iperf_connect -- client to server connection function */ +int +iperf_connect(struct iperf_test *test) +{ +// printf("Connecting to host %s, port %d\n", test->server_hostname, test->server_port); + + FD_ZERO(&test->read_set); + FD_ZERO(&test->write_set); + + get_uuid(test->cookie); + + /* Create and connect the control channel */ + test->ctrl_sck = netdial(Ptcp, test->server_hostname, test->server_port); + if (test->ctrl_sck < 0) { + i_errno = IECONNECT; + return (-1); + } + + if (Nwrite(test->ctrl_sck, test->cookie, COOKIE_SIZE, Ptcp) < 0) { + i_errno = IESENDCOOKIE; + return (-1); + } + + FD_SET(test->ctrl_sck, &test->read_set); + FD_SET(test->ctrl_sck, &test->write_set); + test->max_fd = (test->ctrl_sck > test->max_fd) ? test->ctrl_sck : test->max_fd; + + return (0); +} + + +int +iperf_client_end(struct iperf_test *test) +{ + struct iperf_stream *sp, *np; + + /* show final summary */ + test->reporter_callback(test); + + /* Deleting all streams - CAN CHANGE FREE_STREAM FN */ + for (sp = test->streams; sp; sp = np) { + close(sp->socket); + np = sp->next; + iperf_free_stream(sp); + } + + test->state = IPERF_DONE; + if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { + i_errno = IESENDMESSAGE; + return (-1); + } + + return (0); +} + + +int +iperf_run_client(struct iperf_test * test) +{ + int result; + fd_set temp_read_set, temp_write_set; + struct timeval tv; + + /* Start the client and connect to the server */ + if (iperf_connect(test) < 0) { + return (-1); + } + + // XXX: Do we need to check signal() for errors? + signal(SIGINT, sig_handler); + if (setjmp(env)) { + test->state = CLIENT_TERMINATE; + if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { + i_errno = IESENDMESSAGE; + return (-1); + } + exit(1); + } + + while (test->state != IPERF_DONE) { + + 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, &temp_read_set, &temp_write_set, NULL, &tv); + if (result < 0 && errno != EINTR) { + i_errno = IESELECT; + return (-1); + } else if (result > 0) { + if (FD_ISSET(test->ctrl_sck, &temp_read_set)) { + if (iperf_handle_message_client(test) < 0) + return (-1); + FD_CLR(test->ctrl_sck, &temp_read_set); + } + + if (test->state == TEST_RUNNING) { + if (test->reverse) { + // Reverse mode. Client receives. + if (iperf_recv(test) < 0) + return (-1); + } else { + // Regular mode. Client sends. + if (iperf_send(test) < 0) + return (-1); + } + + /* Perform callbacks */ + if (timer_expired(test->stats_timer)) { + test->stats_callback(test); + if (update_timer(test->stats_timer, test->stats_interval, 0) < 0) + return (-1); + } + if (timer_expired(test->reporter_timer)) { + test->reporter_callback(test); + if (update_timer(test->reporter_timer, test->reporter_interval, 0) < 0) + return (-1); + } + + /* Send TEST_END if all data has been sent or timer expired */ + if (all_data_sent(test) || timer_expired(test->timer)) { + test->stats_callback(test); + test->state = TEST_END; + if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { + i_errno = IESENDMESSAGE; + return (-1); + } + } + } + } + } + + return (0); +} diff --git a/src/iperf_client_api.h b/src/iperf_client_api.h new file mode 100644 index 0000000..1bc683d --- /dev/null +++ b/src/iperf_client_api.h @@ -0,0 +1,18 @@ + +#ifndef __IPERF_CLIENT_API_H +#define __IPERF_CLIENT_API_H + +#include "iperf.h" + +int iperf_run_client(struct iperf_test *); + +int iperf_connect(struct iperf_test *); + +int iperf_create_streams(struct iperf_test *); + +int iperf_handle_message_client(struct iperf_test *); + +int iperf_client_end(struct iperf_test *); + +#endif + diff --git a/src/iperf_server_api.h b/src/iperf_server_api.h index d1d7abb..0574c80 100644 --- a/src/iperf_server_api.h +++ b/src/iperf_server_api.h @@ -1,3 +1,4 @@ + #ifndef __IPERF_SERVER_API_H #define __IPERF_SERVER_API_H @@ -14,3 +15,4 @@ int iperf_handle_message_server(struct iperf_test *); void iperf_test_reset(struct iperf_test *); #endif + diff --git a/src/main.c b/src/main.c index 996bea6..c05a426 100644 --- a/src/main.c +++ b/src/main.c @@ -25,6 +25,7 @@ #include "iperf.h" #include "iperf_api.h" +#include "iperf_client_api.h" #include "iperf_server_api.h" #include "units.h" #include "locale.h"