summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2010-02-17 09:33:18 +0100
committerStefan Metzmacher <metze@samba.org>2010-02-17 14:46:39 +0100
commit1ffcb991a900b78c9175f6b093839fe96b1bd7d9 (patch)
tree3de346c2243b577c4944c9ab115911c530f7a54f
parent8a0949dfc8d2ecf577dfc5ef38496421101b734e (diff)
downloadsamba-1ffcb991a900b78c9175f6b093839fe96b1bd7d9.tar.gz
samba-1ffcb991a900b78c9175f6b093839fe96b1bd7d9.tar.bz2
samba-1ffcb991a900b78c9175f6b093839fe96b1bd7d9.zip
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
-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;