bug 1153212 - Alt-Svc Fixes and re-enable r=dkeeler r=hurley a=sylvestre
authorPatrick McManus <mcmanus@ducksong.com>
Fri, 01 May 2015 09:58:39 -0400
changeset 265842 4c40f581d01d6d6bfb9e2b5748241851d27387a2
parent 265841 b5527b393f628a7e000646dad27577a86de6498e
child 265843 386c5f297cc4e7a0525689635f0c2526271c0f4a
push id4718
push userraliiev@mozilla.com
push dateMon, 11 May 2015 18:39:53 +0000
treeherdermozilla-beta@c20c4ef55f08 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdkeeler, hurley, sylvestre
bugs1153212
milestone39.0a2
bug 1153212 - Alt-Svc Fixes and re-enable r=dkeeler r=hurley a=sylvestre
modules/libpref/init/all.js
netwerk/protocol/http/nsHttpConnectionInfo.h
netwerk/protocol/http/nsHttpConnectionMgr.cpp
security/manager/ssl/src/nsNSSIOLayer.cpp
security/manager/ssl/src/nsNSSIOLayer.h
--- a/modules/libpref/init/all.js
+++ b/modules/libpref/init/all.js
@@ -1326,20 +1326,20 @@ pref("network.http.spdy.ping-threshold",
 pref("network.http.spdy.ping-timeout", 8);
 pref("network.http.spdy.send-buffer-size", 131072);
 pref("network.http.spdy.allow-push", true);
 pref("network.http.spdy.push-allowance", 131072);
 pref("network.http.spdy.default-concurrent", 100);
 
 // alt-svc allows separation of transport routing from
 // the origin host without using a proxy.
-pref("network.http.atsvc.enabled", false);
-pref("network.http.atsvc.oe", false);
-pref("network.http.altsvc.enabled", false);
-pref("network.http.altsvc.oe", false);
+pref("network.http.atsvc.enabled", true);
+pref("network.http.atsvc.oe", true);
+pref("network.http.altsvc.enabled", true);
+pref("network.http.altsvc.oe", true);
 
 pref("network.http.diagnostics", false);
 
 pref("network.http.pacing.requests.enabled", true);
 pref("network.http.pacing.requests.min-parallelism", 6);
 pref("network.http.pacing.requests.hz", 100);
 pref("network.http.pacing.requests.burst", 32);
 
--- a/netwerk/protocol/http/nsHttpConnectionInfo.h
+++ b/netwerk/protocol/http/nsHttpConnectionInfo.h
@@ -56,16 +56,19 @@ private:
     }
 
 public:
     const nsAFlatCString &HashKey() const { return mHashKey; }
 
     const nsCString &GetAuthenticationHost() const { return mAuthenticationHost; }
     int32_t GetAuthenticationPort() const { return mAuthenticationPort; }
 
+    const nsCString &GetOrigin() const { return mAuthenticationHost.IsEmpty() ? mHost : mAuthenticationHost; }
+    int32_t OriginPort() const { return mAuthenticationHost.IsEmpty() ? mPort : mAuthenticationPort; }
+
     // OK to treat these as an infalible allocation
     nsHttpConnectionInfo* Clone() const;
     void CloneAsDirectRoute(nsHttpConnectionInfo **outParam);
     nsresult CreateWildCard(nsHttpConnectionInfo **outParam);
 
     const char *ProxyHost() const { return mProxyInfo ? mProxyInfo->Host().get() : nullptr; }
     int32_t     ProxyPort() const { return mProxyInfo ? mProxyInfo->Port() : -1; }
     const char *ProxyType() const { return mProxyInfo ? mProxyInfo->Type() : nullptr; }
