diff --git a/src/iperf_api.c b/src/iperf_api.c index 62d68c2..c47fa38 100644 --- a/src/iperf_api.c +++ b/src/iperf_api.c @@ -26,7 +26,6 @@ #include #include #include -#include #include #include "net.h" diff --git a/src/iperf_client_api.c b/src/iperf_client_api.c index 88c6b35..41732a2 100644 --- a/src/iperf_client_api.c +++ b/src/iperf_client_api.c @@ -1,6 +1,5 @@ #include #include -#include #include #include #include @@ -169,17 +168,6 @@ iperf_run_client(struct iperf_test * test) 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)); diff --git a/src/iperf_error.c b/src/iperf_error.c index 4b2bb35..7186920 100644 --- a/src/iperf_error.c +++ b/src/iperf_error.c @@ -11,172 +11,213 @@ char * iperf_strerror(int i_errno) { static char errstr[256]; - int len; + int len, perr, herr; + perr = herr = 0; len = sizeof(errstr); memset(errstr, 0, len); switch (i_errno) { case IENONE: - snprintf(errstr, len, "no error"); + snprintf(errstr, len, "No error"); break; case IESERVCLIENT: - snprintf(errstr, len, "iperf cannot be both server and client"); + 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)"); + 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"); + 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); + 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); + 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); + 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); + 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); + 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"); + snprintf(errstr, len, "Unable to create a new test"); + perr = 1; break; case IEINITTEST: - snprintf(errstr, len, "test initialization failed"); + snprintf(errstr, len, "Test initialization failed"); + perr = 1; break; case IELISTEN: - snprintf(errstr, len, "unable to start listener for connections"); + snprintf(errstr, len, "Unable to start listener for connections"); + perr = 1; break; case IECONNECT: - snprintf(errstr, len, "unable to connect to server"); + snprintf(errstr, len, "Unable to connect to server"); + herr = 1; + perr = 1; break; case IEACCEPT: - snprintf(errstr, len, "unable to accept connection from client"); + snprintf(errstr, len, "Unable to accept connection from client"); + herr = 1; + perr = 1; break; case IESENDCOOKIE: - snprintf(errstr, len, "unable to send cookie to server"); + snprintf(errstr, len, "Unable to send cookie to server"); + perr = 1; break; case IERECVCOOKIE: - snprintf(errstr, len, "unable to receive cookie to server"); + snprintf(errstr, len, "Unable to receive cookie to server"); + perr = 1; break; case IECTRLWRITE: - snprintf(errstr, len, "unable to write to the control socket"); + snprintf(errstr, len, "Unable to write to the control socket"); + perr = 1; break; case IECTRLREAD: - snprintf(errstr, len, "unable to read from the control socket"); + snprintf(errstr, len, "Unable to read from the control socket"); + perr = 1; break; case IECTRLCLOSE: - snprintf(errstr, len, "control socket has closed unexpectedly"); + snprintf(errstr, len, "Control socket has closed unexpectedly"); break; case IEMESSAGE: - snprintf(errstr, len, "received an unknown control message"); + snprintf(errstr, len, "Received an unknown control message"); break; case IESENDMESSAGE: - snprintf(errstr, len, "unable to send control message"); + snprintf(errstr, len, "Unable to send control message"); + perr = 1; break; case IERECVMESSAGE: - snprintf(errstr, len, "unable to receive control message"); + snprintf(errstr, len, "Unable to receive control message"); + perr = 1; break; case IESENDPARAMS: - snprintf(errstr, len, "unable to send parameters to server"); + snprintf(errstr, len, "Unable to send parameters to server"); + perr = 1; break; case IERECVPARAMS: - snprintf(errstr, len, "unable to receive parameters from client"); + snprintf(errstr, len, "Unable to receive parameters from client"); + perr = 1; break; case IEPACKAGERESULTS: - snprintf(errstr, len, "unable to package results"); + snprintf(errstr, len, "Unable to package results"); + perr = 1; break; case IESENDRESULTS: - snprintf(errstr, len, "unable to send results"); + snprintf(errstr, len, "Unable to send results"); + perr = 1; break; case IERECVRESULTS: - snprintf(errstr, len, "unable to receive results"); + snprintf(errstr, len, "Unable to receive results"); + perr = 1; break; case IESELECT: - snprintf(errstr, len, "select failed"); + snprintf(errstr, len, "Select failed"); + perr = 1; + break; + case IECLIENTTERM: + snprintf(errstr, len, "The client has terminated"); break; case IESERVERTERM: - snprintf(errstr, len, "the server has terminated"); + snprintf(errstr, len, "The server has terminated"); break; case IEACCESSDENIED: - snprintf(errstr, len, "the server is busy running a test. try again later."); + snprintf(errstr, len, "The server is busy running a test. try again later."); break; case IESETNODELAY: - snprintf(errstr, len, "unable to set TCP NODELAY"); + snprintf(errstr, len, "Unable to set TCP NODELAY"); + perr = 1; break; case IESETMSS: - snprintf(errstr, len, "unable to set TCP MSS"); + snprintf(errstr, len, "Unable to set TCP MSS"); + perr = 1; break; case IEREUSEADDR: - snprintf(errstr, len, "unable to reuse address on socket"); + snprintf(errstr, len, "Unable to reuse address on socket"); + perr = 1; break; case IENONBLOCKING: - snprintf(errstr, len, "unable to set socket to non-blocking"); + snprintf(errstr, len, "Unable to set socket to non-blocking"); + perr = 1; break; case IESETWINDOWSIZE: - snprintf(errstr, len, "unable to set socket window size"); + snprintf(errstr, len, "Unable to set socket window size"); + perr = 1; break; case IEPROTOCOL: - snprintf(errstr, len, "protocol does not exist"); + snprintf(errstr, len, "Protocol does not exist"); break; case IECREATESTREAM: - snprintf(errstr, len, "unable to create a new stream"); + snprintf(errstr, len, "Unable to create a new stream"); + herr = 1; + perr = 1; break; case IEINITSTREAM: - snprintf(errstr, len, "unable to initialize stream"); + snprintf(errstr, len, "Unable to initialize stream"); + herr = 1; + perr = 1; break; case IESTREAMLISTEN: - snprintf(errstr, len, "unable to start stream listener"); + snprintf(errstr, len, "Unable to start stream listener"); + perr = 1; break; case IESTREAMCONNECT: - snprintf(errstr, len, "unable to connect stream"); + snprintf(errstr, len, "Unable to connect stream"); + herr = 1; + perr = 1; break; case IESTREAMACCEPT: - snprintf(errstr, len, "unable to accept stream connection"); + snprintf(errstr, len, "Unable to accept stream connection"); + perr = 1; break; case IESTREAMWRITE: - snprintf(errstr, len, "unable to write to stream socket"); + snprintf(errstr, len, "Unable to write to stream socket"); + perr = 1; break; case IESTREAMREAD: - snprintf(errstr, len, "unable to read from stream socket"); + snprintf(errstr, len, "Unable to read from stream socket"); + perr = 1; break; case IESTREAMCLOSE: - snprintf(errstr, len, "stream socket has closed unexpectedly"); + snprintf(errstr, len, "Stream socket has closed unexpectedly"); break; case IESTREAMID: - snprintf(errstr, len, "stream has an invalid id"); + snprintf(errstr, len, "Stream has an invalid id"); break; case IENEWTIMER: - snprintf(errstr, len, "unable to create new timer"); + snprintf(errstr, len, "Unable to create new timer"); + perr = 1; break; case IEUPDATETIMER: - snprintf(errstr, len, "unable to update timer"); + snprintf(errstr, len, "Unable to update timer"); + perr = 1; break; } + if (herr || perr) + strncat(errstr, ": ", len); + if (h_errno && herr) { + strncat(errstr, hstrerror(h_errno), len); + } else if (errno && perr) { + strncat(errstr, strerror(errno), len); + } + return (errstr); } void 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"); + fprintf(stderr, "%s: %s\n", estr, iperf_strerror(i_errno)); } /* diff --git a/src/iperf_error.h b/src/iperf_error.h index 3418bf4..deb1cdc 100644 --- a/src/iperf_error.h +++ b/src/iperf_error.h @@ -46,29 +46,30 @@ enum { 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) - IEPROTOCOL = 36, // Protocol does not exist + IECLIENTTERM = 29, // The client has terminated + IESERVERTERM = 30, // The server has terminated + IEACCESSDENIED = 31, // The server is busy running a test. Try again later. + IESETNODELAY = 32, // Unable to set TCP NODELAY (check perror) + IESETMSS = 33, // Unable to set TCP MSS (check perror) + IEREUSEADDR = 34, // Unable to set reuse address on socket (check perror) + IENONBLOCKING = 35, // Unable to set socket to non-blocking (check perror) + IESETWINDOWSIZE = 36, // Unable to set socket window size (check perror) + IEPROTOCOL = 37, // Protocol does not exist /* Stream errors */ - IECREATESTREAM = 37, // Unable to create a new stream (check herror/perror) - IEINITSTREAM = 38, // Unable to initialize stream (check herror/perror) - IESTREAMLISTEN = 39, // Unable to start stream listener (check perror) - IESTREAMCONNECT = 40, // Unable to connect stream (check herror/perror) - IESTREAMACCEPT = 41, // Unable to accepte stream connection (check perror) - IESTREAMWRITE = 42, // Unable to write to stream socket (check perror) - IESTREAMREAD = 43, // Unable to read from stream (check perror) - IESTREAMCLOSE = 44, // Stream has closed unexpectedly - IESTREAMID = 45, // Stream has invalid ID + IECREATESTREAM = 38, // Unable to create a new stream (check herror/perror) + IEINITSTREAM = 39, // Unable to initialize stream (check herror/perror) + IESTREAMLISTEN = 40, // Unable to start stream listener (check perror) + IESTREAMCONNECT = 41, // Unable to connect stream (check herror/perror) + IESTREAMACCEPT = 42, // Unable to accepte stream connection (check perror) + IESTREAMWRITE = 43, // Unable to write to stream socket (check perror) + IESTREAMREAD = 44, // Unable to read from stream (check perror) + IESTREAMCLOSE = 45, // Stream has closed unexpectedly + IESTREAMID = 46, // Stream has invalid ID /* Timer errors */ - IENEWTIMER = 46, // Unable to create new timer (check perror) - IEUPDATETIMER = 47, // Unable to update timer (check perror) + IENEWTIMER = 47, // Unable to create new timer (check perror) + IEUPDATETIMER = 48, // Unable to update timer (check perror) }; #endif diff --git a/src/iperf_server_api.c b/src/iperf_server_api.c index e11cdc2..31f76de 100644 --- a/src/iperf_server_api.c +++ b/src/iperf_server_api.c @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -195,6 +194,9 @@ iperf_handle_message_server(struct iperf_test *test) case IPERF_DONE: break; case CLIENT_TERMINATE: + i_errno = IECLIENTTERM; + + // XXX: Remove this line below! fprintf(stderr, "The client has terminated.\n"); for (sp = test->streams; sp; sp = sp->next) { FD_CLR(sp->socket, &test->read_set); @@ -272,18 +274,6 @@ iperf_run_server(struct iperf_test *test) return (-1); } - signal(SIGINT, sig_handler); - if (setjmp(env)) { - test->state = SERVER_TERMINATE; - if (test->ctrl_sck >= 0) { - if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { - i_errno = IESENDMESSAGE; - return (-1); - } - } - return (0); - } - for ( ; ; ) { test->state = IPERF_START; diff --git a/src/main.c b/src/main.c index c05a426..0ea0269 100644 --- a/src/main.c +++ b/src/main.c @@ -82,6 +82,19 @@ main(int argc, char **argv) } iperf_defaults(test); /* sets defaults */ + // XXX: Check signal for errors? + signal(SIGINT, sig_handler); + if (setjmp(env)) { + if (test->ctrl_sck >= 0) { + test->state = (test->role == 'c') ? CLIENT_TERMINATE : SERVER_TERMINATE; + if (Nwrite(test->ctrl_sck, &test->state, sizeof(char), Ptcp) < 0) { + i_errno = IESENDMESSAGE; + return (-1); + } + } + exit(1); + } + if (iperf_parse_arguments(test, argc, argv) < 0) { iperf_error("parameter error"); fprintf(stderr, "\n");