Bug #23758 Unable to connect to any server - IPv6 related
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...)
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.055 sec. using MySQL 8.4.7-u6-cloud
Timestamp references displayed by the system are UTC.
Content reproduced on this site is the property of the
respective copyright holders.
It is not reviewed in advance
by Oracle and does not necessarily represent the opinion of
Oracle or any other party.
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...)