Happy Eyeballs: Make sure that we commit the address type for SSL connections
authorJocelyn Turcotte <jocelyn.turcotte@digia.com>
Mon, 15 Oct 2012 12:35:19 +0000 (14:35 +0200)
committerThe Qt Project <gerrit-noreply@qt-project.org>
Thu, 25 Oct 2012 14:23:49 +0000 (16:23 +0200)
_q_connected checks if pendingEncrypt is false before committing the
address type. This could be used to delay the commit but nothing is done
later in _q_encrypted, so the commit is avoided completely.

This causes SSL connections on a network without IPV6 support to hang
if the domain name record contains both IPV4 and IPV6 addresses.

As SSL is handled a few layers above IP, there should be no reason to
avoid/delay committing the address type if the TCP connection was
established surccessfully. Thus this patch is removing the check completely.

Change-Id: If56a3365f9f51712b4aae3f7902711711ace86fd
Reviewed-by: Shane Kearns <shane.kearns@accenture.com>
src/network/access/qhttpnetworkconnectionchannel.cpp

index a3e46d8..51076c6 100644 (file)
@@ -1025,31 +1025,29 @@ void QHttpNetworkConnectionChannel::_q_disconnected()
 void QHttpNetworkConnectionChannel::_q_connected()
 {
     // For the Happy Eyeballs we need to check if this is the first channel to connect.
-    if (!pendingEncrypt) {
-        if (connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::InProgress) {
-            if (connection->d_func()->delayedConnectionTimer.isActive())
-                connection->d_func()->delayedConnectionTimer.stop();
-            if (networkLayerPreference == QAbstractSocket::IPv4Protocol)
+    if (connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::InProgress) {
+        if (connection->d_func()->delayedConnectionTimer.isActive())
+            connection->d_func()->delayedConnectionTimer.stop();
+        if (networkLayerPreference == QAbstractSocket::IPv4Protocol)
+            connection->d_func()->networkLayerState = QHttpNetworkConnectionPrivate::IPv4;
+        else if (networkLayerPreference == QAbstractSocket::IPv6Protocol)
+            connection->d_func()->networkLayerState = QHttpNetworkConnectionPrivate::IPv6;
+        else {
+            if (socket->peerAddress().protocol() == QAbstractSocket::IPv4Protocol)
                 connection->d_func()->networkLayerState = QHttpNetworkConnectionPrivate::IPv4;
-            else if (networkLayerPreference == QAbstractSocket::IPv6Protocol)
+            else
                 connection->d_func()->networkLayerState = QHttpNetworkConnectionPrivate::IPv6;
-            else {
-                if (socket->peerAddress().protocol() == QAbstractSocket::IPv4Protocol)
-                    connection->d_func()->networkLayerState = QHttpNetworkConnectionPrivate::IPv4;
-                else
-                    connection->d_func()->networkLayerState = QHttpNetworkConnectionPrivate::IPv6;
-            }
-            connection->d_func()->networkLayerDetected(networkLayerPreference);
-        } else {
-            if (((connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv4) && (networkLayerPreference != QAbstractSocket::IPv4Protocol))
-                || ((connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv6) && (networkLayerPreference != QAbstractSocket::IPv6Protocol))) {
-                close();
-                // This is the second connection so it has to be closed and we can schedule it for another request.
-                QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
-                return;
-            }
-            //The connections networkLayerState had already been decided.
         }
+        connection->d_func()->networkLayerDetected(networkLayerPreference);
+    } else {
+        if (((connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv4) && (networkLayerPreference != QAbstractSocket::IPv4Protocol))
+            || ((connection->d_func()->networkLayerState == QHttpNetworkConnectionPrivate::IPv6) && (networkLayerPreference != QAbstractSocket::IPv6Protocol))) {
+            close();
+            // This is the second connection so it has to be closed and we can schedule it for another request.
+            QMetaObject::invokeMethod(connection, "_q_startNextRequest", Qt::QueuedConnection);
+            return;
+        }
+        //The connections networkLayerState had already been decided.
     }
 
     // improve performance since we get the request sent by the kernel ASAP