Uploaded image for project: 'Qt'
  1. Qt
  2. QTBUG-9572

QHostInfo returns first IPV6 address while it should return IPV4 first

    XMLWordPrintable

Details

    • Bug
    • Resolution: Invalid
    • Not Evaluated
    • None
    • 4.6.2
    • Network
    • 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:

      {0:0:0:0:0:0:0:1, 127.0.0.1}

      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.

      Attachments

        No reviews matched the request. Check your Options in the drop-down menu of this sections header.

        Activity

          People

            tmacieir Thiago Macieira (closed Nokia identity) (Inactive)
            sysedit Pierre-Nicolas Rigal
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved:

              Gerrit Reviews

                There are no open Gerrit changes