diff options
author | Stefan Metzmacher <metze@samba.org> | 2010-02-17 09:33:18 +0100 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2010-02-17 14:46:39 +0100 |
commit | 1ffcb991a900b78c9175f6b093839fe96b1bd7d9 (patch) | |
tree | 3de346c2243b577c4944c9ab115911c530f7a54f | |
parent | 8a0949dfc8d2ecf577dfc5ef38496421101b734e (diff) | |
download | samba-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.c | 36 |
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; |