Bug #77752 bind-address wrongly prefers IPv4 over IPv6
Submitted: 16 Jul 2015 20:38 Modified: 11 Aug 2015 12:27
Reporter: Daniël van Eeden (OCA) Email Updates:
Status: Not a Bug Impact on me:
None 
Category:MySQL Server Severity:S3 (Non-critical)
Version:5.7.8 OS:Any
Assigned to: CPU Architecture:Any
Tags: ipv6

[16 Jul 2015 20:38] Daniël van Eeden
Description:
When bind-address=localhost is set and localhost has both a IPv4 and IPv6 address it should use listen on *both*

Somewhat related:
Happy Eyeballs: Success with Dual-Stack Hosts
https://tools.ietf.org/html/rfc6555

Bug #14979 	request for more than just one bind-address

How to repeat:
bind-address=127.0.0.1
2015-07-16T19:16:38.315557Z 0 [Note]   - '127.0.0.1' resolves to '127.0.0.1';

bind-address=localhost
2015-07-16T19:22:21.933714Z 0 [Note]   - 'localhost' resolves to '127.0.0.1';

bind-address=localhost6
2015-07-16T19:22:44.971267Z 0 [Note]   - 'localhost6' resolves to '::1';

$ ping6 -c 1 -n localhost
PING localhost(::1) 56 data bytes
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.040 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.040/0.040/0.040/0.000 ms

