Bug #19726 Connection fails to localhost when using timeout and ipv6 is configured
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.
Portions of this website are copyright © 2001, 2002 The PHP Group
Page generated in 0.039 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: 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.