Bug 1084025 - Add telemetry to measure failures due to not falling back. r=keeler, a=lsblakk
authorMasatoshi Kimura <VYV03354@nifty.ne.jp>
Tue, 09 Dec 2014 07:19:05 +0900
changeset 234303 409a02246b8a
parent 234302 29f65673850d
child 234304 447fb28e81cf
push id7359
push userryanvm@gmail.com
push dateMon, 15 Dec 2014 17:06:30 +0000
treeherdermozilla-aurora@6f4775cbadf1 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerskeeler, lsblakk
bugs1084025
milestone36.0a2
Bug 1084025 - Add telemetry to measure failures due to not falling back. r=keeler, a=lsblakk
security/manager/ssl/src/nsNSSIOLayer.cpp
security/manager/ssl/src/nsNSSIOLayer.h
toolkit/components/telemetry/Histograms.json
--- a/security/manager/ssl/src/nsNSSIOLayer.cpp
+++ b/security/manager/ssl/src/nsNSSIOLayer.cpp
@@ -865,50 +865,95 @@ nsSSLIOLayerHelpers::rememberTolerantAtV
     entry.strongCipherStatus = StrongCiphersWorked;
   }
 
   entry.AssertInvariant();
 
   mTLSIntoleranceInfo.Put(key, entry);
 }
 
-void nsSSLIOLayerHelpers::forgetIntolerance(const nsACString& hostName,
-                                            int16_t port)
+uint16_t
+nsSSLIOLayerHelpers::forgetIntolerance(const nsACString& hostName,
+                                       int16_t port)
 {
   nsCString key;
   getSiteKey(hostName, port, key);
 
   MutexAutoLock lock(mutex);
 
+  uint16_t tolerant = 0;
   IntoleranceEntry entry;
   if (mTLSIntoleranceInfo.Get(key, &entry)) {
     entry.AssertInvariant();
 
+    tolerant = entry.tolerant;
     entry.intolerant = 0;
     entry.intoleranceReason = 0;
     if (entry.strongCipherStatus != StrongCiphersWorked) {
       entry.strongCipherStatus = StrongCipherStatusUnknown;
     }
 
     entry.AssertInvariant();
     mTLSIntoleranceInfo.Put(key, entry);
   }
+
+  return tolerant;
 }
 
 // returns true if we should retry the handshake
 bool
 nsSSLIOLayerHelpers::rememberIntolerantAtVersion(const nsACString& hostName,
                                                  int16_t port,
                                                  uint16_t minVersion,
                                                  uint16_t intolerant,
                                                  PRErrorCode intoleranceReason)
 {
   if (intolerant <= minVersion || intolerant <= mVersionFallbackLimit) {
     // We can't fall back any further. Assume that intolerance isn't the issue.
-    forgetIntolerance(hostName, port);
+    uint32_t tolerant = forgetIntolerance(hostName, port);
+    // If we know the server is tolerant at the version, we don't have to
+    // gather the telemetry.
+    if (intolerant <= tolerant) {
+      return false;
+    }
+
+    uint32_t fallbackLimitBucket = 0;
+    // added if the version has reached the min version.
+    if (intolerant <= minVersion) {
+      switch (minVersion) {
+        case SSL_LIBRARY_VERSION_TLS_1_0:
+          fallbackLimitBucket += 1;
+          break;
+        case SSL_LIBRARY_VERSION_TLS_1_1:
+          fallbackLimitBucket += 2;
+          break;
+        case SSL_LIBRARY_VERSION_TLS_1_2:
+          fallbackLimitBucket += 3;
+          break;
+      }
+    }
+    // added if the version has reached the fallback limit.
+    if (intolerant <= mVersionFallbackLimit) {
+      switch (mVersionFallbackLimit) {
+        case SSL_LIBRARY_VERSION_TLS_1_0:
+          fallbackLimitBucket += 4;
+          break;
+        case SSL_LIBRARY_VERSION_TLS_1_1:
+          fallbackLimitBucket += 8;
+          break;
+        case SSL_LIBRARY_VERSION_TLS_1_2:
+          fallbackLimitBucket += 12;
+          break;
+      }
+    }
+    if (fallbackLimitBucket) {
+      Telemetry::Accumulate(Telemetry::SSL_FALLBACK_LIMIT_REACHED,
+                            fallbackLimitBucket);
+    }
+
     return false;
   }
 
   nsCString key;
   getSiteKey(hostName, port, key);
 
   MutexAutoLock lock(mutex);
 
--- a/security/manager/ssl/src/nsNSSIOLayer.h
+++ b/security/manager/ssl/src/nsNSSIOLayer.h
@@ -220,17 +220,19 @@ private:
 public:
   void rememberTolerantAtVersion(const nsACString& hostname, int16_t port,
                                  uint16_t tolerant);
   bool rememberIntolerantAtVersion(const nsACString& hostname, int16_t port,
                                    uint16_t intolerant, uint16_t minVersion,
                                    PRErrorCode intoleranceReason);
   bool rememberStrongCiphersFailed(const nsACString& hostName, int16_t port,
                                    PRErrorCode intoleranceReason);
-  void forgetIntolerance(const nsACString& hostname, int16_t port);
+  // returns the known tolerant version
+  // or 0 if there is no known tolerant version
+  uint16_t forgetIntolerance(const nsACString& hostname, int16_t port);
   void adjustForTLSIntolerance(const nsACString& hostname, int16_t port,
                                /*in/out*/ SSLVersionRange& range,
                                /*out*/ StrongCipherStatus& strongCipherStatus);
   PRErrorCode getIntoleranceReason(const nsACString& hostname, int16_t port);
 
   void setRenegoUnrestrictedSites(const nsCString& str);
   bool isRenegoUnrestrictedSite(const nsCString& str);
   void clearStoredData();
--- a/toolkit/components/telemetry/Histograms.json
+++ b/toolkit/components/telemetry/Histograms.json
@@ -6448,16 +6448,22 @@
     "description": "detected symptom of SSL 3.0 intolerance, after considering historical info"
   },
   "SSL_VERSION_FALLBACK_INAPPROPRIATE": {
     "expires_in_version": "never",
     "kind": "enumerated",
     "n_values": 64,
     "description": "TLS/SSL version intolerance was falsely detected, server rejected handshake"
   },
+  "SSL_FALLBACK_LIMIT_REACHED": {
+    "expires_in_version": "default",
+    "kind": "enumerated",
+    "n_values": 16,
+    "description": "TLS/SSL version fallback reached the minimum version (1=TLS 1.0, 2=TLS 1.1, 3=TLS 1.2) or the fallback limit (4=TLS 1.0, 8=TLS 1.1, 12=TLS 1.2), stopped the fallback"
+  },
   "SSL_WEAK_CIPHERS_FALLBACK": {
     "expires_in_version": "never",
     "kind": "enumerated",
     "n_values": 64,
     "description": "Fallback attempted when server did not support any strong cipher suites"
   },
   "SSL_CIPHER_SUITE_FULL": {
     "expires_in_version": "never",