php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #74557 mysqlnd doesn't support IPv6 literal hostnames
Submitted: 2017-05-08 16:08 UTC Modified: 2017-05-08 16:22 UTC
From: paul at packetship dot com Assigned:
Status: Open Package: MySQL related
PHP Version: master-Git-2017-05-08 (Git) OS: Linux
Private report: No CVE-ID: None
View Add Comment Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
You can add a comment by following this link or if you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: paul at packetship dot com
New email:
PHP Version: OS:

 

 [2017-05-08 16:08 UTC] 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!)





Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2017-05-08 16:22 UTC] requinix@php.net
-Type: Bug +Type: Documentation Problem
 [2017-05-08 16:22 UTC] requinix@php.net
Putting []s around IPv6 addresses is standard.
 [2017-05-08 16:30 UTC] paul at packetship dot com
Square brackets are only standard in URLs (as per RFC2732), not where hostnames stand alone as in the PDO string.  Having to put them in the hostname field is a workround (which could be usefully documented, agreed!).
 
PHP Copyright © 2001-2019 The PHP Group
All rights reserved.
Last updated: Tue Jul 16 02:01:26 2019 UTC