Bug 684893 - part2: Happy-Eyeballs + let backup socket transport retry with both IPv4+6 on IPv6-only connection attempt failure, r=mcmanus
authorHonza Bambas <honzab.moz@firemni.cz>
Wed, 02 Nov 2011 17:18:54 +0100
changeset 79626 3af633ba04ab8bcee4277e796a927e9ceefc2865
parent 79625 790fff5fd07a4886ceb4cf87c65ab4b4f981b0b8
child 79627 e672c96a4fe4755006d822e126ac06c2535fab75
push id21418
push usermak77@bonardo.net
push dateThu, 03 Nov 2011 14:57:14 +0000
treeherdermozilla-central@6cbeabc07c59 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersmcmanus
bugs684893
milestone10.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 684893 - part2: Happy-Eyeballs + let backup socket transport retry with both IPv4+6 on IPv6-only connection attempt failure, r=mcmanus
modules/libpref/src/init/all.js
netwerk/base/src/nsSocketTransport2.cpp
--- a/modules/libpref/src/init/all.js
+++ b/modules/libpref/src/init/all.js
@@ -786,17 +786,17 @@ pref("network.http.qos", 0);
 
 // The number of milliseconds after sending a SYN for an HTTP connection,
 // to wait before trying a different connection. 0 means do not use a second
 // connection.
 pref("network.http.connection-retry-timeout", 250);
 
 // Disable IPv6 for backup connections to workaround problems about broken
 // IPv6 connectivity.
-pref("network.http.fast-fallback-to-IPv4", false);
+pref("network.http.fast-fallback-to-IPv4", true);
 
 // default values for FTP
 // in a DSCP environment this should be 40 (0x28, or AF11), per RFC-4594,
 // Section 4.8 "High-Throughput Data Service Class", and 80 (0x50, or AF22)
 // per Section 4.7 "Low-Latency Data Service Class".
 pref("network.ftp.data.qos", 0);
 pref("network.ftp.control.qos", 0);
 
--- a/netwerk/base/src/nsSocketTransport2.cpp
+++ b/netwerk/base/src/nsSocketTransport2.cpp
@@ -1252,38 +1252,59 @@ nsSocketTransport::RecoverFromError()
 
     SOCKET_LOG(("nsSocketTransport::RecoverFromError [this=%x state=%x cond=%x]\n",
         this, mState, mCondition));
 
     // can only recover from errors in these states
     if (mState != STATE_RESOLVING && mState != STATE_CONNECTING)
         return false;
 
+    nsresult rv;
+
     // OK to check this outside mLock
     NS_ASSERTION(!mFDconnected, "socket should not be connected");
 
     // can only recover from these errors
     if (mCondition != NS_ERROR_CONNECTION_REFUSED &&
         mCondition != NS_ERROR_PROXY_CONNECTION_REFUSED &&
         mCondition != NS_ERROR_NET_TIMEOUT &&
         mCondition != NS_ERROR_UNKNOWN_HOST &&
         mCondition != NS_ERROR_UNKNOWN_PROXY_HOST)
         return false;
 
     bool tryAgain = false;
 
+    if (mConnectionFlags & DISABLE_IPV6 &&
+        mCondition == NS_ERROR_UNKNOWN_HOST &&
+        mState == STATE_RESOLVING &&
+        !mProxyTransparentResolvesHost) {
+        SOCKET_LOG(("  trying lookup again with both ipv4/ipv6 enabled\n"));
+        mConnectionFlags &= ~DISABLE_IPV6;
+        tryAgain = true;
+    }
+
     // try next ip address only if past the resolver stage...
     if (mState == STATE_CONNECTING && mDNSRecord) {
         mDNSRecord->ReportUnusable(SocketPort());
         
         nsresult rv = mDNSRecord->GetNextAddr(SocketPort(), &mNetAddr);
         if (NS_SUCCEEDED(rv)) {
             SOCKET_LOG(("  trying again with next ip address\n"));
             tryAgain = true;
         }
+        else if (mConnectionFlags & DISABLE_IPV6) {
+            // Drop state to closed.  This will trigger new round of DNS
+            // resolving bellow.
+            // XXX Here should idealy be set now non-existing flag DISABLE_IPV4
+            SOCKET_LOG(("  failed to connect all ipv4 hosts,"
+                        " trying lookup/connect again with both ipv4/ipv6\n"));
+            mState = STATE_CLOSED;
+            mConnectionFlags &= ~DISABLE_IPV6;
+            tryAgain = true;
+        }
     }
 
 #if defined(XP_WIN) || defined(MOZ_PLATFORM_MAEMO)
     // If not trying next address, try to make a connection using dialup. 
     // Retry if that connection is made.
     if (!tryAgain) {
         bool autodialEnabled;
         gSocketTransportService->GetAutodialEnabled(&autodialEnabled);
@@ -1291,17 +1312,16 @@ nsSocketTransport::RecoverFromError()
           tryAgain = nsNativeConnectionHelper::OnConnectionFailed(
                        NS_ConvertUTF8toUTF16(SocketHost()).get());
 	    }
     }
 #endif
 
     // prepare to try again.
     if (tryAgain) {
-        nsresult rv;
         PRUint32 msg;
 
         if (mState == STATE_CONNECTING) {
             mState = STATE_RESOLVING;
             msg = MSG_DNS_LOOKUP_COMPLETE;
         }
         else {
             mState = STATE_CLOSED;