summaryrefslogtreecommitdiff
path: root/source3/lib/util_sock.c
diff options
context:
space:
mode:
authorStefan Metzmacher <metze@samba.org>2011-04-23 11:29:51 +0200
committerStefan Metzmacher <metze@samba.org>2011-04-25 17:42:03 +0200
commita3a38ee90ab4ab2be68ac71d9c581daa6b9ee189 (patch)
treeb234d90675e4e6328ff868378b061f9ab1e70c00 /source3/lib/util_sock.c
parent4bfe2d5655d97fbc7e65744425b5a098e77f5ba1 (diff)
downloadsamba-a3a38ee90ab4ab2be68ac71d9c581daa6b9ee189.tar.gz
samba-a3a38ee90ab4ab2be68ac71d9c581daa6b9ee189.tar.bz2
samba-a3a38ee90ab4ab2be68ac71d9c581daa6b9ee189.zip
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
Diffstat (limited to 'source3/lib/util_sock.c')
-rw-r--r--source3/lib/util_sock.c26
1 files changed, 26 insertions, 0 deletions
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 ||