1
1

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.
Этот коммит содержится в:
Bruce A. Mah 2019-06-18 16:03:21 -07:00 коммит произвёл GitHub
родитель c4bd56f373
Коммит 38bac802fa
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
5 изменённых файлов: 34 добавлений и 15 удалений

Просмотреть файл

@ -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 * California, through Lawrence Berkeley National Laboratory (subject
* to receipt of any required approvals from the U.S. Dept. of * to receipt of any required approvals from the U.S. Dept. of
* Energy). All rights reserved. * Energy). All rights reserved.
@ -385,4 +385,6 @@ struct iperf_test
#define MAX_MSS (9 * 1024) #define MAX_MSS (9 * 1024)
#define MAX_STREAMS 128 #define MAX_STREAMS 128
extern int gerror; /* error value from getaddrinfo(3), for use in internal error handling */
#endif /* !__IPERF_H */ #endif /* !__IPERF_H */

Просмотреть файл

@ -33,6 +33,8 @@
#include "iperf.h" #include "iperf.h"
#include "iperf_api.h" #include "iperf_api.h"
int gerror;
/* Do a printf to stderr. */ /* Do a printf to stderr. */
void void
iperf_err(struct iperf_test *test, const char *format, ...) iperf_err(struct iperf_test *test, const char *format, ...)
@ -185,11 +187,13 @@ iperf_strerror(int int_errno)
break; break;
case IELISTEN: case IELISTEN:
snprintf(errstr, len, "unable to start listener for connections"); snprintf(errstr, len, "unable to start listener for connections");
herr = 1;
perr = 1; perr = 1;
break; break;
case IECONNECT: case IECONNECT:
snprintf(errstr, len, "unable to connect to server"); snprintf(errstr, len, "unable to connect to server");
perr = 1; perr = 1;
herr = 1;
break; break;
case IEACCEPT: case IEACCEPT:
snprintf(errstr, len, "unable to accept connection from client"); snprintf(errstr, len, "unable to accept connection from client");
@ -317,6 +321,7 @@ iperf_strerror(int int_errno)
break; break;
case IESTREAMLISTEN: case IESTREAMLISTEN:
snprintf(errstr, len, "unable to start stream listener"); snprintf(errstr, len, "unable to start stream listener");
herr = 1;
perr = 1; perr = 1;
break; break;
case IESTREAMCONNECT: case IESTREAMCONNECT:
@ -383,10 +388,15 @@ iperf_strerror(int int_errno)
} }
/* Append the result of strerror() or gai_strerror() if appropriate */
if (herr || perr) if (herr || perr)
strncat(errstr, ": ", len - strlen(errstr) - 1); strncat(errstr, ": ", len - strlen(errstr) - 1);
if (errno && perr) if (errno && perr)
strncat(errstr, strerror(errno), len - strlen(errstr) - 1); 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; return errstr;
} }

Просмотреть файл

@ -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 * California, through Lawrence Berkeley National Laboratory (subject
* to receipt of any required approvals from the U.S. Dept. of * to receipt of any required approvals from the U.S. Dept. of
* Energy). All rights reserved. * Energy). All rights reserved.
@ -178,7 +178,7 @@ iperf_sctp_listen(struct iperf_test *test)
} }
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; 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; i_errno = IESTREAMLISTEN;
return -1; return -1;
} }
@ -266,7 +266,7 @@ iperf_sctp_connect(struct iperf_test *test)
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = test->settings->domain; hints.ai_family = test->settings->domain;
hints.ai_socktype = SOCK_STREAM; 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; i_errno = IESTREAMCONNECT;
return -1; return -1;
} }
@ -276,7 +276,7 @@ iperf_sctp_connect(struct iperf_test *test)
hints.ai_family = test->settings->domain; hints.ai_family = test->settings->domain;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
snprintf(portstr, sizeof(portstr), "%d", test->server_port); 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) if (test->bind_address)
freeaddrinfo(local_res); freeaddrinfo(local_res);
i_errno = IESTREAMCONNECT; 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); xbe0 = TAILQ_FIRST(&test->xbind_addrs);
TAILQ_REMOVE(&test->xbind_addrs, xbe0, link); 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; i_errno = IESETSCTPBINDX;
retval = -1; retval = -1;
goto out; 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) { TAILQ_FOREACH(xbe, &test->xbind_addrs, link) {
if (xbe->ai != NULL) if (xbe->ai != NULL)
freeaddrinfo(xbe->ai); 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; i_errno = IESETSCTPBINDX;
retval = -1; retval = -1;
goto out; goto out;

Просмотреть файл

@ -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 * California, through Lawrence Berkeley National Laboratory (subject
* to receipt of any required approvals from the U.S. Dept. of * to receipt of any required approvals from the U.S. Dept. of
* Energy). All rights reserved. * Energy). All rights reserved.
@ -184,7 +184,7 @@ iperf_tcp_listen(struct iperf_test *test)
} }
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE; 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; i_errno = IESTREAMLISTEN;
return -1; return -1;
} }
@ -375,7 +375,7 @@ iperf_tcp_connect(struct iperf_test *test)
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = test->settings->domain; hints.ai_family = test->settings->domain;
hints.ai_socktype = SOCK_STREAM; 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; i_errno = IESTREAMCONNECT;
return -1; return -1;
} }
@ -385,7 +385,7 @@ iperf_tcp_connect(struct iperf_test *test)
hints.ai_family = test->settings->domain; hints.ai_family = test->settings->domain;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
snprintf(portstr, sizeof(portstr), "%d", test->server_port); 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) if (test->bind_address)
freeaddrinfo(local_res); freeaddrinfo(local_res);
i_errno = IESTREAMCONNECT; i_errno = IESTREAMCONNECT;

Просмотреть файл

@ -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 * California, through Lawrence Berkeley National Laboratory (subject
* to receipt of any required approvals from the U.S. Dept. of * to receipt of any required approvals from the U.S. Dept. of
* Energy). All rights reserved. * Energy). All rights reserved.
@ -64,6 +64,13 @@
#include "net.h" #include "net.h"
#include "timer.h" #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 * timeout_connect adapted from netcat, via OpenBSD and FreeBSD
* Copyright (c) 2001 Eric Jackson <ericj@monkey.org> * 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)); memset(&hints, 0, sizeof(hints));
hints.ai_family = domain; hints.ai_family = domain;
hints.ai_socktype = proto; hints.ai_socktype = proto;
if (getaddrinfo(local, NULL, &hints, &local_res) != 0) if ((gerror = getaddrinfo(local, NULL, &hints, &local_res)) != 0)
return -1; return -1;
} }
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = domain; hints.ai_family = domain;
hints.ai_socktype = proto; hints.ai_socktype = proto;
if (getaddrinfo(server, NULL, &hints, &server_res) != 0) if ((gerror = getaddrinfo(server, NULL, &hints, &server_res)) != 0)
return -1; return -1;
s = socket(server_res->ai_family, proto, 0); 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_socktype = proto;
hints.ai_flags = AI_PASSIVE; hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(local, portstr, &hints, &res) != 0) if ((gerror = getaddrinfo(local, portstr, &hints, &res)) != 0)
return -1; return -1;
s = socket(res->ai_family, proto, 0); s = socket(res->ai_family, proto, 0);