aboutsummaryrefslogtreecommitdiff
path: root/src/net.c
diff options
context:
space:
mode:
authorBruce A. Mah <bmah@es.net>2014-07-17 17:14:20 -0700
committerBruce A. Mah <bmah@es.net>2014-07-17 17:14:20 -0700
commit76b5942f6f13b4cf4cb2763874819c7480300d92 (patch)
tree88535eede5a86c9ffc49997dad6ec7ab966c70a0 /src/net.c
parent5b760eef47f9d0535a2e4ef0cbaee66a7735e1c0 (diff)
downloadiperf3-76b5942f6f13b4cf4cb2763874819c7480300d92.tar.gz
Fix a problem with binding to the wildcard address.
On CentOS 6 and MacOS, if no address family was specified, we'd get back an IPv4 address from getaddrinfo(3), with the result that we couldn't accept IPv6 connections in the default server configuration. There was an earlier attempt at fixing this problem that caused Issue #193. This change is a follow-up fix to that issue. While here, put lots of comments around the fix so we remember why we're doing these shenanigans.
Diffstat (limited to 'src/net.c')
-rw-r--r--src/net.c25
1 files changed, 24 insertions, 1 deletions
diff --git a/src/net.c b/src/net.c
index e69d507..ea1b11f 100644
--- a/src/net.c
+++ b/src/net.c
@@ -107,7 +107,24 @@ netannounce(int domain, int proto, char *local, int port)
snprintf(portstr, 6, "%d", port);
memset(&hints, 0, sizeof(hints));
- hints.ai_family = domain;
+ /*
+ * If binding to the wildcard address with no explicit address
+ * family specified, then force us to get an AF_INET6 socket. On
+ * CentOS 6 and MacOS, getaddrinfo(3) with AF_UNSPEC in ai_family,
+ * and ai_flags containing AI_PASSIVE returns a result structure
+ * with ai_family set to AF_INET, with the result that we create
+ * and bind an IPv4 address wildcard address and by default, we
+ * can't accept IPv6 connections.
+ *
+ * On FreeBSD, under the above circumstances, ai_family in the
+ * result structure is set to AF_INET6.
+ */
+ if (domain == AF_UNSPEC && !local) {
+ hints.ai_family = AF_INET6;
+ }
+ else {
+ hints.ai_family = domain;
+ }
hints.ai_socktype = proto;
hints.ai_flags = AI_PASSIVE;
if (getaddrinfo(local, portstr, &hints, &res) != 0)
@@ -126,6 +143,12 @@ netannounce(int domain, int proto, char *local, int port)
freeaddrinfo(res);
return -1;
}
+
+ /*
+ * If we got an IPv6 socket, figure out if it should accept IPv4
+ * connections as well. We do that if and only if no address
+ * family was specified explicitly.
+ */
if (res->ai_family == AF_INET6 && (domain == AF_UNSPEC || domain == AF_INET6)) {
if (domain == AF_UNSPEC)
opt = 0;