$ ping -c 1 -n localhost
PING localhost.localdomain (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.037 ms

--- localhost.localdomain ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.037/0.037/0.037/0.000 ms
[16 Jul 2015 20:39] Daniël van Eeden
$ dig +short -t AAAA localhost
::1

$ dig +short -t A localhost
127.0.0.1
[21 Jul 2015 8:26] MySQL Verification Team
Hello Daniël,

Thank you for the report.
I'm not seeing this on latest 5.7.8 builds, which exact build are you using? 

###

// Build used

[umshastr@hod03]/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64: cat docs/INFO_SRC
commit: ae3b133e5f7b13d1edf7acf7eee6af2c2b4014e2
date: 2015-07-20 14:02:16 +0200
build-date: 2015-07-20 14:16:07 +0200
short: ae3b133
branch: mysql-5.7.8-rc-release

MySQL source 5.7.8

// Oracle Linux Server release 7.0

cat /etc/hosts
127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
::1         localhost localhost.localdomain localhost6 localhost6.localdomain6

-- bind-address=127.0.0.1

bin/mysql_install_db --insecure --basedir=/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64 --datadir=/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64/77752 -v
bin/mysqld --basedir=/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64 --datadir=/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64/77752 --bind-address=127.0.0.1 --socket=/tmp/mysql_ushastry.sock  --port=15000 --log-error=/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64/77752/log.err 2>&1 &

tail /export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64/77752/log.err                         

.
.
2015-07-21T08:17:36.214473Z 0 [Note] Server hostname (bind-address): '127.0.0.1'; port: 15000
2015-07-21T08:17:36.214496Z 0 [Note]   - '127.0.0.1' resolves to '127.0.0.1';
2015-07-21T08:17:36.214513Z 0 [Note] Server socket created on IP: '127.0.0.1'.
2015-07-21T08:17:36.224104Z 0 [Note] Event Scheduler: Loaded 0 events
2015-07-21T08:17:36.224246Z 0 [Note] bin/mysqld: ready for connections.
Version: '5.7.8-rc'  socket: '/tmp/mysql_ushastry.sock'  port: 15000  MySQL Community Server (GPL)

-- bind-address=localhost

bin/mysqld --basedir=/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64 --datadir=/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64/77752 --bind-address=localhost --socket=/tmp/mysql_ushastry.sock  --port=15000 --log-error=/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64/77752/log.err 2>&1 &

 tail /export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64/77752/log.err                         
.
.
2015-07-21T08:19:28.184265Z 0 [Note] Server hostname (bind-address): 'localhost'; port: 15000
2015-07-21T08:19:28.184328Z 0 [Note] InnoDB: Buffer pool(s) load completed at 150721 10:19:28
2015-07-21T08:19:28.184656Z 0 [Note]   - 'localhost' resolves to '::1';
2015-07-21T08:19:28.184664Z 0 [Note]   - 'localhost' resolves to '127.0.0.1';
2015-07-21T08:19:28.184673Z 0 [Note] Server socket created on IP: '127.0.0.1'.
2015-07-21T08:19:28.193053Z 0 [Note] Event Scheduler: Loaded 0 events
2015-07-21T08:19:28.193249Z 0 [Note] bin/mysqld: ready for connections.
Version: '5.7.8-rc'  socket: '/tmp/mysql_ushastry.sock'  port: 15000  MySQL Community Server (GPL)

-- bind-address=localhost6

bin/mysqld --basedir=/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64 --datadir=/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64/77752 --bind-address=localhost6 --socket=/tmp/mysql_ushastry.sock  --port=15000 --log-error=/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64/77752/log.err 2>&1 &

 tail /export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64/77752/log.err                         
.
.
2015-07-21T08:20:33.816152Z 0 [Note] Server hostname (bind-address): 'localhost6'; port: 15000
2015-07-21T08:20:33.816316Z 0 [Note] InnoDB: Buffer pool(s) load completed at 150721 10:20:33
2015-07-21T08:20:33.816492Z 0 [Note]   - 'localhost6' resolves to '::1';
2015-07-21T08:20:33.816508Z 0 [Note] Server socket created on IP: '::1'.
2015-07-21T08:20:33.825269Z 0 [Note] Event Scheduler: Loaded 0 events
2015-07-21T08:20:33.825470Z 0 [Note] bin/mysqld: ready for connections.
Version: '5.7.8-rc'  socket: '/tmp/mysql_ushastry.sock'  port: 15000  MySQL Community Server (GPL)

##

[umshastr@hod03]/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64: ping6 -c 1 -n localhost
PING localhost(::1) 56 data bytes
64 bytes from ::1: icmp_seq=1 ttl=64 time=0.019 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.019/0.019/0.019/0.000 ms
[umshastr@hod03]/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64: ping -c 1 -n localhost
PING localhost (127.0.0.1) 56(84) bytes of data.
64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.020 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.020/0.020/0.020/0.000 ms
[umshastr@hod03]/export/umesh/server/binaries/mysql-5.7.8-rc-linux-glibc2.5-x86_64:

Thanks,
Umesh
[9 Aug 2015 15:22] Daniël van Eeden
My test:

[dvaneeden@dve-mac msb_5_7_8]$ grep bind-address my.sandbox.cnf 
bind-address       = localhost
[dvaneeden@dve-mac msb_5_7_8]$ > data/msandbox.err 
[dvaneeden@dve-mac msb_5_7_8]$ ./start
. sandbox server started
[dvaneeden@dve-mac msb_5_7_8]$ grep localhost data/msandbox.err 
2015-08-09T14:49:08.927292Z 0 [Note] Server hostname (bind-address): 'localhost'; port: 5708
2015-08-09T14:49:08.927441Z 0 [Note]   - 'localhost' resolves to '127.0.0.1';
[dvaneeden@dve-mac msb_5_7_8]$ lsof -i :5708 -n
COMMAND   PID      USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mysqld  13085 dvaneeden   32u  IPv4 152649      0t0  TCP 127.0.0.1:5708 (LISTEN)

To rule out MySQL Sandbox:
$ ./bin/mysqld --datadir=/tmp/test --initialize --lc-messages-dir=/opt/mysql/5.7.8/share
$ ./bin/mysqld --port=5000 --datadir=/tmp/test --lc-messages-dir=/opt/mysql/5.7.8/share --bind-address=localhost &
$ lsof -i :5000
COMMAND   PID      USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mysqld  13492 dvaneeden   20u  IPv4 153224      0t0  TCP localhost.localdomain:commplex-main (LISTEN)
$ pkill mysqld
$ ./bin/mysqld --port=5000 --datadir=/tmp/test --lc-messages-dir=/opt/mysql/5.7.8/share --bind-address=localhost6 &
$ lsof -i :5000
COMMAND   PID      USER   FD   TYPE DEVICE SIZE/OFF NODE NAME
mysqld  13602 dvaneeden   28u  IPv6 152176      0t0  TCP localhost6.localdomain6:commplex-main (LISTEN)

But it doesn't look to be MySQL's fault:

Python 3.4.2 (default, Jul  9 2015, 17:24:30) 
[GCC 5.1.1 20150618 (Red Hat 5.1.1-4)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import socket
>>> for entry in socket.getaddrinfo('localhost', 3306):
...     print(entry)
... 
(<AddressFamily.AF_INET: 2>, <SocketType.SOCK_STREAM: 1>, 6, '', ('127.0.0.1', 3306))
(<AddressFamily.AF_INET: 2>, <SocketType.SOCK_DGRAM: 2>, 17, '', ('127.0.0.1', 3306))
(<AddressFamily.AF_INET: 2>, <SocketType.SOCK_RAW: 3>, 0, '', ('127.0.0.1', 3306))
>>> for entry in socket.getaddrinfo('localhost6', 3306):
...     print(entry)
... 
(<AddressFamily.AF_INET6: 10>, <SocketType.SOCK_STREAM: 1>, 6, '', ('::1', 3306, 0, 0))
(<AddressFamily.AF_INET6: 10>, <SocketType.SOCK_DGRAM: 2>, 17, '', ('::1', 3306, 0, 0))
(<AddressFamily.AF_INET6: 10>, <SocketType.SOCK_RAW: 3>, 0, '', ('::1', 3306, 0, 0))
>>> for entry in socket.getaddrinfo('python.org', 3306):
...     print(entry)
... 
(<AddressFamily.AF_INET: 2>, <SocketType.SOCK_STREAM: 1>, 6, '', ('104.130.43.121', 3306))
(<AddressFamily.AF_INET: 2>, <SocketType.SOCK_DGRAM: 2>, 17, '', ('104.130.43.121', 3306))
(<AddressFamily.AF_INET: 2>, <SocketType.SOCK_RAW: 3>, 0, '', ('104.130.43.121', 3306))
(<AddressFamily.AF_INET6: 10>, <SocketType.SOCK_STREAM: 1>, 6, '', ('2001:4802:7901:0:e60a:1375:0:5', 3306, 0, 0))
(<AddressFamily.AF_INET6: 10>, <SocketType.SOCK_DGRAM: 2>, 17, '', ('2001:4802:7901:0:e60a:1375:0:5', 3306, 0, 0))
(<AddressFamily.AF_INET6: 10>, <SocketType.SOCK_RAW: 3>, 0, '', ('2001:4802:7901:0:e60a:1375:0:5', 3306, 0, 0))

[dvaneeden@dve-mac ~]$ cat /etc/hosts
127.0.0.1		localhost.localdomain localhost
::1		localhost6.localdomain6 localhost6
[dvaneeden@dve-mac ~]$ egrep '^hosts:' /etc/nsswitch.conf
hosts:      files mdns4_minimal [NOTFOUND=return] dns myhostname mymachines

If 'files' is used 'localhost' resolves to '127.0.0.1'.
If 'dns' is used 'localhost' resolves to '127.0.0.1' and '::1'

I would expect getent to 
[dvaneeden@dve-mac ~]$ getent hosts localhost
::1             localhost
[dvaneeden@dve-mac ~]$ ping6 -c 1 localhost
PING localhost(localhost6.localdomain6) 56 data bytes
64 bytes from localhost6.localdomain6: icmp_seq=1 ttl=64 time=0.115 ms

--- localhost ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 0.115/0.115/0.115/0.000 ms

The ahost{,4,v6} databases give different results...
[dvaneeden@dve-mac ~]$ getent ahosts localhost
127.0.0.1       STREAM localhost.localdomain
127.0.0.1       DGRAM  
127.0.0.1       RAW    
[dvaneeden@dve-mac ~]$ getent ahostsv4 localhost
127.0.0.1       STREAM localhost.localdomain
127.0.0.1       DGRAM  
127.0.0.1       RAW    
[dvaneeden@dve-mac ~]$ getent ahostsv6 localhost
::ffff:127.0.0.1 STREAM localhost.localdomain
::ffff:127.0.0.1 DGRAM  
::ffff:127.0.0.1 RAW  

So this is not a (MySQL) bug.
[11 Aug 2015 12:27] MySQL Verification Team
Thank you for confirming.
Marking this as a Not a Bug!

Thanks,
Umesh