summaryrefslogtreecommitdiff
path: root/lib/tsocket/tsocket_bsd.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/tsocket/tsocket_bsd.c')
-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 2b0a24a58c..13680ec0c5 100644
--- a/lib/tsocket/tsocket_bsd.c
+++ b/lib/tsocket/tsocket_bsd.c
@@ -1142,6 +1142,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);
@@ -1191,6 +1192,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:
@@ -1203,10 +1205,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
}
@@ -1237,6 +1241,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;
@@ -1970,6 +1989,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);
@@ -2026,6 +2046,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:
@@ -2038,10 +2059,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
}
@@ -2059,6 +2082,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;