diff options
author | Stefan Metzmacher <metze@samba.org> | 2010-02-17 09:33:18 +0100 |
---|---|---|
committer | Karolin Seeger <kseeger@samba.org> | 2010-02-19 14:32:28 +0100 |
commit | e73afc1e113a751dbf9d79f79555c45fa684a907 (patch) | |
tree | a240b2a2e7ecc94e194906f057fcc2090eb21a54 | |
parent | 6bb4023959da8de5637c765eff9704bcdf2a3698 (diff) | |
download | samba-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.c | 36 |
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; |