Skip to content

Commit

Permalink
Fix two related bugs with -B and IPv4 addresses.
Browse files Browse the repository at this point in the history
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.

(cherry picked from commit 5b760ee)
Signed-off-by: Bruce A. Mah <bmah@es.net>

Conflicts:
	src/locale.c
  • Loading branch information
bmah888 committed Jul 17, 2014
1 parent fb15120 commit 82b6200
Show file tree
Hide file tree
Showing 3 changed files with 4 additions and 21 deletions.
17 changes: 0 additions & 17 deletions src/iperf_api.c
Original file line number Diff line number Diff line change
Expand Up @@ -1719,23 +1719,6 @@ iperf_reset_test(struct iperf_test *test)
test->duration = DURATION;
test->server_affinity = -1;
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;
Expand Down
2 changes: 1 addition & 1 deletion src/locale.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ const char usage_longstr[] = "Usage: iperf [-s|-c host] [options]\n"
" -i, --interval # seconds between periodic bandwidth reports\n"
" -F, --file name xmit/recv the specified file\n"
" -A, --affinity n/n,m set CPU affinity\n"
" -B, --bind <host> bind to a specific interface\n"
" -V, --verbose more detailed output\n"
" -J, --json output in JSON format\n"
" -d, --debug emit debugging output\n"
Expand All @@ -103,7 +104,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 or multicast address\n"
#if defined(linux)
" -C, --linux-congestion <algo> set TCP congestion control algorithm (Linux only)\n"
#endif
Expand Down
6 changes: 3 additions & 3 deletions src/net.c
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,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)
Expand All @@ -123,10 +123,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) {
Expand Down

0 comments on commit 82b6200

Please sign in to comment.