Bug #19726 Connection fails to localhost when using timeout and ipv6 is configured
Submitted: 11 May 2006 13:38 Modified: 26 Jul 2006 18:17
Reporter: Erik Ekman Email Updates:
Status: Closed Impact on me:
None 
Category:Connector / J Severity:S3 (Non-critical)
Version:5.0.0 and 3.1.12 OS:Linux (Linux)
Assigned to: Mark Matthews CPU Architecture:Any

[11 May 2006 13:38] Erik Ekman
Description:
We have a linux computer running MySQL 5 listening to ipv4 ip and to socket. Our java program tries to connect to it via URL jdbc:mysql://localhost:33306/sim?connectTimeout=4000.

The linux machine is configured with IPv6, so the localhost name points to both ::1 and to 127.0.0.1. When using this URL, we get a ConnectException with Connection refused as a message. We found out that it tried to connect to the IPv6 address twice, instead of first to the IPv6 and then to the IPv4.

We use Java 1.4.2_03 on Suse SLES 9.

How to repeat:
Have a MySQL server listening to 127.0.0.1 on linux with ipv6 configured.
Connect to jdbc:mysql://localhost/sim?connectTimeout=4000 with java.
A In

Suggested fix:
In com.mysql.jdbc.StandardSocketFactory lines 165 to 182, change this:
==========================================
Constructor addrConstructor = inetSocketAddressClass
		.getConstructor(new Class[] { String.class,
				Integer.TYPE });

InetAddress[] possibleAddresses = InetAddress
		.getAllByName(this.host);

Exception caughtWhileConnecting = null;

// Need to loop through all possible addresses, in case
// someone has IPV6 configured (SuSE, for example...)

for (int i = 0; i < possibleAddresses.length; i++) {

	try {
		Object sockAddr = addrConstructor
				.newInstance(new Object[] { this.host,
						new Integer(port) });
===========================================
to this:
=============================================
Constructor addrConstructor = inetSocketAddressClass
		.getConstructor(new Class[] { InetAddress.class,
				Integer.TYPE });

InetAddress[] possibleAddresses = InetAddress
		.getAllByName(this.host);

Exception caughtWhileConnecting = null;

// Need to loop through all possible addresses, in case
// someone has IPV6 configured (SuSE, for example...)

for (int i = 0; i < possibleAddresses.length; i++) {
	
	try {
		Object sockAddr = addrConstructor
				.newInstance(new Object[] { possibleAddresses[i],
						new Integer(port) });
============================================
The difference is that we use the constructor that takes an InetAddress instead of a String on line 166, and that we actually use the possibleAddresses[i] instead of this.host in the constructor on line 181. This way we first try the IPv6 address and then the IPv4 address, and connection is successful.
[11 May 2006 13:45] Erik Ekman
The same error is also in Connector/J version 5.0.0.
[11 May 2006 13:50] Erik Ekman
(Changed version in bug)
[11 May 2006 13:54] Erik Ekman
Probably the error was introduced in the fix from bug #6348
[16 Jun 2006 18:35] 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/7780