summaryrefslogtreecommitdiffstats
path: root/lib
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 /lib
parent8a0949dfc8d2ecf577dfc5ef38496421101b734e (diff)
downloadsamba-1ffcb991a900b78c9175f6b093839fe96b1bd7d9.tar.gz
samba-1ffcb991a900b78c9175f6b093839fe96b1bd7d9.tar.xz
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
Diffstat (limited to 'lib')
-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;