summaryrefslogtreecommitdiffstats
path: root/source3/lib
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2009-06-08 13:26:39 -0700
committerJeremy Allison <jra@samba.org>2009-06-08 13:26:39 -0700
commitc736baf9f82e7246718d0b65a93e983a614ad0ed (patch)
treed019fdff169db6fb1e53e0c18fddcea178419842 /source3/lib
parentd2bb72d713d9c339c00536256f44dacf51e57414 (diff)
downloadsamba-c736baf9f82e7246718d0b65a93e983a614ad0ed.tar.gz
samba-c736baf9f82e7246718d0b65a93e983a614ad0ed.tar.xz
samba-c736baf9f82e7246718d0b65a93e983a614ad0ed.zip
Make open_udp_socket() IPv6 clean. Trying to fix bug #6437 - Unable to join IPv6-only ads domain.
Avaiting feedback from submitter before backport to 3.4 and earlier. Jeremy.
Diffstat (limited to 'source3/lib')
-rw-r--r--source3/lib/util_sock.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c
index cf1bb7973eb..31261afd729 100644
--- a/source3/lib/util_sock.c
+++ b/source3/lib/util_sock.c
@@ -1414,24 +1414,39 @@ bool open_any_socket_out(struct sockaddr_storage *addrs, int num_addrs,
int open_udp_socket(const char *host, int port)
{
- int type = SOCK_DGRAM;
- struct sockaddr_in sock_out;
+ struct sockaddr_storage ss;
int res;
- struct in_addr addr;
- addr = interpret_addr2(host);
+ if (!interpret_string_addr(&ss, host, 0)) {
+ DEBUG(10,("open_udp_socket: can't resolve name %s\n",
+ host));
+ return -1;
+ }
- res = socket(PF_INET, type, 0);
+ res = socket(ss.ss_family, SOCK_DGRAM, 0);
if (res == -1) {
return -1;
}
- memset((char *)&sock_out,'\0',sizeof(sock_out));
- putip((char *)&sock_out.sin_addr,(char *)&addr);
- sock_out.sin_port = htons(port);
- sock_out.sin_family = PF_INET;
+#if defined(HAVE_IPV6)
+ if (ss.ss_family == AF_INET6) {
+ struct sockaddr_in6 *psa6;
+ psa6 = (struct sockaddr_in6 *)&ss;
+ psa6->sin6_port = htons(port);
+ if (psa6->sin6_scope_id == 0
+ && IN6_IS_ADDR_LINKLOCAL(&psa6->sin6_addr)) {
+ setup_linklocal_scope_id(
+ (struct sockaddr *)&ss);
+ }
+ }
+#endif
+ if (ss.ss_family == AF_INET) {
+ struct sockaddr_in *psa;
+ psa = (struct sockaddr_in *)&ss;
+ psa->sin_port = htons(port);
+ }
- if (sys_connect(res,(struct sockaddr *)&sock_out)) {
+ if (sys_connect(res,(struct sockaddr *)&ss)) {
close(res);
return -1;
}