--- a/netwerk/protocol/http/nsHttpConnectionMgr.cpp
+++ b/netwerk/protocol/http/nsHttpConnectionMgr.cpp
@@ -875,18 +875,18 @@ nsHttpConnectionMgr::GetSpdyPreferredEnt
     }
 
     // try all the spdy versions we support.
     const SpdyInformation *info = gHttpHandler->SpdyInfo();
     for (uint32_t index = SpdyInformation::kCount;
          NS_SUCCEEDED(rv) && index > 0; --index) {
         if (info->ProtocolEnabled(index - 1)) {
             rv = sslSocketControl->JoinConnection(info->VersionString[index - 1],
-                                                  aOriginalEntry->mConnInfo->GetHost(),
-                                                  aOriginalEntry->mConnInfo->Port(),
+                                                  aOriginalEntry->mConnInfo->GetOrigin(),
+                                                  aOriginalEntry->mConnInfo->OriginPort(),
                                                   &isJoined);
             if (NS_SUCCEEDED(rv) && isJoined) {
                 break;
             }
         }
     }
 
     if (NS_FAILED(rv) || !isJoined) {
--- a/security/manager/ssl/src/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/src/nsNSSIOLayer.cpp
@@ -190,18 +190,26 @@ nsNSSSocketInfo::GetBypassAuthentication
 {
   *arg = mBypassAuthentication;
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNSSSocketInfo::SetBypassAuthentication(bool arg)
 {
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+  if (!mFd) {
+    return NS_ERROR_FAILURE;
+  }
+
   mBypassAuthentication = arg;
-  return NS_OK;
+  return SyncNSSNames(locker);
 }
 
 NS_IMETHODIMP
 nsNSSSocketInfo::GetFailedVerification(bool* arg)
 {
   *arg = mFailedVerification;
   return NS_OK;
 }
@@ -211,29 +219,59 @@ nsNSSSocketInfo::GetAuthenticationName(n
 {
   aAuthenticationName = GetHostName();
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsNSSSocketInfo::SetAuthenticationName(const nsACString& aAuthenticationName)
 {
-  return SetHostName(PromiseFlatCString(aAuthenticationName).get());
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+  if (!mFd) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsCString authenticationName(aAuthenticationName);
+  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
+         ("[%p] nsNSSSocketInfo::SetAuthenticationName change from %s to %s\n",
+          mFd, PromiseFlatCString(GetHostName()).get(),
+          authenticationName.get()));
+
+  nsresult rv = SetHostName(authenticationName.get());
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  return SyncNSSNames(locker);
 }
 
 NS_IMETHODIMP
 nsNSSSocketInfo::GetAuthenticationPort(int32_t* aAuthenticationPort)
 {
   return GetPort(aAuthenticationPort);
 }
 
 NS_IMETHODIMP
 nsNSSSocketInfo::SetAuthenticationPort(int32_t aAuthenticationPort)
 {
-  return SetPort(aAuthenticationPort);
+  nsNSSShutDownPreventionLock locker;
+  if (isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+  if (!mFd) {
+    return NS_ERROR_FAILURE;
+  }
+
+  nsresult rv = SetPort(aAuthenticationPort);
+  if (NS_FAILED(rv)) {
+    return rv;
+  }
+  return SyncNSSNames(locker);
 }
 
 NS_IMETHODIMP
 nsNSSSocketInfo::GetRememberClientAuthCertificate(bool* aRemember)
 {
   NS_ENSURE_ARG_POINTER(aRemember);
   *aRemember = mRememberClientAuthCertificate;
   return NS_OK;
@@ -262,16 +300,46 @@ nsNSSSocketInfo::SetNotificationCallback
     return NS_OK;
   }
 
   mCallbacks = aCallbacks;
 
   return NS_OK;
 }
 
+// forward declare this for SyncNSSNames()
+static nsresult
+nsSSLIOLayerSetPeerName(PRFileDesc* fd, nsNSSSocketInfo* infoObject,
+                        const char* host, int32_t port,
+                        const nsNSSShutDownPreventionLock& /* proofOfLock */);
+
+nsresult
+nsNSSSocketInfo::SyncNSSNames(const nsNSSShutDownPreventionLock& proofOfLock)
+{
+  // I don't know why any of these calls would fail, but if they do
+  // we need to call SetCanceled to avoid non-determinstic results
+
+  const char* hostName = GetHostNameRaw();
+  if (SECSuccess != SSL_SetURL(mFd, hostName)) {
+    PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("[%p] SyncNSSNames SSL_SetURL error: %d\n",
+                                      (void*) mFd, PR_GetError()));
+    SetCanceled(PR_INVALID_STATE_ERROR, PlainErrorMessage);
+    return NS_ERROR_FAILURE;
+  }
+
+  int32_t port = GetPort();
+  if (NS_FAILED(nsSSLIOLayerSetPeerName(mFd, this, hostName, port, proofOfLock))) {
+    PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("[%p] SyncNSSNames SetPeerName error: %d\n",
+                                      (void*) mFd, PR_GetError()));
+    SetCanceled(PR_INVALID_STATE_ERROR, PlainErrorMessage);
+    return NS_ERROR_FAILURE;
+  }
+  return NS_OK;
+}
+
 void
 nsNSSSocketInfo::NoteTimeUntilReady()
 {
   if (mNotedTimeUntilReady)
     return;
 
   mNotedTimeUntilReady = true;
 
@@ -441,16 +509,22 @@ nsNSSSocketInfo::JoinConnection(const ns
   // Different ports may not be joined together
   if (port != GetPort())
     return NS_OK;
 
   // Make sure NPN has been completed and matches requested npnProtocol
   if (!mNPNCompleted || !mNegotiatedNPN.Equals(npnProtocol))
     return NS_OK;
 
+  if (mBypassAuthentication) {
+    // An unauthenticated connection does not know whether or not it
+    // is acceptable for a particular hostname
+    return NS_OK;
+  }
+
   IsAcceptableForHost(hostname, _retval);
 
   if (*_retval) {
     // All tests pass - this is joinable
     mJoined = true;
   }
   return NS_OK;
 }
@@ -2540,21 +2614,54 @@ nsSSLIOLayerImportFD(PRFileDesc* fd,
 loser:
   if (sslSock) {
     PR_Close(sslSock);
   }
   return nullptr;
 }
 
 static nsresult
+nsSSLIOLayerSetPeerName(PRFileDesc* fd, nsNSSSocketInfo* infoObject,
+                        const char* host, int32_t port,
+                        const nsNSSShutDownPreventionLock& /*proofOfLock*/)
+{
+  // Set the Peer ID so that SSL proxy connections work properly and to
+  // separate anonymous and/or private browsing connections.
+  uint32_t flags = infoObject->GetProviderFlags();
+  nsAutoCString peerId;
+  if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080
+    peerId.AppendLiteral("anon:");
+  }
+  if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) {
+    peerId.AppendLiteral("private:");
+  }
+  if (infoObject->GetBypassAuthentication()) {
+    peerId.AppendLiteral("bypassAuth:");
+  }
+  peerId.Append(host);
+  peerId.Append(':');
+  peerId.AppendInt(port);
+  PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
+         ("[%p] nsSSLIOLayerSetPeerName to %s\n", fd, peerId.get()));
+  if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) {
+    return NS_ERROR_FAILURE;
+  }
+  return NS_OK;
+}
+
+static nsresult
 nsSSLIOLayerSetOptions(PRFileDesc* fd, bool forSTARTTLS,
                        const char* proxyHost, const char* host, int32_t port,
                        nsNSSSocketInfo* infoObject)
 {
   nsNSSShutDownPreventionLock locker;
+  if (infoObject->isAlreadyShutDown()) {
+    return NS_ERROR_NOT_AVAILABLE;
+  }
+
   if (forSTARTTLS || proxyHost) {
     if (SECSuccess != SSL_OptionSet(fd, SSL_SECURITY, false)) {
       return NS_ERROR_FAILURE;
     }
   }
 
   // Let's see if we're trying to connect to a site we know is
   // TLS intolerant.
@@ -2600,34 +2707,17 @@ nsSSLIOLayerSetOptions(PRFileDesc* fd, b
   if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_OCSP_STAPLING, enabled)) {
     return NS_ERROR_FAILURE;
   }
 
   if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) {
     return NS_ERROR_FAILURE;
   }
 
