diff options
author | Stefan Metzmacher <metze@samba.org> | 2011-04-23 11:29:51 +0200 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2011-04-25 17:42:03 +0200 |
commit | a3a38ee90ab4ab2be68ac71d9c581daa6b9ee189 (patch) | |
tree | b234d90675e4e6328ff868378b061f9ab1e70c00 /source3 | |
parent | 4bfe2d5655d97fbc7e65744425b5a098e77f5ba1 (diff) | |
download | samba-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')
-rw-r--r-- | source3/lib/util_sock.c | 26 |
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 || |