Details
-
Bug
-
Resolution: Invalid
-
Not Evaluated
-
None
-
4.6.2
-
None
-
Windows 7, VC 2008 SP1
tested on Windows 2008 R2
Description
When connecting to localhost on an IPV6 enabled system (tested with Windows 7 / Windows 2008 R2), the connection takes one second. The reason is that it connects first to 0:0:0:0:0:0:0:1 (and the system answers 1 second later) and then to 127.0.0.1.
In qhostinfo_win.cpp, you can see in QHostInfo QHostInfoAgent::fromName(const QString &hostName):
// Call getaddrinfo, and place all IPv4 addresses at the start // and the IPv6 addresses at the end of the address list in // results.
But the code below is:
switch (p->ai_family) { case AF_INET: { QHostAddress addr; addr.setAddress(ntohl(((sockaddr_in *) p->ai_addr)->sin_addr.s_addr)); if (!addresses.contains(addr)) addresses.append(addr); } break; case AF_INET6: { QHostAddress addr; addr.setAddress(((qt_sockaddr_in6 *) p->ai_addr)->sin6_addr.qt_s6_addr); if (!addresses.contains(addr)) addresses.append(addr); }
so any address is appended to the list, which makes that the order is not IPV4 - IPV6, but the order returned by getaddrinfo.
A solution could be to write:
case AF_INET:
{ QHostAddress addr; addr.setAddress(ntohl(((sockaddr_in *) p->ai_addr)->sin_addr.s_addr)); if (!addresses.contains(addr)) addresses.prepend(addr); }to prepend IPV4 addresses to the list.
Here's the output of a connect with QHOSTINFO_DEBUG and QABSTRACTSOCKET_DEBUG defined:
QAbstractSocket::QAbstractSocket(TcpSocket, QAbstractSocketPrivate == 0xa6ed38,parent == 0x0)
16 - connect to "localhost" : 6394
QAbstractSocket::connectToHost("localhost", 6394, 3)...
QHostInfo::lookupHost("localhost", 0x24ccb8, _q_startConnecting(QHostInfo))
QAbstractSocket::connectToHost("localhost", 6394) == false (connection in progress)
QAbstractSocket::waitForConnected(5000)
QAbstractSocket::waitForConnected(5000) doing host name lookup
QHostInfo::fromName("localhost")
QHostInfoAgent::fromName(0x0): looking up "localhost" (IPv6 support is enabled)
QHostInfoAgent::run(0x0): found 2 entries:
QAbstractSocketPrivate::_q_startConnecting(hostInfo ==
{0:0:0:0:0:0:0:1, 127.0.0.1})
QAbstractSocketPrivate::_q_connectToNextAddress(), connecting to 0:0:0:0:0:0:0:1:6394, 3 left to try
QAbstractSocketPrivate::resetSocketLayer()
QAbstractSocketPrivate::initSocketLayer(TcpSocket, IPv6Protocol) success
QAbstractSocket::waitForConnected(5000) waiting 4.66 secs for connection attempt #1
QAbstractSocketPrivate::_q_connectToNextAddress(), connecting to 127.0.0.1:6394, 2 left to try
QAbstractSocketPrivate::resetSocketLayer()
QAbstractSocketPrivate::initSocketLayer(TcpSocket, IPv4Protocol) success
QAbstractSocket::waitForConnected(5000) waiting 3.63 secs for connection attempt #2
QAbstractSocketPrivate::fetchConnectionParameters() connection to 127.0.0.1:6394 established
QAbstractSocket::waitForConnected(5000) == true
QAbstractSocket::close()
QAbstractSocket::disconnectFromHost()
QAbstractSocket::disconnectFromHost() emits stateChanged()(ClosingState)
QAbstractSocket::disconnectFromHost() disconnecting immediately
QAbstractSocketPrivate::resetSocketLayer()
QAbstractSocket::disconnectFromHost() disconnected!
QAbstractSocket::disconnectFromHost() closed!
QAbstractSocket::~QAbstractSocket()
you can see that it connects first to ipv6 localhost, and one second later to ipv4 one.