-  // Set the Peer ID so that SSL proxy connections work properly and to
-  // separate anonymous and/or private browsing connections.
-  uint32_t flags = infoObject->GetProviderFlags();
-  nsAutoCString peerId;
-  if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080
-    peerId.AppendLiteral("anon:");
-  }
-  if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) {
-    peerId.AppendLiteral("private:");
-  }
-  peerId.Append(host);
-  peerId.Append(':');
-  peerId.AppendInt(port);
-  if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) {
-    return NS_ERROR_FAILURE;
-  }
-
-  return NS_OK;
+  return nsSSLIOLayerSetPeerName(fd, infoObject, host, port, locker);
 }
 
 nsresult
 nsSSLIOLayerAddToSocket(int32_t family,
                         const char* host,
                         int32_t port,
                         const char* proxyHost,
                         int32_t proxyPort,
--- a/security/manager/ssl/src/nsNSSIOLayer.h
+++ b/security/manager/ssl/src/nsNSSIOLayer.h
@@ -131,16 +131,17 @@ private:
   mozilla::psm::SharedSSLState& mSharedState;
   bool mForSTARTTLS;
   SSLVersionRange mTLSVersionRange;
   bool mHandshakePending;
   bool mRememberClientAuthCertificate;
   bool mPreliminaryHandshakeDone; // after false start items are complete
 
   nsresult ActivateSSL();
+  nsresult SyncNSSNames(const nsNSSShutDownPreventionLock& proofOfLock);
 
   nsCString mNegotiatedNPN;
   bool      mNPNCompleted;
   bool      mFalseStartCallbackCalled;
   bool      mFalseStarted;
   bool      mIsFullHandshake;
   bool      mHandshakeCompleted;
   bool      mJoined;