summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2010-02-17 09:33:18 +0100
committerKarolin Seeger <kseeger@samba.org>2010-02-19 14:32:28 +0100
commite73afc1e113a751dbf9d79f79555c45fa684a907 (patch)
treea240b2a2e7ecc94e194906f057fcc2090eb21a54
parent6bb4023959da8de5637c765eff9704bcdf2a3698 (diff)
downloadsamba-e73afc1e113a751dbf9d79f79555c45fa684a907.tar.gz
tsocket/bsd: set IPV6_V6ONLY on AF_INET6 sockets
Some system already have this as default. It's easier to behave the same way on all systems and handle ipv6 and ipv4 sockets separate. metze (cherry picked from commit 1ffcb991a900b78c9175f6b093839fe96b1bd7d9) (cherry picked from commit d1dfa2e92fea3dc54771c4b1a6e3c06ee478b54f)
-rw-r--r--lib/tsocket/tsocket_bsd.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c
index 17250039a4d..634deb8280c 100644
--- a/lib/tsocket/tsocket_bsd.c
+++ b/lib/tsocket/tsocket_bsd.c
@@ -1136,6 +1136,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
int ret;
bool do_bind = false;
bool do_reuseaddr = false;
+ bool do_ipv6only = false;
bool is_inet = false;
int sa_fam = lbsda->u.sa.sa_family;
socklen_t sa_socklen = sizeof(lbsda->u.ss);
@@ -1185,6 +1186,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
}
is_inet = true;
sa_socklen = sizeof(rbsda->u.in6);
+ do_ipv6only = true;
break;
#endif
default:
@@ -1197,10 +1199,12 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
switch (sa_fam) {
case AF_INET:
sa_socklen = sizeof(rbsda->u.in);
+ do_ipv6only = false;
break;
#ifdef HAVE_IPV6
case AF_INET6:
sa_socklen = sizeof(rbsda->u.in6);
+ do_ipv6only = true;
break;
#endif
}
@@ -1231,6 +1235,21 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local,
bsds->fd = fd;
talloc_set_destructor(bsds, tdgram_bsd_destructor);
+#ifdef HAVE_IPV6
+ if (do_ipv6only) {
+ int val = 1;
+
+ ret = setsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY,
+ (const void *)&val, sizeof(val));
+ if (ret == -1) {
+ int saved_errno = errno;
+ talloc_free(dgram);
+ errno = saved_errno;
+ return ret;
+ }
+ }
+#endif
+
if (broadcast) {
int val = 1;
@@ -1964,6 +1983,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx,
bool retry;
bool do_bind = false;
bool do_reuseaddr = false;
+ bool do_ipv6only = false;
bool is_inet = false;
int sa_fam = lbsda->u.sa.sa_family;
socklen_t sa_socklen = sizeof(rbsda->u.ss);
@@ -2020,6 +2040,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx,
}
is_inet = true;
sa_socklen = sizeof(rbsda->u.in6);
+ do_ipv6only = true;
break;
#endif
default:
@@ -2032,10 +2053,12 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx,
switch (sa_fam) {
case AF_INET:
sa_socklen = sizeof(rbsda->u.in);
+ do_ipv6only = false;
break;
#ifdef HAVE_IPV6
case AF_INET6:
sa_socklen = sizeof(rbsda->u.in6);
+ do_ipv6only = true;
break;
#endif
}
@@ -2053,6 +2076,19 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx,
goto post;
}
+#ifdef HAVE_IPV6
+ if (do_ipv6only) {
+ int val = 1;
+
+ ret = setsockopt(state->fd, IPPROTO_IPV6, IPV6_V6ONLY,
+ (const void *)&val, sizeof(val));
+ if (ret == -1) {
+ tevent_req_error(req, errno);
+ goto post;
+ }
+ }
+#endif
+
if (do_reuseaddr) {
int val = 1;