From b60a49dd37350c0a7d05b9ed18347f687c2819ce Mon Sep 17 00:00:00 2001 From: sethdelliott Date: Tue, 20 Jul 2010 22:27:50 +0000 Subject: [PATCH] All error handling is now handled by iperf_error. Also cleaned up some code --- src/iperf.h | 23 ---- src/iperf_api.c | 169 ++++++++++++++------------- src/iperf_api.h | 2 +- src/iperf_error.c | 254 ++++++++++++++++++++++++++++++++++++++++- src/iperf_error.h | 71 ++++++++---- src/iperf_server_api.c | 178 +++++++++++++---------------- src/iperf_tcp.c | 25 +--- src/iperf_udp.c | 41 +++---- src/main.c | 6 +- src/net.c | 15 ++- src/timer.c | 25 ++-- src/timer.h | 2 +- 12 files changed, 513 insertions(+), 298 deletions(-) diff --git a/src/iperf.h b/src/iperf.h index 5f9b3a9..d4c3221 100644 --- a/src/iperf.h +++ b/src/iperf.h @@ -147,33 +147,10 @@ struct iperf_test iperf_size_t bytes_sent; - /* iperf error reporting - * - errtype: (0,1,2) - * 0: use perror(errno) - * 1: use herror(errno) - * 2: use ierror(errno) - */ - //int errtype; - //int errno; - struct iperf_stream *streams; /* pointer to list of struct stream */ struct iperf_settings *default_settings; }; -struct param_exchange -{ - int state; - int protocol; - int num_streams; - int reverse; - int blksize; - int recv_window; - int send_window; - int mss; - char format; - char cookie[COOKIE_SIZE]; -}; - enum { /* default settings */ diff --git a/src/iperf_api.c b/src/iperf_api.c index 6bba42b..a275174 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -28,6 +28,7 @@ #include #include +#include "net.h" #include "iperf.h" #include "iperf_api.h" #include "iperf_udp.h" @@ -265,11 +266,11 @@ all_data_sent(struct iperf_test * test) { if (test->default_settings->bytes > 0) { if (test->bytes_sent >= (test->num_streams * test->default_settings->bytes)) { - return 1; + return (1); } } - return 0; + return (0); } int @@ -287,7 +288,6 @@ iperf_send(struct iperf_test *test) result = select(test->max_fd + 1, NULL, &temp_write_set, NULL, &tv); if (result < 0 && errno != EINTR) { - // perror("select iperf_send"); i_errno = IESELECT; return (-1); } @@ -295,7 +295,6 @@ iperf_send(struct iperf_test *test) for (sp = test->streams; sp != NULL; sp = sp->next) { if (FD_ISSET(sp->socket, &temp_write_set)) { if ((bytes_sent = sp->snd(sp)) < 0) { - // perror("iperf stream->snd"); i_errno = IESTREAMWRITE; return (-1); } @@ -305,7 +304,7 @@ iperf_send(struct iperf_test *test) } } - return 0; + return (0); } int @@ -323,7 +322,6 @@ iperf_recv(struct iperf_test *test) result = select(test->max_fd + 1, &temp_read_set, NULL, NULL, &tv); if (result < 0) { - // perror("select iperf_recv"); i_errno = IESELECT; return (-1); } @@ -331,7 +329,6 @@ iperf_recv(struct iperf_test *test) for (sp = test->streams; sp != NULL; sp = sp->next) { if (FD_ISSET(sp->socket, &temp_read_set)) { if ((bytes_sent = sp->rcv(sp)) < 0) { - // perror("sp->rcv(sp)"); i_errno = IESTREAMREAD; return (-1); } @@ -341,10 +338,10 @@ iperf_recv(struct iperf_test *test) } } - return 0; + return (0); } -void +int iperf_init_test(struct iperf_test *test) { char *prot; @@ -358,8 +355,11 @@ iperf_init_test(struct iperf_test *test) assert(dtargus != 0); - for (sp = test->streams; sp; sp = sp->next) + for (sp = test->streams; sp; sp = sp->next) { sp->send_timer = new_timer(dtargus / SEC_TO_US, dtargus % SEC_TO_US); + if (sp->send_timer == NULL) + return (-1); + } } else { prot = "TCP"; } @@ -367,6 +367,8 @@ iperf_init_test(struct iperf_test *test) /* Set timers */ if (test->default_settings->bytes == 0) { test->timer = new_timer(test->duration, 0); + if (test->timer == NULL) + return (-1); printf(test_start_time, prot, test->num_streams, test->default_settings->blksize, test->duration); } else { @@ -374,14 +376,26 @@ iperf_init_test(struct iperf_test *test) test->default_settings->bytes); } - if (test->stats_interval != 0) + if (test->stats_interval != 0) { test->stats_timer = new_timer(test->stats_interval, 0); - if (test->reporter_interval != 0) + if (test->stats_timer == NULL) + return (-1); + } + if (test->reporter_interval != 0) { test->reporter_timer = new_timer(test->reporter_interval, 0); + if (test->reporter_timer == NULL) + return (-1); + } /* Set start time */ - for (sp = test->streams; sp; sp = sp->next) - gettimeofday(&sp->result->start_time, NULL); + for (sp = test->streams; sp; sp = sp->next) { + if (gettimeofday(&sp->result->start_time, NULL) < 0) { + i_errno = IEINITTEST; + return (-1); + } + } + + return (0); } @@ -445,7 +459,7 @@ package_parameters(struct iperf_test *test) *pstring = (char) (strlen(pstring) - 1); - if (Nwrite(test->ctrl_sck, pstring, (size_t) strlen(pstring), Ptcp) < 0) { + if (Nwrite(test->ctrl_sck, pstring, strlen(pstring), Ptcp) < 0) { i_errno = IESENDPARAMS; return (-1); } @@ -461,33 +475,29 @@ parse_parameters(struct iperf_test *test) char *param, **params; char len, ch; char pstring[256]; - char readbuf[256]; memset(pstring, 0, 256 * sizeof(char)); - if (read(test->ctrl_sck, &len, sizeof(char)) < 0) { - perror("read len"); - return -1; + if (Nread(test->ctrl_sck, &len, sizeof(char), Ptcp) < 0) { + i_errno = IERECVPARAMS; + return (-1); } - while (len > 0) { - memset(readbuf, 0, 256 * sizeof(char)); - if ((len -= read(test->ctrl_sck, readbuf, (size_t) len)) < 0) { - perror("read pstring"); - return -1; - } - strcat(pstring, readbuf); + if (Nread(test->ctrl_sck, pstring, len, Ptcp) < 0) { + i_errno = IERECVPARAMS; + return (-1); } for (param = strtok(pstring, " "), n = 0, params = NULL; param; param = strtok(NULL, " ")) { if ((params = realloc(params, (n+1)*sizeof(char *))) == NULL) { - perror("realloc"); - return -1; + i_errno = IERECVPARAMS; + return (-1); } params[n] = param; n++; } + // XXX: Should we check for parameters exceeding maximum values here? while ((ch = getopt(n, params, "pt:n:m:uNP:Rw:l:b:")) != -1) { switch (ch) { case 'p': @@ -533,7 +543,7 @@ parse_parameters(struct iperf_test *test) free(params); - return 0; + return (0); } /** @@ -553,12 +563,16 @@ iperf_exchange_parameters(struct iperf_test * test) return (-1); } else { - parse_parameters(test); + if (parse_parameters(test) < 0) + return (-1); printf(" cookie: %s\n", test->default_settings->cookie); if (test->protocol == Pudp) { - test->listener_udp = netannounce(test->protocol, NULL, test->server_port); + if ((test->listener_udp = netannounce(test->protocol, NULL, test->server_port)) < 0) { + i_errno = IELISTEN; + return (-1); + } FD_SET(test->listener_udp, &test->read_set); test->max_fd = (test->listener_udp > test->max_fd) ? test->listener_udp : test->max_fd; } else if (test->protocol == Ptcp) { @@ -566,28 +580,28 @@ iperf_exchange_parameters(struct iperf_test * test) FD_CLR(test->listener_tcp, &test->read_set); close(test->listener_tcp); if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) { - perror("socket tcp listener mss"); + i_errno = IELISTEN; return (-1); } if (test->no_delay) { opt = 1; if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) < 0) { - perror("setsockopt TCP_NODELAY"); + i_errno = IESETNODELAY; return (-1); } printf(" TCP NODELAY: on\n"); } // XXX: Setting MSS is very buggy! - if (opt = test->default_settings->mss) { + if ((opt = test->default_settings->mss)) { if (setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, &opt, sizeof(opt)) < 0) { - perror("setsockopt TCP_MAXSEG"); + i_errno = IESETMSS; return (-1); } printf(" TCP MSS: %d\n", opt); } opt = 1; if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)) < 0) { - perror("setsockopt SO_REUSEADDR"); + i_errno = IEREUSEADDR; return (-1); } memset(&sa, 0, sizeof(sa)); @@ -596,11 +610,14 @@ iperf_exchange_parameters(struct iperf_test * test) sa.sin_port = htons(test->server_port); if (bind(s, (struct sockaddr *) &sa, sizeof(sa)) < 0) { close(s); - perror("bind tcp mss/nodelay listener"); + i_errno = IELISTEN; return (-1); } - listen(s, 5); + if (listen(s, 5) < 0) { + i_errno = IELISTEN; + return (-1); + } test->listener_tcp = s; test->max_fd = (s > test->max_fd) ? s : test->max_fd; @@ -612,13 +629,13 @@ iperf_exchange_parameters(struct iperf_test * test) // Send the control message to create streams and start the test test->state = CREATE_STREAMS; if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - perror("Nwrite CREATE_STREAMS"); - return -1; + i_errno = IESENDMESSAGE; + return (-1); } } - return 0; + return (0); } /*************************************************************/ @@ -642,7 +659,6 @@ iperf_exchange_results(struct iperf_test *test) sp->cnt_error, sp->packet_count); size += strlen(buf); if ((results = realloc(results, size+1)) == NULL) { - // perror("realloc results"); i_errno = IEPACKAGERESULTS; return (-1); } @@ -653,12 +669,10 @@ iperf_exchange_results(struct iperf_test *test) size++; size = htonl(size); if (Nwrite(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) { - // perror("Nwrite size"); i_errno = IESENDRESULTS; return (-1); } if (Nwrite(test->ctrl_sck, results, ntohl(size), Ptcp) < 0) { - // perror("Nwrite results"); i_errno = IESENDRESULTS; return (-1); } @@ -666,19 +680,16 @@ iperf_exchange_results(struct iperf_test *test) /* Get server results string */ if (Nread(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) { - // perror("Nread size"); i_errno = IERECVRESULTS; return (-1); } size = ntohl(size); results = (char *) malloc(size * sizeof(char)); if (results == NULL) { - // perror("malloc results"); i_errno = IERECVRESULTS; return (-1); } if (Nread(test->ctrl_sck, results, size, Ptcp) < 0) { - // perror("Nread results"); i_errno = IERECVRESULTS; return (-1); } @@ -692,21 +703,23 @@ iperf_exchange_results(struct iperf_test *test) } else { /* Get client results string */ if (Nread(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) { - perror("Nread size"); + i_errno = IERECVRESULTS; return (-1); } size = ntohl(size); results = (char *) malloc(size * sizeof(char)); if (results == NULL) { - perror("malloc results"); + i_errno = IERECVRESULTS; return (-1); } if (Nread(test->ctrl_sck, results, size, Ptcp) < 0) { - perror("Nread results"); + i_errno = IERECVRESULTS; return (-1); } - parse_results(test, results); + // XXX: Same issue as with client + if (parse_results(test, results) < 0) + return (-1); free(results); @@ -719,7 +732,7 @@ iperf_exchange_results(struct iperf_test *test) sp->cnt_error, sp->packet_count); size += strlen(buf); if ((results = realloc(results, size+1)) == NULL) { - perror("realloc results"); + i_errno = IEPACKAGERESULTS; return (-1); } if (sp == test->streams) @@ -729,18 +742,18 @@ iperf_exchange_results(struct iperf_test *test) size++; size = htonl(size); if (Nwrite(test->ctrl_sck, &size, sizeof(size), Ptcp) < 0) { - perror("Nwrite size"); + i_errno = IESENDRESULTS; return (-1); } if (Nwrite(test->ctrl_sck, results, ntohl(size), Ptcp) < 0) { - perror("Nwrite results"); + i_errno = IESENDRESULTS; return (-1); } free(results); } - return 0; + return (0); } /*************************************************************/ @@ -950,49 +963,43 @@ iperf_create_streams(struct iperf_test *test) if (test->no_delay) { opt = 1; if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) < 0) { - // perror("setsockopt"); i_errno = IECREATESTREAM; return (-1); } } if (opt = test->default_settings->mss) { if (setsockopt(s, IPPROTO_TCP, TCP_MAXSEG, &opt, sizeof(opt)) < 0) { - // perror("setsockopt"); i_errno = IECREATESTREAM; return (-1); } } if (connect(s, (struct sockaddr *) &sa, sizeof(sa)) < 0 && errno != EINPROGRESS) { - // perror("connect tcp stream"); - i_errno = IECREATESTREAM; + i_errno = IESTREAMCONNECT; return (-1); } } else { s = netdial(test->protocol, test->server_hostname, test->server_port); if (s < 0) { - // perror("netdial stream"); - i_errno = IECREATESTREAM; + i_errno = IESTREAMCONNECT; return (-1); } } if (test->protocol == Ptcp) { if (Nwrite(s, test->default_settings->cookie, COOKIE_SIZE, Ptcp) < 0) { - // perror("Nwrite COOKIE\n"); - i_errno = IESTREAMWRITE; + i_errno = IESENDCOOKIE; return (-1); } } else { /* Write to the UDP stream to give the server this stream's credentials */ if (write(s, &buf, sizeof(i)) < 0) { - // perror("write data"); + // XXX: Should this be changed to IESTREAMCONNECT? i_errno = IESTREAMWRITE; return (-1); } /* Wait until the server confirms the client UDP write */ // XXX: Should this read be TCP instead? if (read(s, &buf, sizeof(i)) < 0) { - // perror("read data"); i_errno = IESTREAMREAD; return (-1); } @@ -1028,7 +1035,6 @@ iperf_handle_message_client(struct iperf_test *test) i_errno = IECTRLCLOSE; return (-1); } else { - // perror("read ctrl_sck"); i_errno = IERECVMESSAGE; return (-1); } @@ -1044,7 +1050,8 @@ iperf_handle_message_client(struct iperf_test *test) return (-1); break; case TEST_START: - iperf_init_test(test); + if (iperf_init_test(test) < 0) + return (-1); break; case TEST_RUNNING: break; @@ -1058,16 +1065,12 @@ iperf_handle_message_client(struct iperf_test *test) case IPERF_DONE: break; case SERVER_TERMINATE: - // fprintf(stderr, "The server has terminated. Exiting...\n"); i_errno = IESERVERTERM; return (-1); case ACCESS_DENIED: - // fprintf(stderr, "The server is busy running a test. Try again later.\n"); - // exit(0); i_errno = IEACCESSDENIED; return (-1); default: - // printf("How did you get here? test->state = %d\n", test->state); i_errno = IEMESSAGE; return (-1); } @@ -1094,7 +1097,7 @@ iperf_connect(struct iperf_test *test) } if (Nwrite(test->ctrl_sck, test->default_settings->cookie, COOKIE_SIZE, Ptcp) < 0) { - i_errno = IECTRLWRITE; // XXX: should this set IECONNECT instead? + i_errno = IESENDCOOKIE; return (-1); } @@ -1357,7 +1360,6 @@ iperf_new_stream(struct iperf_test *testp) sp = (struct iperf_stream *) malloc(sizeof(struct iperf_stream)); if (!sp) { - // perror("malloc"); i_errno = IECREATESTREAM; return (NULL); } @@ -1368,17 +1370,14 @@ iperf_new_stream(struct iperf_test *testp) sp->result = (struct iperf_stream_result *) malloc(sizeof(struct iperf_stream_result)); if (!sp->buffer) { - // perror("Malloc sp->buffer"); i_errno = IECREATESTREAM; return (NULL); } if (!sp->settings) { - // perror("Malloc sp->settings"); i_errno = IECREATESTREAM; return (NULL); } if (!sp->result) { - // perror("Malloc sp->result"); i_errno = IECREATESTREAM; return (NULL); } @@ -1444,6 +1443,7 @@ iperf_init_stream(struct iperf_stream * sp, struct iperf_test * testp) // set_tcp_options(sp->socket, testp->no_delay, testp->default_settings->mss); } + return (0); } /**************************************************************************/ @@ -1484,11 +1484,11 @@ iperf_client_end(struct iperf_test *test) test->state = IPERF_DONE; if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - perror("Nwrite IPERF_DONE"); - return -1; + i_errno = IESENDMESSAGE; + return (-1); } - return 0; + return (0); } void @@ -1506,19 +1506,16 @@ iperf_run_client(struct iperf_test * test) /* Start the client and connect to the server */ if (iperf_connect(test) < 0) { - // set error and return return (-1); } // XXX: Do we need to check signal() for errors? signal(SIGINT, sig_handler); if (setjmp(env)) { - fprintf(stderr, "Exiting...\n"); test->state = CLIENT_TERMINATE; if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { i_errno = IESENDMESSAGE; return (-1); - // fprintf(stderr, "Unable to send CLIENT_TERMINATE message to server\n"); } exit(1); } @@ -1532,7 +1529,6 @@ iperf_run_client(struct iperf_test * test) result = select(test->max_fd + 1, &temp_read_set, &temp_write_set, NULL, &tv); if (result < 0 && errno != EINTR) { - // perror("select"); i_errno = IESELECT; return (-1); } else if (result > 0) { @@ -1556,11 +1552,13 @@ iperf_run_client(struct iperf_test * test) /* Perform callbacks */ if (timer_expired(test->stats_timer)) { test->stats_callback(test); - update_timer(test->stats_timer, test->stats_interval, 0); + if (update_timer(test->stats_timer, test->stats_interval, 0) < 0) + return (-1); } if (timer_expired(test->reporter_timer)) { test->reporter_callback(test); - update_timer(test->reporter_timer, test->reporter_interval, 0); + 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 */ @@ -1568,7 +1566,6 @@ iperf_run_client(struct iperf_test * test) test->stats_callback(test); test->state = TEST_END; if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - // perror("Nwrite TEST_END"); i_errno = IESENDMESSAGE; return (-1); } diff --git a/src/iperf_api.h b/src/iperf_api.h index 254d663..886ce66 100644 --- a/src/iperf_api.h +++ b/src/iperf_api.h @@ -131,7 +131,7 @@ 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 *); -void iperf_init_test(struct iperf_test *); +int iperf_init_test(struct iperf_test *); int iperf_parse_arguments(struct iperf_test *, int, char **); #endif diff --git a/src/iperf_error.c b/src/iperf_error.c index c6f05f3..1fa27a9 100644 --- a/src/iperf_error.c +++ b/src/iperf_error.c @@ -7,8 +7,175 @@ int i_errno; +char * +iperf_strerror(int i_errno) +{ + static char errstr[256]; + int len; + + len = sizeof(errstr); + memset(errstr, 0, len); + + switch (i_errno) { + case IENONE: + snprintf(errstr, len, "no error"); + break; + case IESERVCLIENT: + snprintf(errstr, len, "iperf cannot be both server and client"); + break; + case IENOROLE: + snprintf(errstr, len, "iperf instance must either be a client (-c) or server (-s)"); + break; + case IECLIENTONLY: + snprintf(errstr, len, "some option you are trying to set is client only"); + break; + case IEDURATION: + snprintf(errstr, len, "test duration too long (maximum = %d seconds)", MAX_TIME); + break; + case IENUMSTREAMS: + snprintf(errstr, len, "number of parallel streams too large (maximum = %d)", MAX_STREAMS); + break; + case IEBLOCKSIZE: + snprintf(errstr, len, "block size too large (maximum = %d bytes)", MAX_BLOCKSIZE); + break; + case IEBUFSIZE: + snprintf(errstr, len, "socket buffer size too large (maximum = %d bytes)", MAX_TCP_BUFFER); + break; + case IEINTERVAL: + snprintf(errstr, len, "report interval too large (maximum = %d seconds)", MAX_INTERVAL); + break; + case IEMSS: + snprintf(errstr, len, "TCP MSS too large (maximum = %d bytes)", MAX_MSS); + break; + case IENEWTEST: + snprintf(errstr, len, "unable to create a new test"); + break; + case IEINITTEST: + snprintf(errstr, len, "test initialization failed"); + break; + case IELISTEN: + snprintf(errstr, len, "unable to start listener for connections"); + break; + case IECONNECT: + snprintf(errstr, len, "unable to connect to server"); + break; + case IEACCEPT: + snprintf(errstr, len, "unable to accept connection from client"); + break; + case IESENDCOOKIE: + snprintf(errstr, len, "unable to send cookie to server"); + break; + case IERECVCOOKIE: + snprintf(errstr, len, "unable to receive cookie to server"); + break; + case IECTRLWRITE: + snprintf(errstr, len, "unable to write to the control socket"); + break; + case IECTRLREAD: + snprintf(errstr, len, "unable to read from the control socket"); + break; + case IECTRLCLOSE: + snprintf(errstr, len, "control socket has closed unexpectedly"); + break; + case IEMESSAGE: + snprintf(errstr, len, "received an unknown control message"); + break; + case IESENDMESSAGE: + snprintf(errstr, len, "unable to send control message"); + break; + case IERECVMESSAGE: + snprintf(errstr, len, "unable to receive control message"); + break; + case IESENDPARAMS: + snprintf(errstr, len, "unable to send parameters to server"); + break; + case IERECVPARAMS: + snprintf(errstr, len, "unable to receive parameters from client"); + break; + case IEPACKAGERESULTS: + snprintf(errstr, len, "unable to package results"); + break; + case IESENDRESULTS: + snprintf(errstr, len, "unable to send results"); + break; + case IERECVRESULTS: + snprintf(errstr, len, "unable to receive results"); + break; + case IESELECT: + snprintf(errstr, len, "select failed"); + break; + case IESERVERTERM: + snprintf(errstr, len, "the server has terminated"); + break; + case IEACCESSDENIED: + snprintf(errstr, len, "the server is busy running a test. try again later."); + break; + case IESETNODELAY: + snprintf(errstr, len, "unable to set TCP NODELAY"); + break; + case IESETMSS: + snprintf(errstr, len, "unable to set TCP MSS"); + break; + case IEREUSEADDR: + snprintf(errstr, len, "unable to reuse address on socket"); + break; + case IENONBLOCKING: + snprintf(errstr, len, "unable to set socket to non-blocking"); + break; + case IESETWINDOWSIZE: + snprintf(errstr, len, "unable to set socket window size"); + break; + case IECREATESTREAM: + snprintf(errstr, len, "unable to create a new stream"); + break; + case IEINITSTREAM: + snprintf(errstr, len, "unable to initialize stream"); + break; + case IESTREAMCONNECT: + snprintf(errstr, len, "unable to connect stream"); + break; + case IESTREAMACCEPT: + snprintf(errstr, len, "unable to accept stream connection"); + break; + case IESTREAMWRITE: + snprintf(errstr, len, "unable to write to stream socket"); + break; + case IESTREAMREAD: + snprintf(errstr, len, "unable to read from stream socket"); + break; + case IESTREAMCLOSE: + snprintf(errstr, len, "stream socket has closed unexpectedly"); + break; + case IESTREAMID: + snprintf(errstr, len, "stream has an invalid id"); + break; + case IENEWTIMER: + snprintf(errstr, len, "unable to create new timer"); + break; + case IEUPDATETIMER: + snprintf(errstr, len, "unable to update timer"); + break; + } + + return (errstr); +} + void -ierror(char *estr) +iperf_error(char *estr) +{ + fprintf(stderr, "%s: ", estr); + fprintf(stderr, "%s", iperf_strerror(i_errno)); + if (errno) + fprintf(stderr, ": %s", strerror(errno)); + else if (h_errno) + fprintf(stderr, ": %s", hstrerror(h_errno)); + + fprintf(stderr, "\n"); +} + +/* +void +iperf_error(char *estr) { fprintf(stderr, "%s: ", estr); @@ -166,5 +333,90 @@ ierror(char *estr) else fprintf(stderr, "unable to receive control message\n"); break; + case IESENDCOOKIE: + if (errno) + fprintf(stderr, "unable to send cookie to server: %s\n", strerror(errno)); + else + fprintf(stderr, "unable to send cookie to server\n"); + break; + case IERECVCOOKIE: + if (errno) + fprintf(stderr, "unable to receive cookie to server: %s\n", strerror(errno)); + else + fprintf(stderr, "unable to receive cookie to server\n"); + break; + case IELISTEN: + if (errno) + fprintf(stderr, "unable to start listener for connections: %s\n", strerror(errno)); + else + fprintf(stderr, "unable to start listener for connections\n"); + break; + case IEACCEPT: + if (errno) + fprintf(stderr, "unable to accept connection from client: %s\n", strerror(errno)); + else if (h_errno) + fprintf(stderr, "unable to accept connection from client: %s\n", hstrerror(h_errno)); + else + fprintf(stderr, "unable to accept connection from client\n"); + break; + case IESETNODELAY: + if (errno) + fprintf(stderr, "unable to set TCP NODELAY: %s\n", strerror(errno)); + else + fprintf(stderr, "unable to set TCP NODELAY\n"); + break; + case IESETMSS: + if (errno) + fprintf(stderr, "unable to set TCP MSS: %s\n", strerror(errno)); + else + fprintf(stderr, "unable to set TCP MSS\n"); + break; + case IEREUSEADDR: + if (errno) + fprintf(stderr, "unable to reuse address on socket: %s\n", strerror(errno)); + else + fprintf(stderr, "unable to reuse address on socket\n"); + break; + case IESTREAMCONNECT: + if (errno) + fprintf(stderr, "unable to connect stream: %s\n", strerror(errno)); + else if (h_errno) + fprintf(stderr, "unable to connect stream: %s\n", hstrerror(h_errno)); + else + fprintf(stderr, "unable to connect stream\n"); + break; + case IESTREAMACCEPT: + if (errno) + fprintf(stderr, "unable to accept stream connection: %s\n", strerror(errno)); + else + fprintf(stderr, "unable to accept stream connection\n"); + break; + case IENONBLOCKING: + if (errno) + fprintf(stderr, "unable to set socket to non-blocking: %s\n", strerror(errno)); + else + fprintf(stderr, "unable to set socket to non-blocking\n"); + break; + case IEUPDATETIMER: + if (errno) + fprintf(stderr, "unable to update timer: %s\n", strerror(errno)); + else + fprintf(stderr, "unable to update timer\n"); + break; + case IENEWTIMER: + if (errno) + fprintf(stderr, "unable to create new timer: %s\n", strerror(errno)); + else + fprintf(stderr, "unable to create new timer\n"); + break; + case IEINITTEST: + if (errno) + fprintf(stderr, "test initialization failed: %s\n", strerror(errno)); + else + fprintf(stderr, "test initialization failed\n"); + break; } } + +*/ + diff --git a/src/iperf_error.h b/src/iperf_error.h index c8c19c5..3e79568 100644 --- a/src/iperf_error.h +++ b/src/iperf_error.h @@ -6,11 +6,15 @@ #ifndef __IPERF_ERROR_H #define __IPERF_ERROR_H -void ierror(char *); +void iperf_error(char *); + +char *iperf_strerror(int); extern int i_errno; enum { + /* Parameter errors */ + IENONE = 0, // No error IESERVCLIENT = 1, // Iperf cannot be both server and client IENOROLE = 2, // Iperf must either be a client (-c) or server (-s) IECLIENTONLY = 3, // This option is client only @@ -20,29 +24,48 @@ enum { IEBUFSIZE = 7, // Socket buffer size too large. Maximum value = %dMAX_TCP_BUFFER IEINTERVAL = 8, // Report interval too large. Maxumum value = %dMAX_INTERVAL IEMSS = 9, // MSS too large. Maximum value = %dMAX_MSS - IECTRLWRITE = 10, // Unable to write to the control socket (check perror) - IECTRLREAD = 11, // Unable to read from the control socket (check perror) - IECTRLCLOSE = 12, // Control socket has closed unexpectedly - IESTREAMWRITE = 13, // Unable to write to stream socket (check perror) - IESTREAMREAD = 14, // Unable to read from stream (check perror) - IESTREAMCLOSE = 15, // Stream has closed unexpectedly - IENEWTEST = 16, // Unable to create a new test (check perror) - IECONNECT = 17, // Unable to connect to server (check herror/perror) [from netdial] - IESELECT = 18, // Select failed (check perror) - IESENDPARAMS = 19, // Unable to send parameters to server (check perror) - IERECVPARAMS = 20, // Unable to receive parameters from client (check perror) - IECREATESTREAM = 21, // Unable to create a new stream (check herror/perror) - IEINITSTREAM = 22, // Unable to initialize stream (check herror/perror) - IESETWINDOWSIZE = 23, // Unable to set socket window size (check perror) - IEPACKAGERESULTS = 24, // Unable to package results (check perror) - IESENDRESULTS = 25, // Unable to send results to client/server (check perror) - IERECVRESULTS = 26, // Unable to receive results from client/server (check perror) - IESTREAMID = 27, // Stream has invalid ID - IESERVERTERM = 28, // The server has terminated - IEACCESSDENIED = 29, // The server is busy running a test. Try again later. - IEMESSAGE = 30, // Received an unknown message - IESENDMESSAGE = 31, // Unable to send control message to client/server (check perror) - IERECVMESSAGE = 32, // Unable to receive control message from client/server (check perror) + + /* Test errors */ + IENEWTEST = 10, // Unable to create a new test (check perror) + IEINITTEST = 11, // Test initialization failed (check perror) + IELISTEN = 12, // Unable to listen for connections (check perror) + IECONNECT = 13, // Unable to connect to server (check herror/perror) [from netdial] + IEACCEPT = 14, // Unable to accept connection from client (check herror/perror) + IESENDCOOKIE = 15, // Unable to send cookie to server (check perror) + IERECVCOOKIE = 16, // Unable to receive cookie from client (check perror) + IECTRLWRITE = 17, // Unable to write to the control socket (check perror) + IECTRLREAD = 18, // Unable to read from the control socket (check perror) + IECTRLCLOSE = 19, // Control socket has closed unexpectedly + IEMESSAGE = 20, // Received an unknown message + IESENDMESSAGE = 21, // Unable to send control message to client/server (check perror) + IERECVMESSAGE = 22, // Unable to receive control message from client/server (check perror) + IESENDPARAMS = 23, // Unable to send parameters to server (check perror) + IERECVPARAMS = 24, // Unable to receive parameters from client (check perror) + IEPACKAGERESULTS = 25, // Unable to package results (check perror) + IESENDRESULTS = 26, // Unable to send results to client/server (check perror) + IERECVRESULTS = 27, // Unable to receive results from client/server (check perror) + IESELECT = 28, // Select failed (check perror) + IESERVERTERM = 29, // The server has terminated + IEACCESSDENIED = 30, // The server is busy running a test. Try again later. + IESETNODELAY = 31, // Unable to set TCP NODELAY (check perror) + IESETMSS = 32, // Unable to set TCP MSS (check perror) + IEREUSEADDR = 33, // Unable to set reuse address on socket (check perror) + IENONBLOCKING = 34, // Unable to set socket to non-blocking (check perror) + IESETWINDOWSIZE = 35, // Unable to set socket window size (check perror) + + /* Stream errors */ + IECREATESTREAM = 36, // Unable to create a new stream (check herror/perror) + IEINITSTREAM = 37, // Unable to initialize stream (check herror/perror) + IESTREAMCONNECT = 38, // Unable to connect stream (check herror/perror) + IESTREAMACCEPT = 39, // Unable to accepte stream connection (check perror) + IESTREAMWRITE = 40, // Unable to write to stream socket (check perror) + IESTREAMREAD = 41, // Unable to read from stream (check perror) + IESTREAMCLOSE = 42, // Stream has closed unexpectedly + IESTREAMID = 43, // Stream has invalid ID + + /* Timer errors */ + IENEWTIMER = 44, // Unable to create new timer (check perror) + IEUPDATETIMER = 45, // Unable to update timer (check perror) }; #endif diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c index a6fccc5..a73481c 100644 --- a/src/iperf_server_api.c +++ b/src/iperf_server_api.c @@ -35,6 +35,7 @@ #include "iperf_api.h" #include "iperf_udp.h" #include "iperf_tcp.h" +#include "iperf_error.h" #include "timer.h" #include "net.h" #include "units.h" @@ -51,9 +52,8 @@ iperf_server_listen(struct iperf_test *test) int x; if((test->listener_tcp = netannounce(Ptcp, NULL, test->server_port)) < 0) { - // Needs to set some sort of error number/message - perror("netannounce test->listener_tcp"); - return -1; + i_errno = IELISTEN; + return (-1); } printf("-----------------------------------------------------------\n"); @@ -95,83 +95,68 @@ iperf_accept(struct iperf_test *test) { int s; int rbuf = ACCESS_DENIED; - char ipl[512], ipr[512]; + char ipl[512], ipr[512]; // XXX: This is overkill. Max length of IPv6 address = 46 (INET6_ADDRSTRLEN) char cookie[COOKIE_SIZE]; socklen_t len; struct sockaddr_in addr; struct sockaddr_in temp1, temp2; - struct iperf_stream *sp; - static int streams_accepted; len = sizeof(addr); if ((s = accept(test->listener_tcp, (struct sockaddr *) &addr, &len)) < 0) { - perror("accept"); - return -1; + i_errno = IEACCEPT; + return (-1); } if (test->ctrl_sck == -1) { /* Server free, accept new client */ if (Nread(s, test->default_settings->cookie, COOKIE_SIZE, Ptcp) < 0) { - perror("Nread COOKIE\n"); - return -1; + i_errno = IERECVCOOKIE; + return (-1); } FD_SET(s, &test->read_set); FD_SET(s, &test->write_set); test->max_fd = (s > test->max_fd) ? s : test->max_fd; test->ctrl_sck = s; - streams_accepted = 0; len = sizeof(struct sockaddr_in); - if (getsockname(s, (struct sockaddr *) &temp1, &len) < 0) - perror("getsockname"); - if (getpeername(s, (struct sockaddr *) &temp2, &len) < 0) - perror("getpeername"); + if (getsockname(s, (struct sockaddr *) &temp1, &len) < 0) { + i_errno = IEACCEPT; + return (-1); + } + if (getpeername(s, (struct sockaddr *) &temp2, &len) < 0) { + i_errno = IEACCEPT; + return (-1); + } + // XXX: Check inet_ntop for errors? inet_ntop(AF_INET, (void *) &temp1.sin_addr, ipl, sizeof(ipl)); inet_ntop(AF_INET, (void *) &temp2.sin_addr, ipr, sizeof(ipr)); + printf(report_peer, s, ipl, ntohs(temp1.sin_port), ipr, ntohs(temp2.sin_port)); test->state = PARAM_EXCHANGE; if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - perror("Nwrite PARAM_EXCHANGE\n"); - exit(1); + i_errno = IESENDMESSAGE; + return (-1); + } + if (iperf_exchange_parameters(test) < 0) { + return (-1); } - iperf_exchange_parameters(test); } else { + // XXX: Do we even need to receive cookie if we're just going to deny anyways? if (Nread(s, cookie, COOKIE_SIZE, Ptcp) < 0) { - perror("Nread COOKIE\n"); - return -1; + i_errno = IERECVCOOKIE; + return (-1); } - if ((strcmp(test->default_settings->cookie, cookie) == 0) && (test->state == CREATE_STREAMS)) { - sp = test->new_stream(test); - sp->socket = s; - iperf_init_stream(sp, test); - iperf_add_stream(test, sp); - FD_SET(s, &test->read_set); - FD_SET(s, &test->write_set); - test->max_fd = (s > test->max_fd) ? s : test->max_fd; - connect_msg(sp); - - ++streams_accepted; - if (streams_accepted == test->num_streams) { - test->state = TEST_START; - if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - perror("Nwrite TEST_START\n"); - return -1; - } - } - - } else { - if (Nwrite(s, &rbuf, sizeof(int), Ptcp) < 0) { - perror("Nwrite ACCESS_DENIED"); - return -1; - } - close(s); + if (Nwrite(s, &rbuf, sizeof(int), Ptcp) < 0) { + i_errno = IESENDMESSAGE; + return (-1); } + close(s); } - return 0; + return (0); } @@ -187,20 +172,23 @@ iperf_accept_tcp_stream(struct iperf_test *test) len = sizeof(addr); if ((s = accept(test->listener_tcp, (struct sockaddr *) &addr, &len)) < 0) { - perror("accept tcp stream"); + i_errno = IESTREAMCONNECT; return (-1); } if (Nread(s, cookie, COOKIE_SIZE, Ptcp) < 0) { - perror("Nread cookie"); + i_errno = IERECVCOOKIE; return (-1); } if (strcmp(test->default_settings->cookie, cookie) == 0) { - // XXX: CANNOT USE iperf_tcp_accept since stream is alread accepted at this point. New model needed! + // XXX: CANNOT USE iperf_tcp_accept since stream is already accepted at this point. New model needed! sp = test->new_stream(test); + if (!sp) + return (-1); sp->socket = s; - iperf_init_stream(sp, test); + if (iperf_init_stream(sp, test) < 0) + return (-1); iperf_add_stream(test, sp); FD_SET(s, &test->read_set); FD_SET(s, &test->write_set); @@ -209,7 +197,7 @@ iperf_accept_tcp_stream(struct iperf_test *test) connect_msg(sp); } else { if (Nwrite(s, &rbuf, sizeof(char), Ptcp) < 0) { - perror("Nwrite ACCESS_DENIED"); + i_errno = IESENDMESSAGE; return (-1); } close(s); @@ -217,14 +205,6 @@ iperf_accept_tcp_stream(struct iperf_test *test) return (0); } - -int -iperf_accept_udp_stream(struct iperf_test *test) -{ - // do nothing for now - return (0); -} - /**************************************************************************/ int iperf_handle_message_server(struct iperf_test *test) @@ -232,14 +212,16 @@ iperf_handle_message_server(struct iperf_test *test) int rval; struct iperf_stream *sp; - if ((rval = read(test->ctrl_sck, &test->state, sizeof(char))) <= 0) { + // XXX: Need to rethink how this behaves to fit API + if ((rval = Nread(test->ctrl_sck, &test->state, sizeof(char), Ptcp)) <= 0) { if (rval == 0) { fprintf(stderr, "The client has unexpectedly closed the connection.\n"); + i_errno = IECTRLCLOSE; test->state = IPERF_DONE; - return 0; + return (0); } else { - perror("read ctrl_sck"); - return -1; + i_errno = IERECVMESSAGE; + return (-1); } } @@ -255,14 +237,15 @@ iperf_handle_message_server(struct iperf_test *test) } test->state = EXCHANGE_RESULTS; if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - perror("Nwrite EXCHANGE_RESULTS"); - exit(1); + i_errno = IESENDMESSAGE; + return (-1); } - iperf_exchange_results(test); + if (iperf_exchange_results(test) < 0) + return (-1); test->state = DISPLAY_RESULTS; if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - perror("Nwrite DISPLAY_RESULTS"); - exit(1); + i_errno = IESENDMESSAGE; + return (-1); } test->reporter_callback(test); break; @@ -278,12 +261,11 @@ iperf_handle_message_server(struct iperf_test *test) test->state = IPERF_DONE; break; default: - // XXX: This needs to be replaced by actual error handling - fprintf(stderr, "Unrecognized state: %d\n", test->state); - return -1; + i_errno = IEMESSAGE; + return (-1); } - return 0; + return (0); } void @@ -344,18 +326,16 @@ iperf_run_server(struct iperf_test *test) // Open socket and listen if (iperf_server_listen(test) < 0) { - // XXX: This needs to be replaced by more formal error handling - fprintf(stderr, "An error occurred. Exiting.\n"); - exit(1); + return (-1); } signal(SIGINT, sig_handler); if (setjmp(env)) { - fprintf(stderr, "Exiting...\n"); test->state = SERVER_TERMINATE; if (test->ctrl_sck >= 0) { if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - fprintf(stderr, "Unable to send SERVER_TERMINATE message to client\n"); + i_errno = IESENDMESSAGE; + return (-1); } } return 0; @@ -374,21 +354,20 @@ iperf_run_server(struct iperf_test *test) 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); + i_errno = IESELECT; + return (-1); } else if (result > 0) { if (FD_ISSET(test->listener_tcp, &temp_read_set)) { if (test->state != CREATE_STREAMS) { if (iperf_accept(test) < 0) { - fprintf(stderr, "iperf_accept: error accepting control socket. exiting...\n"); - exit(1); + return (-1); } FD_CLR(test->listener_tcp, &temp_read_set); } } if (FD_ISSET(test->ctrl_sck, &temp_read_set)) { - iperf_handle_message_server(test); + if (iperf_handle_message_server(test) < 0) + return (-1); FD_CLR(test->ctrl_sck, &temp_read_set); } @@ -396,16 +375,14 @@ iperf_run_server(struct iperf_test *test) if (test->protocol == Ptcp) { if (FD_ISSET(test->listener_tcp, &temp_read_set)) { if (iperf_accept_tcp_stream(test) < 0) { - fprintf(stderr, "iperf_accept_tcp_stream: an error occurred.\n"); - exit(1); + return (-1); } FD_CLR(test->listener_tcp, &temp_read_set); } } else { if (FD_ISSET(test->listener_udp, &temp_read_set)) { if (iperf_udp_accept(test) < 0) { - fprintf(stderr, "iperf_accept_udp_stream: an error occurred.\n"); - exit(1); + return (-1); } FD_CLR(test->listener_udp, &temp_read_set); } @@ -420,7 +397,7 @@ iperf_run_server(struct iperf_test *test) FD_CLR(test->listener_tcp, &test->read_set); close(test->listener_tcp); if ((s = netannounce(Ptcp, NULL, test->server_port)) < 0) { - perror("reconnect tcp listener"); + i_errno = IELISTEN; return (-1); } test->listener_tcp = s; @@ -430,14 +407,15 @@ iperf_run_server(struct iperf_test *test) } test->state = TEST_START; if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - perror("Nwrite TEST_START"); - return -1; + i_errno = IESENDMESSAGE; + return (-1); } - iperf_init_test(test); + if (iperf_init_test(test) < 0) + return (-1); test->state = TEST_RUNNING; if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - perror("Nwrite TEST_RUNNING"); - return -1; + i_errno = IESENDMESSAGE; + return (-1); } } } @@ -445,20 +423,24 @@ iperf_run_server(struct iperf_test *test) if (test->state == TEST_RUNNING) { if (test->reverse) { // Reverse mode. Server sends. - iperf_send(test); + if (iperf_send(test) < 0) + return (-1); } else { // Regular mode. Server receives. - iperf_recv(test); + if (iperf_recv(test) < 0) + return (-1); } /* Perform callbacks */ if (timer_expired(test->stats_timer)) { test->stats_callback(test); - update_timer(test->stats_timer, test->stats_interval, 0); + if (update_timer(test->stats_timer, test->stats_interval, 0) < 0) + return (-1); } if (timer_expired(test->reporter_timer)) { test->reporter_callback(test); - update_timer(test->reporter_timer, test->reporter_interval, 0); + if (update_timer(test->reporter_timer, test->reporter_interval, 0) < 0) + return (-1); } } } @@ -470,6 +452,6 @@ iperf_run_server(struct iperf_test *test) } - return 0; + return (0); } diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c index 74b9aef..d015d2c 100644 --- a/src/iperf_tcp.c +++ b/src/iperf_tcp.c @@ -55,10 +55,6 @@ iperf_tcp_recv(struct iperf_stream * sp) int result = 0; int size = sp->settings->blksize; - if (!sp->buffer) { - fprintf(stderr, "iperf_tcp_recv: receive buffer not allocated\n"); - return -1; - } #ifdef USE_RECV /* * NOTE: Nwrite/Nread seems to be 10-15% faster than send/recv for @@ -70,9 +66,8 @@ iperf_tcp_recv(struct iperf_stream * sp) #else result = Nread(sp->socket, sp->buffer, size, Ptcp); #endif - if (result == -1) { - perror("Read error"); - return -1; + if (result < 0) { + return (-1); } sp->result->bytes_received += result; sp->result->bytes_received_this_interval += result; @@ -94,18 +89,14 @@ iperf_tcp_send(struct iperf_stream * sp) int result; int size = sp->settings->blksize; - if (!sp->buffer) { - fprintf(stderr, "iperf_tcp_send: transmit buffer not allocated\n"); - return -1; - } - #ifdef USE_SEND result = send(sp->socket, sp->buffer, size, 0); #else result = Nwrite(sp->socket, sp->buffer, size, Ptcp); #endif - if (result < 0) - perror("Nwrite error"); + if (result < 0) { + return (-1); + } sp->result->bytes_sent += result; sp->result->bytes_sent_this_interval += result; @@ -121,7 +112,6 @@ iperf_new_tcp_stream(struct iperf_test * testp) sp = (struct iperf_stream *) iperf_new_stream(testp); if (!sp) { - perror("malloc"); return (NULL); } sp->rcv = iperf_tcp_recv; /* pointer to receive function */ @@ -135,7 +125,7 @@ iperf_new_tcp_stream(struct iperf_test * testp) /**************************************************************************/ -/** +/** XXX: This function is not currently in use! * iperf_tcp_accept -- accepts a new TCP connection * on tcp_listener_socket for TCP data and param/result * exchange messages @@ -159,9 +149,6 @@ iperf_tcp_accept(struct iperf_test * test) return -1; } - // XXX: Nonblocking off. OKAY since we use select. - // setnonblocking(peersock); - // XXX: This doesn't fit our API model! sp = test->new_stream(test); sp->socket = peersock; diff --git a/src/iperf_udp.c b/src/iperf_udp.c index ad7a936..a175a0a 100644 --- a/src/iperf_udp.c +++ b/src/iperf_udp.c @@ -36,6 +36,7 @@ #include "iperf.h" #include "iperf_api.h" #include "iperf_udp.h" +#include "iperf_error.h" #include "timer.h" #include "net.h" #include "locale.h" @@ -68,7 +69,6 @@ iperf_udp_recv(struct iperf_stream *sp) #endif if (result < 0) { - perror("Nread udp result"); return (-1); } sp->result->bytes_received += result; @@ -95,9 +95,8 @@ iperf_udp_recv(struct iperf_stream *sp) } /* jitter measurement */ - if (gettimeofday(&arrival_time, NULL) < 0) { - perror("gettimeofday"); - } + gettimeofday(&arrival_time, NULL); + transit = timeval_diff(&sent_time, &arrival_time); d = transit - sp->prev_transit; if (d < 0) @@ -129,8 +128,8 @@ iperf_udp_send(struct iperf_stream *sp) assert(dtargus != 0); - if (gettimeofday(&before, 0) < 0) - perror("gettimeofday"); + gettimeofday(&before, 0); + ++sp->packet_count; sec = htonl(before.tv_sec); usec = htonl(before.tv_usec); @@ -147,13 +146,12 @@ iperf_udp_send(struct iperf_stream *sp) #endif if (result < 0) - perror("Nwrite udp error"); + return (-1); sp->result->bytes_sent += result; sp->result->bytes_sent_this_interval += result; - if (gettimeofday(&after, 0) < 0) - perror("gettimeofday"); + gettimeofday(&after, 0); adjustus = dtargus; adjustus += (before.tv_sec - after.tv_sec) * SEC_TO_US; @@ -163,7 +161,8 @@ iperf_udp_send(struct iperf_stream *sp) dtargus = adjustus; } - update_timer(sp->send_timer, 0, dtargus); + if (update_timer(sp->send_timer, 0, dtargus) < 0) + return (-1); } return result; @@ -177,7 +176,6 @@ iperf_new_udp_stream(struct iperf_test * testp) sp = (struct iperf_stream *) iperf_new_stream(testp); if (!sp) { - perror("malloc"); return (NULL); } sp->rcv = iperf_udp_recv; @@ -209,41 +207,44 @@ iperf_udp_accept(struct iperf_test *test) len = sizeof sa_peer; if ((sz = recvfrom(test->listener_udp, &buf, sizeof(buf), 0, (struct sockaddr *) &sa_peer, &len)) < 0) { - perror("recvfrom in udp accept"); + i_errno = IESTREAMACCEPT; return (-1); } if (connect(s, (struct sockaddr *) &sa_peer, len) < 0) { - perror("iperf_udp_accept: connect error"); - return -1; + i_errno = IESTREAMACCEPT; + return (-1); } sp = test->new_stream(test); if (!sp) return (-1); sp->socket = s; - iperf_init_stream(sp, test); + if (iperf_init_stream(sp, test) < 0) + return (-1); iperf_add_stream(test, sp); FD_SET(s, &test->read_set); FD_SET(s, &test->write_set); test->max_fd = (s > test->max_fd) ? s : test->max_fd; test->listener_udp = netannounce(Pudp, NULL, test->server_port); - if (test->listener_udp < 0) - return -1; + if (test->listener_udp < 0) { + i_errno = IELISTEN; + return (-1); + } FD_SET(test->listener_udp, &test->read_set); test->max_fd = (test->max_fd < test->listener_udp) ? test->listener_udp : test->max_fd; /* Let the client know we're ready "accept" another UDP "stream" */ if (write(sp->socket, &buf, sizeof(buf)) < 0) { - perror("write listen message"); - return -1; + i_errno = IESTREAMWRITE; + return (-1); } connect_msg(sp); test->streams_accepted++; - return 0; + return (0); } diff --git a/src/main.c b/src/main.c index 55f8f40..5560ce5 100644 --- a/src/main.c +++ b/src/main.c @@ -77,20 +77,20 @@ main(int argc, char **argv) test = iperf_new_test(); if (!test) { - ierror("create new test error"); + iperf_error("create new test error"); exit(1); } iperf_defaults(test); /* sets defaults */ if (iperf_parse_arguments(test, argc, argv) < 0) { - ierror("parameter error"); + iperf_error("parameter error"); fprintf(stderr, "\n"); usage_long(); exit(1); } if (iperf_run(test) < 0) { - ierror("error"); + iperf_error("error"); exit(1); } diff --git a/src/net.c b/src/net.c index b44f30a..3e60b81 100644 --- a/src/net.c +++ b/src/net.c @@ -29,13 +29,11 @@ netdial(int proto, char *client, int port) /* XXX: This is not working for non-fully qualified host names use getaddrinfo() instead? */ if ((hent = gethostbyname(client)) == 0) { - // perror("gethostbyname"); return (-1); } s = socket(AF_INET, proto, 0); if (s < 0) { - // perror("socket"); return (-1); } @@ -45,7 +43,6 @@ netdial(int proto, char *client, int port) sa.sin_family = AF_INET; if (connect(s, (struct sockaddr *) & sa, sizeof sa) < 0 && errno != EINPROGRESS) { - // perror("netdial: connect error"); return (-1); } @@ -53,7 +50,6 @@ netdial(int proto, char *client, int port) // XXX: Is there a reason to call getpeername() if none of the return values are used? if (getpeername(s, (struct sockaddr *) & sa, &sn) < 0) { - // perror("getpeername error"); return (-1); } @@ -73,7 +69,6 @@ netannounce(int proto, char *local, int port) s = socket(AF_INET, proto, 0); if (s < 0) { - perror("socket"); return (-1); } int opt = 1; @@ -84,12 +79,14 @@ netannounce(int proto, char *local, int port) if (bind(s, (struct sockaddr *) & sa, sizeof(struct sockaddr_in)) < 0) { close(s); - perror("bind"); return (-1); } - if (proto == SOCK_STREAM) - listen(s, 5); + if (proto == SOCK_STREAM) { + if (listen(s, 5) < 0) { + return (-1); + } + } return s; } @@ -195,6 +192,7 @@ getsock_tcp_mss(int inSock) /*************************************************************/ /* sets TCP_NODELAY and TCP_MAXSEG if requested */ +// XXX: This function is not being used. int set_tcp_options(int sock, int no_delay, int mss) @@ -244,6 +242,7 @@ set_tcp_options(int sock, int no_delay, int mss) /****************************************************************************/ +// XXX: This function is not being used. int setnonblocking(int sock) { diff --git a/src/timer.c b/src/timer.c index 2681825..fe79c4a 100644 --- a/src/timer.c +++ b/src/timer.c @@ -8,6 +8,7 @@ #include #include "timer.h" +#include "iperf_error.h" double timeval_to_double(struct timeval * tv) @@ -34,10 +35,7 @@ timer_expired(struct timer * tp) struct timeval now; int64_t end = 0, current = 0; - if (gettimeofday(&now, NULL) < 0) { - perror("gettimeofday"); - return -1; - } + gettimeofday(&now, NULL); end += tp->end.tv_sec * 1000000; end += tp->end.tv_usec; @@ -48,17 +46,19 @@ timer_expired(struct timer * tp) return current > end; } -void +int update_timer(struct timer * tp, time_t sec, suseconds_t usec) { if (gettimeofday(&tp->begin, NULL) < 0) { - perror("gettimeofday"); + i_errno = IEUPDATETIMER; + return (-1); } tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; tp->end.tv_usec = tp->begin.tv_usec + (time_t) usec; tp->expired = timer_expired; + return (0); } struct timer * @@ -67,13 +67,13 @@ new_timer(time_t sec, suseconds_t usec) struct timer *tp = NULL; tp = (struct timer *) calloc(1, sizeof(struct timer)); if (tp == NULL) { - perror("malloc"); - return NULL; + i_errno = IENEWTIMER; + return (NULL); } if (gettimeofday(&tp->begin, NULL) < 0) { - perror("gettimeofday"); - return NULL; + i_errno = IENEWTIMER; + return (NULL); } tp->end.tv_sec = tp->begin.tv_sec + (time_t) sec; @@ -131,10 +131,7 @@ timer_remaining(struct timer * tp) struct timeval now; long int end_time = 0, current_time = 0, diff = 0; - if (gettimeofday(&now, NULL) < 0) { - perror("gettimeofday"); - return -1; - } + gettimeofday(&now, NULL); end_time += tp->end.tv_sec * 1000000; end_time += tp->end.tv_usec; diff --git a/src/timer.h b/src/timer.h index 4c6faff..0a73290 100644 --- a/src/timer.h +++ b/src/timer.h @@ -18,7 +18,7 @@ double timeval_to_double(struct timeval *tv); double timeval_diff(struct timeval *tv0, struct timeval *tv1); -void update_timer(struct timer *tp, time_t sec, suseconds_t usec); +int update_timer(struct timer *tp, time_t sec, suseconds_t usec); int64_t timer_remaining(struct timer *tp);