Bug->Doc #74557 [Opn]: mysqlnd doesn't support IPv6 literal hostnames
| From: | requinix@php.net | Date: | Mon, 08 May 2017 16:22:33 +0000 |
| Subject: | Bug->Doc #74557 [Opn]: mysqlnd doesn't support IPv6 literal hostnames | ||
| References: | 1 | Groups: | php.doc.bugs |
| Request: | Send a blank email to doc-bugs+get-14677@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=74557&edit=1
ID: 74557
Updated by: requinix@php.net
Reported by: paul at packetship dot com
Summary: mysqlnd doesn't support IPv6 literal hostnames
Status: Open
-Type: Bug
+Type: Documentation Problem
Package: MySQL related
Operating System: Linux
PHP Version: master-Git-2017-05-08 (Git)
Block user comment: N
Private report: N
New Comment:
Putting []s around IPv6 addresses is standard.
Previous Comments:
------------------------------------------------------------------------
[2017-05-08 16:08:46] paul at packetship dot com
Description:
------------
(tested on PHP 7.0.15-0ubuntu0.16.04.4 but verified from git master source)
Attempting to connect to an IPv6 MySQL server using its literal IPv6 address fails unless you put
square brackets [ ] around the address in the hostname.
Square brackets are required in the URL form if there is a port - e.g.
http://[1234:5678::42]:8080/
but are not normally used for hostnames by themselves.
Although putting [ ] around the hostname makes it work - e.g.
$pdo = new PDO("mysql:host=[1234:5678::42];port=3306;dbname=foo", ...);
this is not expected, or documented.
The problem arises because the mysqlnd driver reconstructs a stream URL with the hostname and port:
transport.l = mnd_sprintf(&transport.s, 0, "tcp://%s:%u", hostname.s, port);
( https://github.com/php/php-src/blob/master/ext/mysqlnd/mysqlnd_connection.c#L581
)
This does not take into account that the hostname could already contain colons in an IPv6 address.
The IP address parser ( https://github.com/php/php-src/blob/master/main/streams/xp_socket.c#L573
) has code to work this out if there are square brackets around the IPv6 address, but fails
otherwise. This is why putting square brackets around the hostname in the PDO string works.
The fix would be to check for ':' in the hostname and surround it with [ ] if present -
e.g.
around mysqlnd_connection.c:L581
if (strchr(hostname.s, ':'))
transport.l = mnd_sprintf(&transport.s, 0, "tcp://[%s]:%u",
hostname.s, port);
else
transport.l = mnd_sprintf(&transport.s, 0, "tcp://%s:%u",
hostname.s, port);
(or something like that, PHP-style C is not my language, I'm afraid!)
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=74557&edit=1