From 6bb4023959da8de5637c765eff9704bcdf2a3698 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 17 Feb 2010 08:49:28 +0100 Subject: [PATCH] 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) (cherry picked from commit b4a5c3325a272c97658aaede1f1c659260524789) --- lib/tsocket/tsocket_bsd.c | 55 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 53 insertions(+), 2 deletions(-) diff --git a/lib/tsocket/tsocket_bsd.c b/lib/tsocket/tsocket_bsd.c index d5050f90e7b..17250039a4d 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) { -- 2.11.4.GIT