From a3a38ee90ab4ab2be68ac71d9c581daa6b9ee189 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Sat, 23 Apr 2011 11:29:51 +0200 Subject: s3:lib/util_sock: listen on IPv6 addresses with IPV6_ONLY (bug #7383) This avoids getting IPv4 addresses as mapped IPv6 addresses (e.g. ::ffff:192.168.0.1). Before the bahavior was inconsistent between operating system and distributions. Some system have IPV6_ONLY as default. Now we consistently get AF_INET for IPv4 addresses and AF_INET6 for IPv6 addresses. It also makes it possible to listen only on IPv6 now as "::" doesn't imply "0.0.0.0" anymore. Which also avoids confusing log messages that we were not able to bind to "0.0.0.0". metze --- source3/lib/util_sock.c | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/source3/lib/util_sock.c b/source3/lib/util_sock.c index 71f6a8f29c..eb74b75960 100644 --- a/source3/lib/util_sock.c +++ b/source3/lib/util_sock.c @@ -787,6 +787,32 @@ int open_socket_in(int type, #endif /* SO_REUSEPORT */ } +#ifdef HAVE_IPV6 + /* + * As IPV6_V6ONLY is the default on some systems, + * we better try to be consistent and always use it. + * + * This also avoids using IPv4 via AF_INET6 sockets + * and makes sure %I never resolves to a '::ffff:192.168.0.1' + * string. + */ + if (sock.ss_family == AF_INET6) { + int val = 1; + int ret; + + ret = setsockopt(res, IPPROTO_IPV6, IPV6_V6ONLY, + (const void *)&val, sizeof(val)); + if (ret == -1) { + if(DEBUGLVL(0)) { + dbgtext("open_socket_in(): IPV6_ONLY failed: "); + dbgtext("%s\n", strerror(errno)); + } + close(res); + return -1; + } + } +#endif + /* now we've got a socket - we need to bind it */ if (bind(res, (struct sockaddr *)&sock, slen) == -1 ) { if( DEBUGLVL(dlevel) && (port == SMB_PORT1 || -- cgit