1
1

Fix two related bugs with -B and IPv4 addresses.

If specifying -B with an IPv4 literal address or with an FQDN that
resolved to an IPv4 address, but we had not explicitly specified an
address family with -4, we failed to set up the socket correctly
because we assumed binding to an IPv6 address, and instead (after some
error spewage) wound up binding to wildcard address.

The fix in this commit has multiple parts:  First, if the address
family hasn't been explictly specified, don't force AF_INET6 in the
hints to getaddrinfo(3).  AF_UNSPEC should generate the correct
(according to RFC 6724) behavior.

Second, iperf_reset_test() should not discard members that were passed
from command-line parameters, because that alters the behavior of the
iperf3 when it tries to recreate the listening socket.  In the failure
situation described in this issue (and possibly other as well), the
value of -B gets discarded, so on subsequent attempts to set up the
listening socket it just binds to the wildcard address.

While here, fix on-line help related to the -B option to match
reality.

Note that we're not completely in compliance with RFC 6724, which
states that we should actually try all of the addresses in returned by
getaddrinfo(3), rather than just the first one.

Fixes Issue #193.
Этот коммит содержится в:
Bruce A. Mah 2014-07-17 14:30:39 -07:00
родитель fa0e81c853
Коммит 5b760eef47
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4984910A8CAAEE8A
3 изменённых файлов: 4 добавлений и 21 удалений

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

@ -1850,23 +1850,6 @@ iperf_reset_test(struct iperf_test *test)
CPU_ZERO(&test->cpumask);
#endif /* HAVE_CPUSET_SETAFFINITY */
test->state = 0;
if(test->title) {
free(test->title);
test->title = NULL;
}
if(test->server_hostname) {
free(test->server_hostname);
test->server_hostname = NULL;
}
if(test->bind_address) {
free(test->bind_address);
test->bind_address = NULL;
}
if(test->congestion) {
free(test->congestion);
test->congestion = NULL;
}
test->ctrl_sck = -1;
test->prot_listener = -1;

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

@ -83,6 +83,7 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n"
#if defined(HAVE_CPU_AFFINITY)
" -A, --affinity n/n,m set CPU affinity\n"
#endif /* HAVE_CPU_AFFINITY */
" -B, --bind <host> bind to a specific interface\n"
" -V, --verbose more detailed output\n"
" -J, --json output in JSON format\n"
" --logfile f send output to a log file\n"
@ -110,7 +111,6 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n"
" -P, --parallel # number of parallel client streams to run\n"
" -R, --reverse run in reverse mode (server sends, client receives)\n"
" -w, --window #[KMG] TCP window size (socket buffer size)\n"
" -B, --bind <host> bind to a specific interface\n"
#if defined(HAVE_TCP_CONGESTION)
" -C, --congestion <algo> set TCP congestion control algorithm (Linux and FreeBSD only)\n"
#endif /* HAVE_TCP_CONGESTION */

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

@ -107,7 +107,7 @@ netannounce(int domain, int proto, char *local, int port)
snprintf(portstr, 6, "%d", port);
memset(&hints, 0, sizeof(hints));
hints.ai_family = (domain == AF_UNSPEC ? AF_INET6 : domain);
hints.ai_family = domain;
hints.ai_socktype = proto;
hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(local, portstr, &hints, &res) != 0)
@ -126,10 +126,10 @@ netannounce(int domain, int proto, char *local, int port)
freeaddrinfo(res);
return -1;
}
if (domain == AF_UNSPEC || domain == AF_INET6) {
if (res->ai_family == AF_INET6 && (domain == AF_UNSPEC || domain == AF_INET6)) {
if (domain == AF_UNSPEC)
opt = 0;
else if (domain == AF_INET6)
else
opt = 1;
if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY,
(char *) &opt, sizeof(opt)) < 0) {