summaryrefslogtreecommitdiffstats
path: root/src/iperf_error.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/iperf_error.c')
-rw-r--r--src/iperf_error.c527
1 files changed, 527 insertions, 0 deletions
diff --git a/src/iperf_error.c b/src/iperf_error.c
new file mode 100644
index 0000000..6426554
--- /dev/null
+++ b/src/iperf_error.c
@@ -0,0 +1,527 @@
+/*
+ * iperf, Copyright (c) 2014-2022, The Regents of the University of
+ * California, through Lawrence Berkeley National Laboratory (subject
+ * to receipt of any required approvals from the U.S. Dept. of
+ * Energy). All rights reserved.
+ *
+ * If you have questions about your rights to use or distribute this
+ * software, please contact Berkeley Lab's Technology Transfer
+ * Department at TTD@lbl.gov.
+ *
+ * NOTICE. This software is owned by the U.S. Department of Energy.
+ * As such, the U.S. Government has been granted for itself and others
+ * acting on its behalf a paid-up, nonexclusive, irrevocable,
+ * worldwide license in the Software to reproduce, prepare derivative
+ * works, and perform publicly and display publicly. Beginning five
+ * (5) years after the date permission to assert copyright is obtained
+ * from the U.S. Department of Energy, and subject to any subsequent
+ * five (5) year renewals, the U.S. Government is granted for itself
+ * and others acting on its behalf a paid-up, nonexclusive,
+ * irrevocable, worldwide license in the Software to reproduce,
+ * prepare derivative works, distribute copies to the public, perform
+ * publicly and display publicly, and to permit others to do so.
+ *
+ * This code is distributed under a BSD style license, see the LICENSE
+ * file for complete information.
+ */
+#include <stdio.h>
+#include <errno.h>
+#include <netdb.h>
+#include <string.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include "iperf.h"
+#include "iperf_api.h"
+
+int gerror;
+
+char iperf_timestrerr[100];
+
+/* Do a printf to stderr. */
+void
+iperf_err(struct iperf_test *test, const char *format, ...)
+{
+ va_list argp;
+ char str[1000];
+ time_t now;
+ struct tm *ltm = NULL;
+ char *ct = NULL;
+
+ if (pthread_mutex_lock(&(test->print_mutex)) != 0) {
+ perror("iperf_err: pthread_mutex_lock");
+ }
+
+ /* Timestamp if requested */
+ if (test != NULL && test->timestamps) {
+ time(&now);
+ ltm = localtime(&now);
+ strftime(iperf_timestrerr, sizeof(iperf_timestrerr), test->timestamp_format, ltm);
+ ct = iperf_timestrerr;
+ }
+
+ va_start(argp, format);
+ vsnprintf(str, sizeof(str), format, argp);
+ if (test != NULL && test->json_output && test->json_top != NULL)
+ cJSON_AddStringToObject(test->json_top, "error", str);
+ else {
+ if (test && test->outfile && test->outfile != stdout) {
+ if (ct) {
+ fprintf(test->outfile, "%s", ct);
+ }
+ fprintf(test->outfile, "iperf3: %s\n", str);
+ }
+ else {
+ if (ct) {
+ fprintf(stderr, "%s", ct);
+ }
+ fprintf(stderr, "iperf3: %s\n", str);
+ }
+ }
+ va_end(argp);
+
+ if (pthread_mutex_unlock(&(test->print_mutex)) != 0) {
+ perror("iperf_err: pthread_mutex_unlock");
+ }
+}
+
+/* Do a printf to stderr or log file as appropriate, then exit. */
+void
+iperf_errexit(struct iperf_test *test, const char *format, ...)
+{
+ va_list argp;
+ char str[1000];
+ time_t now;
+ struct tm *ltm = NULL;
+ char *ct = NULL;
+
+ if (pthread_mutex_lock(&(test->print_mutex)) != 0) {
+ perror("iperf_errexit: pthread_mutex_lock");
+ }
+
+ /* Timestamp if requested */
+ if (test != NULL && test->timestamps) {
+ time(&now);
+ ltm = localtime(&now);
+ strftime(iperf_timestrerr, sizeof(iperf_timestrerr), "%c ", ltm);
+ ct = iperf_timestrerr;
+ }
+
+ va_start(argp, format);
+ vsnprintf(str, sizeof(str), format, argp);
+ if (test != NULL && test->json_output) {
+ if (test->json_top != NULL) {
+ cJSON_AddStringToObject(test->json_top, "error", str);
+ }
+ iperf_json_finish(test);
+ } else
+ if (test && test->outfile && test->outfile != stdout) {
+ if (ct) {
+ fprintf(test->outfile, "%s", ct);
+ }
+ fprintf(test->outfile, "iperf3: %s\n", str);
+ }
+ else {
+ if (ct) {
+ fprintf(stderr, "%s", ct);
+ }
+ fprintf(stderr, "iperf3: %s\n", str);
+ }
+
+ if (pthread_mutex_unlock(&(test->print_mutex)) != 0) {
+ perror("iperf_errexit: pthread_mutex_unlock");
+ }
+
+ va_end(argp);
+ if (test)
+ iperf_delete_pidfile(test);
+ exit(1);
+}
+
+int i_errno;
+
+char *
+iperf_strerror(int int_errno)
+{
+ static char errstr[256];
+ int len, perr, herr;
+ perr = herr = 0;
+
+ len = sizeof(errstr);
+ memset(errstr, 0, len);
+
+ switch (int_errno) {
+ case IENONE:
+ snprintf(errstr, len, "no error");
+ break;
+ case IESERVCLIENT:
+ snprintf(errstr, len, "cannot be both server and client");
+ break;
+ case IENOROLE:
+ snprintf(errstr, len, "must either be a client (-c) or server (-s)");
+ break;
+ case IESERVERONLY:
+ snprintf(errstr, len, "some option you are trying to set is server only");
+ 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, "invalid report interval (min = %g, max = %g seconds)", MIN_INTERVAL, MAX_INTERVAL);
+ break;
+ case IEBIND: /* UNUSED */
+ snprintf(errstr, len, "--bind must be specified to use --cport");
+ break;
+ case IEUDPBLOCKSIZE:
+ snprintf(errstr, len, "block size invalid (minimum = %d bytes, maximum = %d bytes)", MIN_UDP_BLOCKSIZE, MAX_UDP_BLOCKSIZE);
+ break;
+ case IEBADTOS:
+ snprintf(errstr, len, "bad TOS value (must be between 0 and 255 inclusive)");
+ break;
+ case IESETCLIENTAUTH:
+ snprintf(errstr, len, "you must specify a username, password, and path to a valid RSA public key");
+ break;
+ case IESETSERVERAUTH:
+ snprintf(errstr, len, "you must specify a path to a valid RSA private key and a user credential file");
+ break;
+ case IESERVERAUTHUSERS:
+ snprintf(errstr, len, "cannot access authorized users file");
+ break;
+ case IEBADFORMAT:
+ snprintf(errstr, len, "bad format specifier (valid formats are in the set [kmgtKMGT])");
+ break;
+ case IEBADPORT:
+ snprintf(errstr, len, "port number must be between 1 and 65535 inclusive");
+ break;
+ case IEMSS:
+ snprintf(errstr, len, "TCP MSS too large (maximum = %d bytes)", MAX_MSS);
+ break;
+ case IENOSENDFILE:
+ snprintf(errstr, len, "this OS does not support sendfile");
+ break;
+ case IEOMIT:
+ snprintf(errstr, len, "bogus value for --omit");
+ break;
+ case IEUNIMP:
+ snprintf(errstr, len, "an option you are trying to set is not implemented yet");
+ break;
+ case IEFILE:
+ snprintf(errstr, len, "unable to open -F file");
+ perr = 1;
+ break;
+ case IEBURST:
+ snprintf(errstr, len, "invalid burst count (maximum = %d)", MAX_BURST);
+ break;
+ case IEENDCONDITIONS:
+ snprintf(errstr, len, "only one test end condition (-t, -n, -k) may be specified");
+ break;
+ case IELOGFILE:
+ snprintf(errstr, len, "unable to open log file");
+ perr = 1;
+ break;
+ case IENOSCTP:
+ snprintf(errstr, len, "no SCTP support available");
+ break;
+ case IENEWTEST:
+ snprintf(errstr, len, "unable to create a new test");
+ perr = 1;
+ break;
+ case IEINITTEST:
+ snprintf(errstr, len, "test initialization failed");
+ perr = 1;
+ break;
+ case IEAUTHTEST:
+ snprintf(errstr, len, "test authorization failed");
+ break;
+ case IELISTEN:
+ snprintf(errstr, len, "unable to start listener for connections");
+ herr = 1;
+ perr = 1;
+ break;
+ case IECONNECT:
+ snprintf(errstr, len, "unable to connect to server - server may have stopped running or use a different port, firewall issue, etc.");
+ perr = 1;
+ herr = 1;
+ break;
+ case IEACCEPT:
+ 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");
+ perr = 1;
+ break;
+ case IERECVCOOKIE:
+ snprintf(errstr, len, "unable to receive cookie at server");
+ perr = 1;
+ break;
+ case IECTRLWRITE:
+ 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");
+ perr = 1;
+ break;
+ case IECTRLCLOSE:
+ snprintf(errstr, len, "control socket has closed unexpectedly");
+ break;
+ case IEMESSAGE:
+ snprintf(errstr, len, "received an unknown control message (ensure other side is iperf3 and not iperf)");
+ break;
+ case IESENDMESSAGE:
+ snprintf(errstr, len, "unable to send control message - port may not be available, the other side may have stopped running, etc.");
+ perr = 1;
+ break;
+ case IERECVMESSAGE:
+ snprintf(errstr, len, "unable to receive control message - port may not be available, the other side may have stopped running, etc.");
+ perr = 1;
+ break;
+ case IESENDPARAMS:
+ snprintf(errstr, len, "unable to send parameters to server");
+ perr = 1;
+ break;
+ case IERECVPARAMS:
+ snprintf(errstr, len, "unable to receive parameters from client");
+ perr = 1;
+ break;
+ case IEPACKAGERESULTS:
+ snprintf(errstr, len, "unable to package results");
+ perr = 1;
+ break;
+ case IESENDRESULTS:
+ snprintf(errstr, len, "unable to send results");
+ perr = 1;
+ break;
+ case IERECVRESULTS:
+ snprintf(errstr, len, "unable to receive results");
+ perr = 1;
+ break;
+ case IESELECT:
+ 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");
+ 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/SCTP NODELAY");
+ perr = 1;
+ break;
+ case IESETMSS:
+ snprintf(errstr, len, "unable to set TCP/SCTP MSS");
+ perr = 1;
+ break;
+ case IESETBUF:
+ snprintf(errstr, len, "unable to set socket buffer size");
+ perr = 1;
+ break;
+ case IESETTOS:
+ snprintf(errstr, len, "unable to set IP TOS");
+ perr = 1;
+ break;
+ case IESETCOS:
+ snprintf(errstr, len, "unable to set IPv6 traffic class");
+ perr = 1;
+ break;
+ case IESETFLOW:
+ snprintf(errstr, len, "unable to set IPv6 flow label");
+ break;
+ case IEREUSEADDR:
+ snprintf(errstr, len, "unable to reuse address on socket");
+ perr = 1;
+ break;
+ case IENONBLOCKING:
+ snprintf(errstr, len, "unable to set socket to non-blocking");
+ perr = 1;
+ break;
+ case IESETWINDOWSIZE:
+ snprintf(errstr, len, "unable to set socket window size");
+ perr = 1;
+ break;
+ case IEPROTOCOL:
+ snprintf(errstr, len, "protocol does not exist");
+ break;
+ case IEAFFINITY:
+ snprintf(errstr, len, "unable to set CPU affinity");
+ perr = 1;
+ break;
+ case IERCVTIMEOUT:
+ snprintf(errstr, len, "receive timeout value is incorrect or not in range");
+ perr = 1;
+ break;
+ case IESNDTIMEOUT:
+ snprintf(errstr, len, "send timeout value is incorrect or not in range");
+ perr = 1;
+ break;
+ case IEUDPFILETRANSFER:
+ snprintf(errstr, len, "cannot transfer file using UDP");
+ break;
+ case IERVRSONLYRCVTIMEOUT:
+ snprintf(errstr, len, "client receive timeout is valid only in receiving mode");
+ perr = 1;
+ break;
+ case IEDAEMON:
+ snprintf(errstr, len, "unable to become a daemon");
+ perr = 1;
+ break;
+ case IECREATESTREAM:
+ snprintf(errstr, len, "unable to create a new stream");
+ herr = 1;
+ perr = 1;
+ break;
+ case IEINITSTREAM:
+ snprintf(errstr, len, "unable to initialize stream");
+ herr = 1;
+ perr = 1;
+ break;
+ case IESTREAMLISTEN:
+ snprintf(errstr, len, "unable to start stream listener");
+ herr = 1;
+ perr = 1;
+ break;
+ case IESTREAMCONNECT:
+ snprintf(errstr, len, "unable to connect stream");
+ herr = 1;
+ perr = 1;
+ break;
+ case IESTREAMACCEPT:
+ snprintf(errstr, len, "unable to accept stream connection");
+ perr = 1;
+ break;
+ case IESTREAMWRITE:
+ snprintf(errstr, len, "unable to write to stream socket");
+ perr = 1;
+ break;
+ case IESTREAMREAD:
+ snprintf(errstr, len, "unable to read from stream socket");
+ perr = 1;
+ 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");
+ perr = 1;
+ break;
+ case IEUPDATETIMER:
+ snprintf(errstr, len, "unable to update timer");
+ perr = 1;
+ break;
+ case IESETCONGESTION:
+ snprintf(errstr, len, "unable to set TCP_CONGESTION: "
+ "Supplied congestion control algorithm not supported on this host");
+ break;
+ case IEPIDFILE:
+ snprintf(errstr, len, "unable to write PID file");
+ perr = 1;
+ break;
+ case IEV6ONLY:
+ snprintf(errstr, len, "Unable to set/reset IPV6_V6ONLY");
+ perr = 1;
+ break;
+ case IESETSCTPDISABLEFRAG:
+ snprintf(errstr, len, "unable to set SCTP_DISABLE_FRAGMENTS");
+ perr = 1;
+ break;
+ case IESETSCTPNSTREAM:
+ snprintf(errstr, len, "unable to set SCTP_INIT num of SCTP streams\n");
+ perr = 1;
+ break;
+ case IESETPACING:
+ snprintf(errstr, len, "unable to set socket pacing");
+ perr = 1;
+ break;
+ case IESETBUF2:
+ snprintf(errstr, len, "socket buffer size not set correctly");
+ break;
+ case IEREVERSEBIDIR:
+ snprintf(errstr, len, "cannot be both reverse and bidirectional");
+ break;
+ case IETOTALRATE:
+ snprintf(errstr, len, "total required bandwidth is larger than server limit");
+ break;
+ case IESKEWTHRESHOLD:
+ snprintf(errstr, len, "skew threshold must be a positive number");
+ break;
+ case IEIDLETIMEOUT:
+ snprintf(errstr, len, "idle timeout parameter is not positive or larger than allowed limit");
+ break;
+ case IEBINDDEV:
+ snprintf(errstr, len, "Unable to bind-to-device (check perror, maybe permissions?)");
+ break;
+ case IEBINDDEVNOSUPPORT:
+ snprintf(errstr, len, "`<ip>%%<dev>` is not supported as system does not support bind to device");
+ break;
+ case IEHOSTDEV:
+ snprintf(errstr, len, "host device name (ip%%<dev>) is supported (and required) only for IPv6 link-local address");
+ break;
+ case IENOMSG:
+ snprintf(errstr, len, "idle timeout for receiving data");
+ break;
+ case IESETDONTFRAGMENT:
+ snprintf(errstr, len, "unable to set IP Do-Not-Fragment flag");
+ break;
+ case IESETUSERTIMEOUT:
+ snprintf(errstr, len, "unable to set TCP USER_TIMEOUT");
+ perr = 1;
+ break;
+ case IEPTHREADCREATE:
+ snprintf(errstr, len, "unable to create thread");
+ perr = 1;
+ break;
+ case IEPTHREADCANCEL:
+ snprintf(errstr, len, "unable to cancel thread");
+ perr = 1;
+ break;
+ case IEPTHREADJOIN:
+ snprintf(errstr, len, "unable to join thread");
+ perr = 1;
+ break;
+ case IEPTHREADATTRINIT:
+ snprintf(errstr, len, "unable to create thread attributes");
+ perr = 1;
+ break;
+ case IEPTHREADATTRDESTROY:
+ snprintf(errstr, len, "unable to destroy thread attributes");
+ perr = 1;
+ break;
+ default:
+ snprintf(errstr, len, "int_errno=%d", int_errno);
+ perr = 1;
+ break;
+ }
+
+ /* Append the result of strerror() or gai_strerror() if appropriate */
+ if (herr || perr)
+ strncat(errstr, ": ", len - strlen(errstr) - 1);
+ if (errno && perr)
+ strncat(errstr, strerror(errno), len - strlen(errstr) - 1);
+ else if (herr && gerror) {
+ strncat(errstr, gai_strerror(gerror), len - strlen(errstr) - 1);
+ gerror = 0;
+ }
+
+ return errstr;
+}