Bug #23758 Unable to connect to any server - IPv6 related
Submitted: 29 Oct 2006 23:31 Modified: 6 Nov 2006 14:11
Reporter: Luca Tettamanti Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / NET Severity:S2 (Serious)
Version:1.0.8-RC OS:Microsoft Windows (Windows 2003)
Assigned to: CPU Architecture:Any
Tags: connector, ipv6, open

[29 Oct 2006 23:31] Luca Tettamanti
Description:
Testing the new RC of .NET connector I've found a regression from 1.0.7.
I'm unable to connect to *any* database. The problem seems to be related to IPv6.

The exception thrown at Open():
"Unable to connect to any of the specified MySQL hosts"

in MySql.Data.MySqlClient.NativeDriver.Open()
in MySql.Data.MySqlClient.Driver.Create(MySqlConnectionString settings)
in MySql.Data.MySqlClient.MySqlPool.CreateNewPooledConnection()
in MySql.Data.MySqlClient.MySqlPool.GetPooledConnection()
in MySql.Data.MySqlClient.MySqlPool.GetConnection()
in MySql.Data.MySqlClient.MySqlConnection.Open()

The inner exception is far more interesting ;)

"Address not compatible with the specified protocol" (my translation, I see the localized message, anyway error code is 10047).

in System.Net.Sockets.Socket.DoBeginConnect(EndPoint endPointSnapshot, SocketAddress socketAddress, LazyAsyncResult asyncResult)
in System.Net.Sockets.Socket.BeginConnect(EndPoint remoteEP, AsyncCallback callback, Object state)
in MySql.Data.Common.StreamCreator.CreateSocketStream(IPAddress ip, Int32 port, Boolean unix) in C:\Programmi\mysql\MySQL Connector Net 1.0.8\Source\MySqlClient\common\StreamCreator.cs:riga 134
in MySql.Data.Common.StreamCreator.GetStream(UInt32 timeOut) in C:\Programmi\mysql\MySQL Connector Net 1.0.8\Source\MySqlClient\common\StreamCreator.cs:riga 80
in MySql.Data.MySqlClient.NativeDriver.Open() in C:\Programmi\mysql\MySQL Connector Net 1.0.8\Source\MySqlClient\nativedriver.cs:riga 145

My analysis:

Connection string:
Host=localhost;Database=dbname;User Id=myuser;Password=pass

What I see is that StreamCreator.GetStream() gets the IP address(es) of the host using:

  IPHostEntry ipHE = Dns.GetHostEntry(dnsHosts[index]);
(line 73)

On my system IPv6 networking is enabled, so the resulting address list contains IPv6 addresses and IPv4 address is the last of the list. Please note that I'm *not* trying to connect to a v6 address.
Afterwards StreamCreator.GetStream() pass down each address to CreateSocketStream() until one is successful. Problem is that inside CreateSocketStream() the socket is created using AF "InterNetwork" (lines 131-133); BeginConnect() is called on this socket using a v6 address and throws an exception. The outer loop cannot handle the exception which propagates back and prevent any connection.

1.0.7 does not exhibit this behaviour.

How to repeat:
string connStr = "Host=localhost;Database=dbname;User Id=myuser;Password=pass"
MySqlConnection conn = new MySqlConnection(connStr);
conn.Open();

IPv6 networking must be enabled.

Suggested fix:
Skip any IPv6 address returned by GetHostEntry. I've modified the loop in StreamCreator.GetStream() in this way:

foreach (IPAddress address in ipHE.AddressList)
{
	/* Skip IPv6 addresses */
	if (address.AddressFamily == AddressFamily.InterNetworkV6)
		continue;
	stream = CreateSocketStream(address, port, false);
	if (stream != null)
		break;
}

(I'd send a patch but I can't find a way to attach a file...)
[29 Oct 2006 23:37] Luca Tettamanti
Bugfix, unified diff patch

Attachment: open-ipv6.diff (application/octet-stream, text), 464 bytes.

[29 Oct 2006 23:39] Luca Tettamanti
Ok, I managed to attach the patch, unified diff format.
[30 Oct 2006 16:22] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/14571
[30 Oct 2006 16:25] Bugs System
A patch for this bug has been committed. After review, it may
be pushed to the relevant source trees for release in the next
version. You can access the patch from:

  http://lists.mysql.com/commits/14572
[6 Nov 2006 14:11] MC Brown
A note has been added to the 5.0.2 and 1.0.9 changelogs.