From 6af295bad1240f15002cbf59e609da5c8e8c475e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Feb 2010 09:43:00 +0100 Subject: [PATCH 1/5] socket_wrapper: also ignore AF_INET6 in swrap_setsockopt() metze (cherry picked from commit 0b3e950731fe72a258a631e39ca1304d54663536) --- lib/socket_wrapper/socket_wrapper.c | 4 ++++ 1 files changed, 4 insertions(+), 0 deletions(-) diff --git a/lib/socket_wrapper/socket_wrapper.c b/lib/socket_wrapper/socket_wrapper.c index a188cc6..9d732ee 100644 --- a/lib/socket_wrapper/socket_wrapper.c +++ b/lib/socket_wrapper/socket_wrapper.c @@ -1839,6 +1839,10 @@ _PUBLIC_ int swrap_setsockopt(int s, int level, int optname, const void *o switch (si->family) { case AF_INET: return 0; +#ifdef HAVE_IPV6 + case AF_INET6: + return 0; +#endif default: errno = ENOPROTOOPT; return -1; -- 1.6.3.3 From 9481664270123b62a436030a5dc8331f3e08b6a0 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Feb 2010 08:42:22 +0100 Subject: [PATCH 2/5] tsocket/bsd: fix do_bind logic for AF_INET We want the explicit bind() when we don't use the any address. metze (cherry picked from commit 135543b4c300e2fc31ee4165ce630644e1aef455) --- lib/tsocket/tsocket_bsd.c | 4 ++-- 1 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c index 1c1e580..1cc9781 100644 --- a/lib/tsocket/tsocket_bsd.c +++ b/lib/tsocket/tsocket_bsd.c @@ -1164,7 +1164,7 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local, do_reuseaddr = true; do_bind = true; } - if (lbsda->u.in.sin_addr.s_addr == INADDR_ANY) { + if (lbsda->u.in.sin_addr.s_addr != INADDR_ANY) { do_bind = true; } break; @@ -1973,7 +1973,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx, do_reuseaddr = true; do_bind = true; } - if (lbsda->u.in.sin_addr.s_addr == INADDR_ANY) { + if (lbsda->u.in.sin_addr.s_addr != INADDR_ANY) { do_bind = true; } break; -- 1.6.3.3 From 065c977a2c7f2b3bee0c34db11292bbd9f69c878 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Feb 2010 08:45:58 +0100 Subject: [PATCH 3/5] tsocket/bsd: fix bug #7140 use calculated sa_socklen for bind() in tstream_bsd_connect_send() This is needed because, we can't use sizeof(sockaddr_storage) for AF_UNIX sockets. Also some platforms require exact values for AF_INET and AF_INET6. metze (cherry picked from commit 6637b2f4b06fcee1e8e1b1782dd96e3273f8caac) --- lib/tsocket/tsocket_bsd.c | 2 +- 1 files changed, 1 insertions(+), 1 deletions(-) diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c index 1cc9781..d5050f9 100644 --- a/lib/tsocket/tsocket_bsd.c +++ b/lib/tsocket/tsocket_bsd.c @@ -2019,7 +2019,7 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx, } if (do_bind) { - ret = bind(state->fd, &lbsda->u.sa, sizeof(lbsda->u.ss)); + ret = bind(state->fd, &lbsda->u.sa, sa_socklen); if (ret == -1) { tevent_req_error(req, errno); goto post; -- 1.6.3.3 From 4694ffb1616d5d1d03d5832b757ea9966f425395 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Feb 2010 08:49:28 +0100 Subject: [PATCH 4/5] tsocket/bsd: fix bug #7140 autodetect ipv4 and ipv6 based on the remote address if the local address is any metze (cherry picked from commit 8a0949dfc8d2ecf577dfc5ef38496421101b734e) --- lib/tsocket/tsocket_bsd.c | 55 +++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 53 insertions(+), 2 deletions(-) diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c index d5050f9..1725003 100644 --- a/lib/tsocket/tsocket_bsd.c +++ b/lib/tsocket/tsocket_bsd.c @@ -1136,6 +1136,8 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local, int ret; bool do_bind = false; bool do_reuseaddr = false; + bool is_inet = false; + int sa_fam = lbsda->u.sa.sa_family; socklen_t sa_socklen = sizeof(lbsda->u.ss); if (remote) { @@ -1167,6 +1169,8 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local, if (lbsda->u.in.sin_addr.s_addr != INADDR_ANY) { do_bind = true; } + is_inet = true; + sa_socklen = sizeof(rbsda->u.in); break; #ifdef HAVE_IPV6 case AF_INET6: @@ -1179,6 +1183,8 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local, sizeof(in6addr_any)) != 0) { do_bind = true; } + is_inet = true; + sa_socklen = sizeof(rbsda->u.in6); break; #endif default: @@ -1186,7 +1192,21 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local, return -1; } - fd = socket(lbsda->u.sa.sa_family, SOCK_DGRAM, 0); + if (!do_bind && is_inet && rbsda) { + sa_fam = rbsda->u.sa.sa_family; + switch (sa_fam) { + case AF_INET: + sa_socklen = sizeof(rbsda->u.in); + break; +#ifdef HAVE_IPV6 + case AF_INET6: + sa_socklen = sizeof(rbsda->u.in6); + break; +#endif + } + } + + fd = socket(sa_fam, SOCK_DGRAM, 0); if (fd < 0) { return fd; } @@ -1248,6 +1268,12 @@ static int tdgram_bsd_dgram_socket(const struct tsocket_address *local, } if (rbsda) { + if (rbsda->u.sa.sa_family != sa_fam) { + talloc_free(dgram); + errno = EINVAL; + return -1; + } + ret = connect(fd, &rbsda->u.sa, sa_socklen); if (ret == -1) { int saved_errno = errno; @@ -1938,6 +1964,8 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx, bool retry; bool do_bind = false; bool do_reuseaddr = false; + bool is_inet = false; + int sa_fam = lbsda->u.sa.sa_family; socklen_t sa_socklen = sizeof(rbsda->u.ss); req = tevent_req_create(mem_ctx, &state, @@ -1976,6 +2004,8 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx, if (lbsda->u.in.sin_addr.s_addr != INADDR_ANY) { do_bind = true; } + is_inet = true; + sa_socklen = sizeof(rbsda->u.in); break; #ifdef HAVE_IPV6 case AF_INET6: @@ -1988,6 +2018,8 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx, sizeof(in6addr_any)) != 0) { do_bind = true; } + is_inet = true; + sa_socklen = sizeof(rbsda->u.in6); break; #endif default: @@ -1995,7 +2027,21 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx, goto post; } - state->fd = socket(lbsda->u.sa.sa_family, SOCK_STREAM, 0); + if (!do_bind && is_inet) { + sa_fam = rbsda->u.sa.sa_family; + switch (sa_fam) { + case AF_INET: + sa_socklen = sizeof(rbsda->u.in); + break; +#ifdef HAVE_IPV6 + case AF_INET6: + sa_socklen = sizeof(rbsda->u.in6); + break; +#endif + } + } + + state->fd = socket(sa_fam, SOCK_STREAM, 0); if (state->fd == -1) { tevent_req_error(req, errno); goto post; @@ -2026,6 +2072,11 @@ static struct tevent_req * tstream_bsd_connect_send(TALLOC_CTX *mem_ctx, } } + if (rbsda->u.sa.sa_family != sa_fam) { + tevent_req_error(req, EINVAL); + goto post; + } + ret = connect(state->fd, &rbsda->u.sa, sa_socklen); err = tsocket_bsd_error_from_errno(ret, errno, &retry); if (retry) { -- 1.6.3.3 From 2ecc7b0aaa0b83051318fbb999af423e40172db7 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Feb 2010 09:33:18 +0100 Subject: [PATCH 5/5] 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) --- 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 1725003..634deb8 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; -- 1.6.3.3