aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBruce A. Mah <bmah@es.net>2019-06-18 16:03:21 -0700
committerGitHub <noreply@github.com>2019-06-18 16:03:21 -0700
commit38bac802fa85db9012981ff87c3725812a3d8a07 (patch)
treea9dca0d615540654f27c8532de4713523ed52b28
parentc4bd56f3736d362e33be56929d306ccb0d37d0ef (diff)
downloadiperf3-38bac802fa85db9012981ff87c3725812a3d8a07.tar.gz
fix: Emit appropriate error messages from getaddrinfo(3). (#888)
* fix: Emit appropriate error messages from getaddrinfo(3). This fixes an omission likely caused when switching resolver library calls. Fixes #846.
-rwxr-xr-xsrc/iperf.h4
-rw-r--r--src/iperf_error.c10
-rw-r--r--src/iperf_sctp.c12
-rw-r--r--src/iperf_tcp.c8
-rw-r--r--src/net.c15
5 files changed, 34 insertions, 15 deletions
diff --git a/src/iperf.h b/src/iperf.h
index b8a6e58..6ce77f5 100755
--- a/src/iperf.h
+++ b/src/iperf.h
@@ -1,5 +1,5 @@
/*
- * iperf, Copyright (c) 2014-2018, The Regents of the University of
+ * iperf, Copyright (c) 2014-2019, 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.
@@ -385,4 +385,6 @@ struct iperf_test
#define MAX_MSS (9 * 1024)
#define MAX_STREAMS 128
+extern int gerror; /* error value from getaddrinfo(3), for use in internal error handling */
+
#endif /* !__IPERF_H */
diff --git a/src/iperf_error.c b/src/iperf_error.c
index e6eb032..fd3cccc 100644
--- a/src/iperf_error.c
+++ b/src/iperf_error.c
@@ -33,6 +33,8 @@
#include "iperf.h"
#include "iperf_api.h"
+int gerror;
+
/* Do a printf to stderr. */
void
iperf_err(struct iperf_test *test, const char *format, ...)
@@ -185,11 +187,13 @@ iperf_strerror(int int_errno)
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");
perr = 1;
+ herr = 1;
break;
case IEACCEPT:
snprintf(errstr, len, "unable to accept connection from client");
@@ -317,6 +321,7 @@ iperf_strerror(int int_errno)
break;
case IESTREAMLISTEN:
snprintf(errstr, len, "unable to start stream listener");
+ herr = 1;
perr = 1;
break;
case IESTREAMCONNECT:
@@ -383,10 +388,15 @@ iperf_strerror(int int_errno)
}
+ /* 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;
}
diff --git a/src/iperf_sctp.c b/src/iperf_sctp.c
index c1cb134..06e1e23 100644
--- a/src/iperf_sctp.c
+++ b/src/iperf_sctp.c
@@ -1,5 +1,5 @@
/*
- * iperf, Copyright (c) 2014-2018, The Regents of the University of
+ * iperf, Copyright (c) 2014-2019, 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.
@@ -178,7 +178,7 @@ iperf_sctp_listen(struct iperf_test *test)
}
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
- if (getaddrinfo(test->bind_address, portstr, &hints, &res) != 0) {
+ if ((gerror = getaddrinfo(test->bind_address, portstr, &hints, &res)) != 0) {
i_errno = IESTREAMLISTEN;
return -1;
}
@@ -266,7 +266,7 @@ iperf_sctp_connect(struct iperf_test *test)
memset(&hints, 0, sizeof(hints));
hints.ai_family = test->settings->domain;
hints.ai_socktype = SOCK_STREAM;
- if (getaddrinfo(test->bind_address, NULL, &hints, &local_res) != 0) {
+ if ((gerror = getaddrinfo(test->bind_address, NULL, &hints, &local_res)) != 0) {
i_errno = IESTREAMCONNECT;
return -1;
}
@@ -276,7 +276,7 @@ iperf_sctp_connect(struct iperf_test *test)
hints.ai_family = test->settings->domain;
hints.ai_socktype = SOCK_STREAM;
snprintf(portstr, sizeof(portstr), "%d", test->server_port);
- if (getaddrinfo(test->server_hostname, portstr, &hints, &server_res) != 0) {
+ if ((gerror = getaddrinfo(test->server_hostname, portstr, &hints, &server_res)) != 0) {
if (test->bind_address)
freeaddrinfo(local_res);
i_errno = IESTREAMCONNECT;
@@ -548,7 +548,7 @@ iperf_sctp_bindx(struct iperf_test *test, int s, int is_server)
xbe0 = TAILQ_FIRST(&test->xbind_addrs);
TAILQ_REMOVE(&test->xbind_addrs, xbe0, link);
- if (getaddrinfo(xbe0->name, servname, &hints, &xbe0->ai) != 0) {
+ if ((gerror = getaddrinfo(xbe0->name, servname, &hints, &xbe0->ai)) != 0) {
i_errno = IESETSCTPBINDX;
retval = -1;
goto out;
@@ -592,7 +592,7 @@ iperf_sctp_bindx(struct iperf_test *test, int s, int is_server)
TAILQ_FOREACH(xbe, &test->xbind_addrs, link) {
if (xbe->ai != NULL)
freeaddrinfo(xbe->ai);
- if (getaddrinfo(xbe->name, servname, &hints, &xbe->ai) != 0) {
+ if ((gerror = getaddrinfo(xbe->name, servname, &hints, &xbe->ai)) != 0) {
i_errno = IESETSCTPBINDX;
retval = -1;
goto out;
diff --git a/src/iperf_tcp.c b/src/iperf_tcp.c
index f6ef78f..232aaa1 100644
--- a/src/iperf_tcp.c
+++ b/src/iperf_tcp.c
@@ -1,5 +1,5 @@
/*
- * iperf, Copyright (c) 2014-2018, The Regents of the University of
+ * iperf, Copyright (c) 2014-2019, 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.
@@ -184,7 +184,7 @@ iperf_tcp_listen(struct iperf_test *test)
}
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE;
- if (getaddrinfo(test->bind_address, portstr, &hints, &res) != 0) {
+ if ((gerror = getaddrinfo(test->bind_address, portstr, &hints, &res)) != 0) {
i_errno = IESTREAMLISTEN;
return -1;
}
@@ -375,7 +375,7 @@ iperf_tcp_connect(struct iperf_test *test)
memset(&hints, 0, sizeof(hints));
hints.ai_family = test->settings->domain;
hints.ai_socktype = SOCK_STREAM;
- if (getaddrinfo(test->bind_address, NULL, &hints, &local_res) != 0) {
+ if ((gerror = getaddrinfo(test->bind_address, NULL, &hints, &local_res)) != 0) {
i_errno = IESTREAMCONNECT;
return -1;
}
@@ -385,7 +385,7 @@ iperf_tcp_connect(struct iperf_test *test)
hints.ai_family = test->settings->domain;
hints.ai_socktype = SOCK_STREAM;
snprintf(portstr, sizeof(portstr), "%d", test->server_port);
- if (getaddrinfo(test->server_hostname, portstr, &hints, &server_res) != 0) {
+ if ((gerror = getaddrinfo(test->server_hostname, portstr, &hints, &server_res)) != 0) {
if (test->bind_address)
freeaddrinfo(local_res);
i_errno = IESTREAMCONNECT;
diff --git a/src/net.c b/src/net.c
index fd525ee..96fb7ed 100644
--- a/src/net.c
+++ b/src/net.c
@@ -1,5 +1,5 @@
/*
- * iperf, Copyright (c) 2014-2018, The Regents of the University of
+ * iperf, Copyright (c) 2014-2019, 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.
@@ -65,6 +65,13 @@
#include "timer.h"
/*
+ * Declaration of gerror in iperf_error.c. Most other files in iperf3 can get this
+ * by including "iperf.h", but net.c lives "below" this layer. Clearly the
+ * presence of this declaration is a sign we need to revisit this layering.
+ */
+extern int gerror;
+
+/*
* timeout_connect adapted from netcat, via OpenBSD and FreeBSD
* Copyright (c) 2001 Eric Jackson <ericj@monkey.org>
*/
@@ -122,14 +129,14 @@ netdial(int domain, int proto, char *local, int local_port, char *server, int po
memset(&hints, 0, sizeof(hints));
hints.ai_family = domain;
hints.ai_socktype = proto;
- if (getaddrinfo(local, NULL, &hints, &local_res) != 0)
+ if ((gerror = getaddrinfo(local, NULL, &hints, &local_res)) != 0)
return -1;
}
memset(&hints, 0, sizeof(hints));
hints.ai_family = domain;
hints.ai_socktype = proto;
- if (getaddrinfo(server, NULL, &hints, &server_res) != 0)
+ if ((gerror = getaddrinfo(server, NULL, &hints, &server_res)) != 0)
return -1;
s = socket(server_res->ai_family, proto, 0);
@@ -238,7 +245,7 @@ netannounce(int domain, int proto, char *local, int port)
}
hints.ai_socktype = proto;
hints.ai_flags = AI_PASSIVE;
- if (getaddrinfo(local, portstr, &hints, &res) != 0)
+ if ((gerror = getaddrinfo(local, portstr, &hints, &res)) != 0)
return -1;
s = socket(res->ai_family, proto, 0);